4 using System.Collections.Generic;
5 using System.Collections.Specialized;
6 using System.Diagnostics;
9 using System.Threading;
10 using Microsoft.Build.Execution;
12 using SiliconStudio.Assets.Analysis;
13 using SiliconStudio.Core;
14 using SiliconStudio.Core.Collections;
15 using SiliconStudio.Core.Diagnostics;
16 using SiliconStudio.Core.IO;
17 using SiliconStudio.Assets.Diagnostics;
18 using SiliconStudio.Core.Reflection;
19 using SiliconStudio.Core.Storage;
20 using SiliconStudio.Core.VisualStudio;
22 namespace SiliconStudio.Assets
32 private readonly
object dependenciesLock =
new object();
53 packages.CollectionChanged += PackagesCollectionChanged;
56 Packages.Add(package);
61 public bool IsDirty {
get; set; }
83 return packages.Where(
package => !package.IsSystem);
91 public UFile SolutionPath {
get; set; }
98 if (dependencies != null)
100 dependencies.Dispose();
108 public bool HasDependencyManager
112 lock (dependenciesLock)
114 return dependencies != null;
128 return currentPackage;
134 if (!Packages.Contains(value))
136 throw new InvalidOperationException(
"Expecting a package that is already registered in this session");
139 currentPackage = value;
149 if (CurrentPackage == null)
154 yield
return CurrentPackage;
156 foreach (var storeDep
in CurrentPackage.Meta.Dependencies)
158 var
package = Packages.Find(storeDep);
162 yield
return package;
166 foreach (var localDep
in CurrentPackage.LocalDependencies)
168 var
package = Packages.Find(localDep.Id);
172 yield
return package;
185 lock (dependenciesLock)
202 AddExistingPackage(packagePath, loggerResult, loadParameters);
217 if (packagePath == null)
throw new ArgumentNullException(
"packagePath");
218 if (logger == null)
throw new ArgumentNullException(
"logger");
219 if (!packagePath.
IsAbsolute)
throw new ArgumentException(
"Invalid relative path. Expecting an absolute package path",
"packagePath");
220 if (!
File.Exists(packagePath))
throw new FileNotFoundException(
"Unable to find package", packagePath);
222 var loadParameters = loadParametersArg ?? PackageLoadParameters.Default();
228 AssetReferenceAnalysis.EnableCaching =
true;
232 package = PreLoadPackage(this, logger, packagePath, false, packagesLoaded, loadParameters);
235 foreach (var packageToAdd
in packagesLoaded)
237 var analysis =
new PackageAnalysis(packageToAdd, GetPackageAnalysisParametersForLoad());
238 analysis.Run(logger);
244 AssetReferenceAnalysis.EnableCaching =
false;
260 if (filePath == null)
throw new ArgumentNullException(
"filePath");
261 if (sessionResult == null)
throw new ArgumentNullException(
"sessionResult");
264 loadParameters = loadParameters ?? PackageLoadParameters.Default();
267 filePath = FileUtility.GetAbsolutePath(filePath);
269 if (!
File.Exists(filePath))
throw new ArgumentException(
"File [{0}] must exist".ToFormat(filePath),
"filePath");
274 AssetReferenceAnalysis.EnableCaching =
true;
276 using (var profile = Profiler.Begin(PackageSessionProfilingKeys.Loading))
278 sessionResult.Clear();
279 sessionResult.Progress(
"Loading..", 0, 1);
283 var packagePaths =
new List<string>();
286 if (PackageSessionHelper.IsSolutionFile(filePath))
288 PackageSessionHelper.LoadSolution(session, filePath, packagePaths, sessionResult);
290 else if (PackageSessionHelper.IsPackageFile(filePath))
292 packagePaths.Add(filePath);
296 sessionResult.Error(
"Unsupported file extension (only .sln or {0} are supported)", Package.PackageFileExtension);
300 var cancelToken = loadParameters.CancelToken;
304 foreach (var packageFilePath
in packagePaths)
306 PreLoadPackage(session, sessionResult, packageFilePath,
false, packagesLoaded, loadParameters);
309 if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested)
316 session.LoadMissingReferences(sessionResult, loadParameters);
320 var analysisResults = analysis.Run();
321 analysisResults.CopyTo(sessionResult);
324 if (!cancelToken.HasValue || !cancelToken.Value.IsCancellationRequested)
326 sessionResult.Session = session;
333 session.IsDirty =
false;
339 AssetReferenceAnalysis.EnableCaching =
false;
353 Load(filePath, result, loadParameters);
364 var loadParameters = loadParametersArg ?? PackageLoadParameters.Default();
366 var cancelToken = loadParameters.CancelToken;
371 var previousPackages = Packages.ToList();
372 foreach (var package
in previousPackages)
375 if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested)
380 PreLoadPackageDependencies(
this, log, package, packagesLoaded, loadParameters);
392 bool packagesSaved =
false;
395 using (var profile = Profiler.Begin(PackageSessionProfilingKeys.Saving))
400 var previousAssets =
new Dictionary<Guid, AssetItem>();
401 foreach (var assetItem
in packagesCopy.SelectMany(package => package.Assets))
403 previousAssets[assetItem.Id] = assetItem;
407 var newAssets =
new Dictionary<Guid, AssetItem>();
408 foreach (var assetItem
in LocalPackages.SelectMany(package => package.Assets))
410 newAssets[assetItem.Id] = assetItem;
414 var assetsOrPackagesToRemove =
new Dictionary<UFile, object>();
415 foreach (var assetIt
in previousAssets)
417 var asset = assetIt.Value;
420 if (!newAssets.TryGetValue(assetIt.Key, out newAsset) || newAsset.Location != asset.Location)
422 assetsOrPackagesToRemove[asset.FullPath] = asset;
438 if (!CheckModifiedPackages() && assetsOrPackagesToRemove.Count == 0)
445 if (dependencies != null)
447 dependencies.BeginSavingSession();
457 foreach (var fileIt
in assetsOrPackagesToRemove)
459 var assetPath = fileIt.Key;
460 var assetItemOrPackage = fileIt.Value;
462 if (
File.Exists(assetPath))
466 File.Delete(assetPath);
470 var assetItem = assetItemOrPackage as
AssetItem;
471 if (assetItem != null)
473 log.Error(assetItem.Package, assetItem.ToReference(),
AssetMessageCode.AssetCannotDelete, ex, assetPath);
477 var
package = assetItemOrPackage as Package;
480 log.Error(package, null, AssetMessageCode.AssetCannotDelete, ex, assetPath);
488 packagesCopy.Clear();
489 foreach (var package
in LocalPackages)
495 var packageClone = package.Clone(
false);
496 packagesCopy.Add(packageClone);
499 packagesSaved =
true;
503 if (dependencies != null)
505 dependencies.EndSavingSession();
512 PackageSessionHelper.SaveSolution(
this, log);
523 private bool CheckModifiedPackages()
530 foreach (var package
in LocalPackages)
532 if (package.IsDirty || package.Assets.IsDirty)
536 if (package.Assets.Any(item => item.IsDirty))
544 private void PackagesCollectionChanged(
object sender, NotifyCollectionChangedEventArgs e)
548 case NotifyCollectionChangedAction.Add:
549 RegisterPackage((
Package)e.NewItems[0]);
551 case NotifyCollectionChangedAction.Remove:
552 UnRegisterPackage((
Package)e.OldItems[0]);
555 case NotifyCollectionChangedAction.Replace:
556 packagesCopy.Clear();
558 foreach (var oldPackage
in e.OldItems.OfType<
Package>())
560 UnRegisterPackage(oldPackage);
563 foreach (var packageToCopy
in packages)
565 RegisterPackage(packageToCopy);
571 private void RegisterPackage(
Package package)
573 package.Session =
this;
576 package.AssetDirtyChanged += OnAssetDirtyChanged;
581 FreezePackage(package);
591 private void FreezePackage(
Package package)
596 packagesCopy.Add(package.Clone(
false));
599 private void UnRegisterPackage(
Package package)
601 package.Session = null;
604 package.AssetDirtyChanged -= OnAssetDirtyChanged;
606 packagesCopy.RemoveById(package.Id);
611 private void OnAssetDirtyChanged(
Asset asset)
613 Action<Asset> handler = AssetDirtyChanged;
614 if (handler != null) handler(asset);
619 if (session == null)
throw new ArgumentNullException(
"session");
620 if (log == null)
throw new ArgumentNullException(
"log");
621 if (filePath == null)
throw new ArgumentNullException(
"filePath");
622 if (loadedPackages == null)
throw new ArgumentNullException(
"loadedPackages");
623 if (loadParameters == null)
throw new ArgumentNullException(
"loadParameters");
627 var packageId = Package.GetPackageIdFromFile(filePath);
632 return session.Packages.Find(packageId);
638 return loadedPackages.Find(packageId);
642 var newLoadParameters = loadParameters.Clone();
643 newLoadParameters.AssemblyContainer = session.assemblyContainer;
646 var
package = Package.Load(log, filePath, newLoadParameters);
647 package.IsSystem = isSystemPackage;
650 loadedPackages.Add(package);
653 PreLoadPackageDependencies(session, log, package, loadedPackages, loadParameters);
656 session.Packages.Add(package);
659 package.ValidateAssets(loadParameters.GenerateNewAssetIds);
662 session.FreezePackage(package);
668 log.Error(
"Error while pre-loading package [{0}]", ex, filePath);
676 if (session == null)
throw new ArgumentNullException(
"session");
677 if (log == null)
throw new ArgumentNullException(
"log");
678 if (package == null)
throw new ArgumentNullException(
"package");
679 if (loadParameters == null)
throw new ArgumentNullException(
"loadParameters");
684 var loadedPackage = session.Packages.Find(packageDependency);
685 if (loadedPackage != null)
690 var file = PackageStore.Instance.GetPackageFileName(packageDependency.Name, packageDependency.Version);
696 log.Error(
"Unable to find package {0} not installed", packageDependency);
701 PreLoadPackage(session, log, file,
true, loadedPackages, loadParameters);
716 var subPackageFilePath = package.RootDirectory != null ? UPath.Combine(package.RootDirectory, newLocation) : newLocation;
719 PreLoadPackage(session, log, subPackageFilePath.FullPath,
false, loadedPackages, loadParameters);
727 IsPackageCheckDependencies =
true,
728 IsProcessingAssetReferences =
true,
729 IsLoggingAssetNotFoundAsError =
true,
bool IsSystem
Gets or sets a value indicating whether this package is a system package.
AssetItemCollection TemporaryAssets
Gets the temporary assets list loaded from disk before they are going into Assets.
PackageSession(Package package)
Initializes a new instance of the PackageSession class.
static PackageSessionResult Load(string filePath, PackageLoadParameters loadParameters=null)
Loads a package from specified file path.
SiliconStudio.Core.Diagnostics.LoggerResult LoggerResult
A logger that stores messages locally useful for internal log scenarios.
PackageCollection Packages
Gets the packages.
A registry for file extensions, IAssetImporter, IAssetFactory and aliases associated with assets...
Package AddExistingPackage(UFile packagePath, ILogger logger, PackageLoadParameters loadParametersArg=null)
Adds an existing package to the current session.
AssetMessageCode
A message code used by AssetLogMessage to identify an error/warning.
Action< Asset > AssetDirtyChanged
void Dispose()
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resourc...
Class PackageAnalysisParameters. This class cannot be inherited.
bool ContainsById(Guid packageGuid)
Determines whether this collection contains a package with the specified package unique identifier...
An analysis to check the validity of a Package, convert UFile or UDirectory references to absolute/re...
An asset item part of a Package accessible through SiliconStudio.Assets.Package.Assets.
A session for editing a package.
static void Load(string filePath, PackageSessionResult sessionResult, PackageLoadParameters loadParameters=null)
Loads a package from specified file path.
PackageSession()
Initializes a new instance of the PackageSession class.
bool IsAbsolute
Determines whether this instance is absolute.
A package analysis provides methods to validate the integrity of a whole package. ...
LoggerResult AddExistingPackage(UFile packagePath, PackageLoadParameters loadParameters=null)
Adds an existing package to the current session.
A class responsible for providing asset dependencies for a PackageSession and file tracking dependenc...
Result returned when loading a session using PackageSession.Load(string,PackageSessionResult,System.Nullable{System.Threading.CancellationToken},bool)
List< PackageReference > LocalDependencies
Gets the local package dependencies used by this package (only valid for local references). Global dependencies are defined through the Meta property in PackageMeta.Dependencies
IEnumerable< Package > GetPackagesFromCurrent()
Gets the packages referenced by the current package.
A package managing assets.
void LoadMissingReferences(ILogger log, PackageLoadParameters loadParametersArg=null)
Loads the missing references
static string ExpandString(object context, string stringToExpand)
Expands a string using the registered string expander (RegisterStringExpander)
Parameters used for loading a package.
An interface that tags if an object is dirty.
LoggerResult Save()
Saves all packages and assets.
PackageMeta Meta
Gets or sets the metadata associated with this package.
Defines a normalized file path. See UPath for details. This class cannot be inherited.