예제 #1
1
        public override bool Upgrade(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, IList<PackageLoadingAssetFile> assetFiles)
        {
            // Paradox 1.1 projects didn't have their dependency properly updated (they might have been marked as 1.0).
            // We know they are 1.1 only because there is a .props file.
            // This check shouldn't be necessary from 1.2.
            var packagePath = dependentPackage.FullPath;
            var propsFilePath = UPath.Combine(packagePath.GetParent(), (UFile)(packagePath.GetFileName() + ".props"));
            if (!File.Exists(propsFilePath) && dependency.Version.MinVersion < new PackageVersion("1.1.0-beta"))
            {
                log.Error("Can't upgrade old projects from {0} 1.0 to 1.1", dependency.Name);
                return false;
            }

            // Nothing to do for now, most of the work is already done by individual asset upgraders
            // We can later add logic here for package-wide upgrades (i.e. GameSettingsAsset)
            if (dependency.Version.MinVersion < new PackageVersion("1.2.0-beta"))
            {
                // UIImageGroups and SpriteGroups asset have been merged into a single SpriteSheet => rename the assets and modify the tag
                var uiImageGroups = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".pdxuiimage");
                var spitesGroups = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".pdxsprite");
                RenameAndChangeTag(assetFiles, uiImageGroups, "!UIImageGroup");
                RenameAndChangeTag(assetFiles, spitesGroups, "!SpriteGroup");
            }

            return true;
        }
예제 #2
0
 public EffectCompileCommand(AssetCompilerContext context, UDirectory baseUrl, string effectName, CompilerParameters compilerParameters, Package package)
 {
     this.context = context;
     this.baseUrl = baseUrl;
     this.effectName = effectName;
     this.compilerParameters = compilerParameters;
     this.package = package;
 }
 /// <summary>
 /// Initializes a new instance of <see cref="AssetMigrationContext"/>.
 /// </summary>
 /// <param name="package"></param>
 /// <param name="assetReference"></param>
 /// <param name="assetFullPath"></param>
 /// <param name="log"></param>
 public AssetMigrationContext(Package package, IReference assetReference, string assetFullPath, ILogger log)
 {
     if (log == null) throw new ArgumentNullException(nameof(log));
     Package = package;
     AssetReference = assetReference;
     AssetFullPath = assetFullPath;
     Log = new AssetLogger(package, assetReference, assetFullPath, log);
 }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PackageLoadingAssetFile" /> class.
        /// </summary>
        /// <param name="package">The package this asset will be part of.</param>
        /// <param name="filePath">The relative file path (from default asset folder).</param>
        /// <param name="sourceFolder">The source folder (optional, can be null).</param>
        /// <exception cref="System.ArgumentException">filePath must be relative</exception>
        public PackageLoadingAssetFile(Package package, UFile filePath, UDirectory sourceFolder)
        {
            if (filePath.IsAbsolute)
                throw new ArgumentException("filePath must be relative", filePath);

            SourceFolder = UPath.Combine(package.RootDirectory, sourceFolder ?? package.GetDefaultAssetFolder());
            FilePath = UPath.Combine(SourceFolder, filePath);
        }
예제 #5
0
 public AssetLogger(Package package, IReference assetReference, string assetFullPath, ILogger loggerToForward)
 {
     this.package = package;
     this.assetReference = assetReference;
     this.assetFullPath = assetFullPath;
     this.loggerToForward = loggerToForward;
     ActivateLog(LogMessageType.Debug);
 }
예제 #6
0
파일: PackageStore.cs 프로젝트: cg123/xenko
        /// <summary>
        /// Initializes a new instance of the <see cref="PackageStore"/> class.
        /// </summary>
        /// <exception cref="System.InvalidOperationException">Unable to find a valid Xenko installation path</exception>
        private PackageStore(string installationPath = null, string defaultPackageName = "Xenko", string defaultPackageVersion = XenkoVersion.CurrentAsText)
        {
            // TODO: these are currently hardcoded to Xenko
            DefaultPackageName = defaultPackageName;
            DefaultPackageVersion = new PackageVersion(defaultPackageVersion);
            defaultPackageDirectory = DirectoryHelper.GetPackageDirectory(defaultPackageName);
   
            // 1. Try to use the specified installation path
            if (installationPath != null)
            {
                if (!DirectoryHelper.IsInstallationDirectory(installationPath))
                {
                    throw new ArgumentException("Invalid Xenko installation path [{0}]".ToFormat(installationPath), "installationPath");
                }

                globalInstallationPath = installationPath;
            }

            // 2. Try to resolve an installation path from the path of this assembly
            // We need to be able to use the package manager from an official Xenko install as well as from a developer folder
            if (globalInstallationPath == null)
            {
                globalInstallationPath = DirectoryHelper.GetInstallationDirectory(DefaultPackageName);
            }

            // If there is no root, this is an error
            if (globalInstallationPath == null)
            {
                throw new InvalidOperationException("Unable to find a valid Xenko installation or dev path");
            }

            // Preload default package
            var logger = new LoggerResult();
            var defaultPackageFile = DirectoryHelper.GetPackageFile(defaultPackageDirectory, DefaultPackageName);
            defaultPackage = Package.Load(logger, defaultPackageFile, GetDefaultPackageLoadParameters());
            if (defaultPackage == null)
            {
                throw new InvalidOperationException("Error while loading default package from [{0}]: {1}".ToFormat(defaultPackageFile, logger.ToText()));
            }
            defaultPackage.IsSystem = true;

            // A flag variable just to know if it is a bare bone development directory
            isDev = defaultPackageDirectory != null && DirectoryHelper.IsRootDevDirectory(defaultPackageDirectory);

            // Check if we are in a root directory with store/packages facilities
            if (NugetStore.IsStoreDirectory(globalInstallationPath))
            {
                packagesDirectory = UPath.Combine(globalInstallationPath, (UDirectory)NugetStore.DefaultGamePackagesDirectory);
                store = new NugetStore(globalInstallationPath);
            }
            else
            {
                // We should exit from here if NuGet is not configured.
                MessageBox.Show($"Unexpected installation. Cannot find a proper NuGet configuration for [{defaultPackageName}] in [{globalInstallationPath}]", "Installation Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Environment.Exit(1);
            }
        }
        /// <summary>
        /// Create a <see cref="Package"/> that can be used to compile an <see cref="AssetItem"/> by analyzing and resolving its dependencies.
        /// </summary>
        /// <returns>The package packageSession that can be used to compile the asset item.</returns>
        public static Package CreateCompilePackageFromAsset(this PackageSession session, AssetItem originalAssetItem)
        {
            // create the compile root package and package session
            var assetPackageCloned = new Package();
            var compilePackageSession = new PackageSession(assetPackageCloned);

            AddAssetToCompilePackage(session, originalAssetItem, assetPackageCloned);

            return assetPackageCloned;
        }
예제 #8
0
        private static void FillPackageDependencies(Package rootPackage, bool isRecursive, ICollection<Package> packagesFound, bool storeOnly = false)
        {
            var session = rootPackage.Session;

            if (session == null && (rootPackage.Meta.Dependencies.Count > 0 || rootPackage.LocalDependencies.Count > 0))
            {
                throw new InvalidOperationException("Cannot query package with dependencies when it is not attached to a session");
            }

            // 1. Load store package
            foreach (var packageDependency in rootPackage.Meta.Dependencies)
            {
                var package = session.Packages.Find(packageDependency);
                if (package == null)
                {
                    continue;
                }

                if (!packagesFound.Contains(package))
                {
                    packagesFound.Add(package);

                    if (isRecursive)
                    {
                        FillPackageDependencies(package, isRecursive, packagesFound, storeOnly);
                    }
                }
            }

            if (storeOnly)
            {
                return;
            }

            // 2. Load local packages
            foreach (var packageReference in rootPackage.LocalDependencies)
            {
                var package = session.Packages.Find(packageReference.Id);
                if (package == null)
                {
                    continue;
                }

                if (!packagesFound.Contains(package))
                {
                    packagesFound.Add(package);

                    if (isRecursive)
                    {
                        FillPackageDependencies(package, isRecursive, packagesFound, storeOnly);
                    }
                }
            }

        }
예제 #9
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PackageSession"/> class.
 /// </summary>
 public PackageSession(Package package)
 {
     packages = new PackageCollection();
     packagesCopy = new PackageCollection();
     assemblyContainer = new AssemblyContainer();
     packages.CollectionChanged += PackagesCollectionChanged;
     if (package != null)
     {
         Packages.Add(package);
     }            
 }
        public static GraphicsPlatform GetGraphicsPlatform(this AssetCompilerContext context, Package package)
        {
            // If we have a command line override, use it first
            string graphicsApi;
            if (context.OptionProperties.TryGetValue("SiliconStudioXenkoGraphicsApi", out graphicsApi))
                return (GraphicsPlatform)Enum.Parse(typeof(GraphicsPlatform), graphicsApi);

            // Ohterwise, use game settings, or default as fallback
            var settings = package.GetGameSettingsAsset();
            return settings == null ? context.Platform.GetDefaultGraphicsPlatform() : RenderingSettings.GetGraphicsPlatform(context.Platform, settings.Get<RenderingSettings>(context.Profile).PreferredGraphicsPlatform);
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the <see cref="PackageSession"/> class.
        /// </summary>
        public PackageSession(Package package)
        {
            constraintProvider.AddConstraint(PackageStore.Instance.DefaultPackageName, new VersionSpec(PackageStore.Instance.DefaultPackageVersion.ToSemanticVersion()));

            packages = new PackageCollection();
            packagesCopy = new PackageCollection();
            assemblyContainer = new AssemblyContainer();
            packages.CollectionChanged += PackagesCollectionChanged;
            if (package != null)
            {
                Packages.Add(package);
            }            
        }
예제 #12
0
        /// <inheritdoc/>
        public override bool UpgradeAfterAssetsLoaded(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, PackageVersionRange dependencyVersionBeforeUpdate)
        {
            if (dependencyVersionBeforeUpdate.MinVersion < new PackageVersion("1.3.0-alpha02"))
            {
                // Add everything as root assets (since we don't know what the project was doing in the code before)
                foreach (var assetItem in dependentPackage.Assets)
                {
                    if (!AssetRegistry.IsAssetTypeAlwaysMarkAsRoot(assetItem.Asset.GetType()))
                        dependentPackage.RootAssets.Add(new AssetReference<Asset>(assetItem.Id, assetItem.Location));
                }
            }

            return true;
        }
예제 #13
0
        /// <summary>
        /// This method is called when a package needs to be tracked
        /// </summary>
        /// <param name="package">The package to track.</param>
        private void TrackPackage(Package package)
        {
            if (packages.Contains(package))
                return;

            packages.Add(package);

            foreach (var asset in package.Assets)
            {
                TrackAsset(asset);
            }

            package.Assets.CollectionChanged += Assets_CollectionChanged;
        }
        public static void AddLoadingFromSession(this ShaderGeneratorContextBase context, Package package)
        {
            var previousGetAssetFriendlyName = context.GetAssetFriendlyName;
            var previousFindAsset = context.FindAsset;

            // Setup the GetAssetFriendlyName callback
            context.GetAssetFriendlyName = runtimeAsset =>
            {
                string assetFriendlyName = null;

                if (previousGetAssetFriendlyName != null)
                {
                    assetFriendlyName = previousGetAssetFriendlyName(runtimeAsset);
                }

                if (string.IsNullOrEmpty(assetFriendlyName))
                {
                    var referenceAsset = AttachedReferenceManager.GetAttachedReference(runtimeAsset);
                    assetFriendlyName = string.Format("{0}:{1}", referenceAsset.Id, referenceAsset.Url);
                }

                return assetFriendlyName;
            };

            // Setup the FindAsset callback
            context.FindAsset = runtimeAsset =>
            {
                object newAsset = null; 
                if (previousFindAsset != null)
                {
                    newAsset = previousFindAsset(runtimeAsset);
                }

                if (newAsset != null)
                {
                    return newAsset;
                }

                var reference = AttachedReferenceManager.GetAttachedReference(runtimeAsset);


                var assetItem = package.Session.FindAsset(reference.Id) ?? package.Session.FindAsset(reference.Url);

                if (assetItem == null)
                {
                    return null;
                }
                return assetItem.Asset;
            };            
        }
예제 #15
0
        /// <summary>
        /// This method is called when a package needs to be un-tracked
        /// </summary>
        /// <param name="package">The package to un-track.</param>
        private void UnTrackPackage(Package package)
        {
            if (!packages.Contains(package))
                return;

            package.Assets.CollectionChanged -= Assets_CollectionChanged;

            foreach (var asset in package.Assets)
            {
                UnTrackAsset(asset);
            }

            packages.Remove(package);
        }
예제 #16
0
        /// <summary>
        /// Creates a new Paradox package with the specified name
        /// </summary>
        /// <param name="name">Name of the package</param>
        /// <returns>A new package instance</returns>
        public static Package NewPackage(string name)
        {
            var package = new Package
            {
                Meta =
                {
                    Name = name,
                    Version = new PackageVersion("1.0.0.0")
                },
            };

            // Add dependency to latest Paradox package
            package.Meta.Dependencies.Add(ParadoxConfig.GetLatestPackageDependency());

            // Setup the assets folder by default
            package.Profiles.Add(PackageProfile.NewShared());

            return package;
        }
        public static void AddLoadingFromSession(this ShaderGeneratorContextBase shaderGeneratorContext, Package package)
        {
            shaderGeneratorContext.FindAsset = material =>
            {
                if (material.Descriptor != null)
                {
                    return material.Descriptor;
                }

                var reference = AttachedReferenceManager.GetAttachedReference(material);

                var assetItem = package.Session.FindAsset(reference.Id) ?? package.Session.FindAsset(reference.Url);

                if (assetItem == null)
                {
                    return null;
                }
                return (IMaterialDescriptor)assetItem.Asset;
            };            
        }
예제 #18
0
        /// <summary>
        /// Create a <see cref="PackageSession"/> that can be used to compile an <see cref="AssetItem"/> by analyzing and resolving its dependencies.
        /// </summary>
        /// <returns>The package packageSession that can be used to compile the asset item.</returns>
        public static PackageSession CreateCompilePackageFromAsset(this PackageSession session, AssetItem originalAssetItem)
        {
            if (originalAssetItem == null) throw new ArgumentNullException("originalAssetItem");

            // Find the asset from the session
            var assetItem = originalAssetItem.Package.FindAsset(originalAssetItem.Id);
            if (assetItem == null)
            {
                throw new ArgumentException("Cannot find the specified AssetItem instance in the session");
            }

            // Calculate dependencies
            var dependencies = session.DependencyManager.ComputeDependencies(assetItem, AssetDependencySearchOptions.Out | AssetDependencySearchOptions.Recursive);
            var assetItemRootCloned = dependencies.Item.Clone();

            // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages
            assetItemRootCloned.SourceFolder = assetItem.FullPath.GetParent();

            // create the compile root package and package session
            var assetPackageCloned = new Package();
            var compilePackageSession = new PackageSession(assetPackageCloned);

            assetPackageCloned.Assets.Add(assetItemRootCloned);

            // For each asset item dependency, clone it in the new package
            foreach (var assetLink in dependencies.LinksOut)
            {
                // Only add assets not already added (in case of circular dependencies)
                if (assetPackageCloned.Assets.Find(assetLink.Item.Id) == null)
                {
                    // create a copy of the asset item and add it to the appropriate compile package
                    var itemCloned = assetLink.Item.Clone();

                    // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages
                    itemCloned.SourceFolder = assetLink.Item.FullPath.GetParent();
                    assetPackageCloned.Assets.Add(itemCloned);
                }
            }

            return compilePackageSession;
        }
        public static void AddAssetToCompilePackage(this PackageSession session, AssetItem originalAssetItem, Package assetPackageCloned)
        {
            if (originalAssetItem == null) throw new ArgumentNullException("originalAssetItem");

            // Find the asset from the session
            var assetItem = originalAssetItem.Package.FindAsset(originalAssetItem.Id);
            if (assetItem == null)
            {
                throw new ArgumentException("Cannot find the specified AssetItem instance in the session");
            }

            // Calculate dependencies
            // Search only for references
            var dependencies = session.DependencyManager.ComputeDependencies(assetItem.Id, AssetDependencySearchOptions.Out | AssetDependencySearchOptions.Recursive, ContentLinkType.Reference);
            if (dependencies == null)
                throw new InvalidOperationException("The asset doesn't exist in the dependency manager anymore");

            var assetItemRootCloned = dependencies.Item.Clone();

            // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages
            assetItemRootCloned.SourceFolder = assetItem.FullPath.GetParent();

            if (assetPackageCloned.Assets.Find(assetItemRootCloned.Id) == null)
                assetPackageCloned.Assets.Add(assetItemRootCloned);

            // For each asset item dependency, clone it in the new package
            foreach (var assetLink in dependencies.LinksOut)
            {
                // Only add assets not already added (in case of circular dependencies)
                if (assetPackageCloned.Assets.Find(assetLink.Item.Id) == null)
                {
                    // create a copy of the asset item and add it to the appropriate compile package
                    var itemCloned = assetLink.Item.Clone();

                    // Store the fullpath to the sourcefolder, this avoid us to clone hierarchy of packages
                    itemCloned.SourceFolder = assetLink.Item.FullPath.GetParent();
                    assetPackageCloned.Assets.Add(itemCloned);
                }
            }
        }
예제 #20
0
        public static void Build(Package package, string outputDirectory = null)
        {
            if (package == null) throw new ArgumentNullException("package");

            var meta = new NuGet.ManifestMetadata();
            package.Meta.ToNugetManifest(meta);

            var builder = new NuGet.PackageBuilder();
            builder.Populate(meta);

            // TODO this is not working 
            var files = new List<NuGet.ManifestFile>()
                {
                    NewFile(@"Bin\**\*.exe", "Bin"),
                    NewFile(@"Bin\**\*.vsix", "Bin"),
                    NewFile(@"Bin\**\*.so", "Bin"),
                    NewFile(@"Bin\**\*.a", "Bin"),
                    NewFile(@"Bin\**\*.md", "Bin"),
                    NewFile(@"Bin\**\*.html", "Bin"),
                    NewFile(@"Bin\**\*.config", "Bin"),
                    NewFile(@"Bin\**\*.dll", "Bin"),
                    NewFile(@"Bin\**\*.xml", "Bin"),
                    NewFile(@"Bin\**\*.winmd", "Bin"),
                    NewFile(@"Targets\*.targets", "Targets"),
                };

            // Handle Assets
            var rootDir = package.RootDirectory;

            var newPackage = new Package { Meta = package.Meta };

            foreach (var profile in package.Profiles)
            {
                var target = "Assets/" + profile.Name;
                foreach (var assetFolder in profile.AssetFolders)
                {
                    // TODO: handle exclude in asset folders
                    //files.Add(NewFile(source, target, @"**\*.cs;**\*.hlsl;**\*.csproj;**\*.csproj.user;**\obj\**"));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.pdxsl", target));
                    files.Add(NewFile(assetFolder.Path.MakeRelative(rootDir) + "/**/*.pdxfx", target));
                }

                var targetProfile = new PackageProfile(profile.Name);
                targetProfile.AssetFolders.Add(new AssetFolder(target));
                newPackage.Profiles.Add(targetProfile);
            }

            // Handle templates
            var targetFolder = new TemplateFolder("Templates");

            foreach (var templateFolder in package.TemplateFolders)
            {
                var source = templateFolder.Path.MakeRelative(rootDir) + "/**";
                UDirectory target = targetFolder.Path;
                if (templateFolder.Group != null)
                {
                    target = UPath.Combine(target, templateFolder.Group);
                }

                var excludeFiles = templateFolder.Exclude;
                files.Add(NewFile(source, target, excludeFiles));

                // Add template files
                foreach (var templateFile in templateFolder.Files)
                {
                    var newTemplateFile = templateFile.MakeRelative(templateFolder.Path);
                    if (templateFolder.Group != null)
                    {
                        newTemplateFile = UPath.Combine(templateFolder.Group, newTemplateFile);
                    }

                    newTemplateFile = UPath.Combine(targetFolder.Path, newTemplateFile);
                    targetFolder.Files.Add(newTemplateFile);
                }
            }

            // Create temp package for archive
            newPackage.TemplateFolders.Add(targetFolder);
            var newPackageFileName = "temp" + Guid.NewGuid() + ".pdxpkg";
            newPackage.FullPath = package.RootDirectory + "/" + newPackageFileName;
            var result = newPackage.Save();
            if (result.HasErrors)
            {
                throw new InvalidOperationException(result.ToText());
                // TODO throw error
            }
            files.Add(NewFile(newPackageFileName, package.Meta.Name + Package.PackageFileExtension));

            // Add files
            builder.PopulateFiles(package.RootDirectory, files);

            outputDirectory = outputDirectory ?? Environment.CurrentDirectory;

            // Save the nupkg
            var outputPath = GetOutputPath(builder,  outputDirectory);
            bool isExistingPackage = File.Exists(outputPath);
            if (isExistingPackage)
            {
                File.Delete(outputPath);
            }
            try
            {
                using (Stream stream = File.Create(outputPath))
                {
                    builder.Save(stream);
                }
            }
            catch
            {
                if (!isExistingPackage && File.Exists(outputPath))
                {
                    File.Delete(outputPath);
                }
                throw;
            }

            File.Delete(newPackage.FullPath);
        }
예제 #21
0
        public override bool UpgradeBeforeAssembliesLoaded(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage)
        {
            if (dependency.Version.MinVersion < new PackageVersion("1.4.0-alpha01"))
            {
                // Only load workspace for C# assemblies (default includes VB but not added as a NuGet package)
                var csharpWorkspaceAssemblies = new[] { Assembly.Load("Microsoft.CodeAnalysis.Workspaces"), Assembly.Load("Microsoft.CodeAnalysis.CSharp.Workspaces"), Assembly.Load("Microsoft.CodeAnalysis.Workspaces.Desktop") };
                var workspace = MSBuildWorkspace.Create(ImmutableDictionary<string, string>.Empty, MefHostServices.Create(csharpWorkspaceAssemblies));

                var tasks = dependentPackage.Profiles
                    .SelectMany(profile => profile.ProjectReferences)
                    .Select(projectReference => UPath.Combine(dependentPackage.RootDirectory, projectReference.Location))
                    .Distinct()
                    .Select(projectFullPath => Task.Run(() => UpgradeProject(workspace, projectFullPath)))
                    .ToArray();

                Task.WaitAll(tasks);
            }

            return true;
        }
예제 #22
0
        public override bool Upgrade(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, IList<PackageLoadingAssetFile> assetFiles)
        {
            // Paradox 1.1 projects didn't have their dependency properly updated (they might have been marked as 1.0).
            // We know they are 1.1 only because there is a .props file.
            // This check shouldn't be necessary from 1.2.
            var packagePath = dependentPackage.FullPath;
            var propsFilePath = UPath.Combine(packagePath.GetParent(), (UFile)(packagePath.GetFileName() + ".props"));
            if (!File.Exists(propsFilePath) && dependency.Version.MinVersion < new PackageVersion("1.1.0-beta"))
            {
                log.Error("Can't upgrade old projects from {0} 1.0 to 1.1", dependency.Name);
                return false;
            }

            // Nothing to do for now, most of the work is already done by individual asset upgraders
            // We can later add logic here for package-wide upgrades (i.e. GameSettingsAsset)
            if (dependency.Version.MinVersion < new PackageVersion("1.2.0-beta"))
            {
                // UIImageGroups and SpriteGroups asset have been merged into a single SpriteSheet => rename the assets and modify the tag
                var uiImageGroups = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".pdxuiimage");
                var spritesGroups = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".pdxsprite");
                RenameAndChangeTag(assetFiles, uiImageGroups, "!UIImageGroup");
                RenameAndChangeTag(assetFiles, spritesGroups, "!SpriteGroup");
            }

            if (dependency.Version.MinVersion < new PackageVersion("1.3.0-alpha01"))
            {
                // Create GameSettingsAsset
                GameSettingsAsset.UpgraderVersion130.Upgrade(session, log, dependentPackage, dependency, dependencyPackage, assetFiles);
            }

            if (dependency.Version.MinVersion < new PackageVersion("1.3.0-alpha02"))
            {
                // Delete EffectLogAsset
                foreach (var assetFile in assetFiles)
                {
                    if (assetFile.FilePath.GetFileName() == EffectLogAsset.DefaultFile)
                    {
                        assetFile.Deleted = true;
                    }
                }
            }

            if (dependency.Version.MinVersion < new PackageVersion("1.4.0-beta"))
            {
                // Update file extensions with Xenko prefix
                var legacyAssets = from assetFile in assetFiles
                                   where !assetFile.Deleted
                                   let extension = assetFile.FilePath.GetFileExtension()
                                   where extension.StartsWith(".pdx")
                                   select new { AssetFile = assetFile, NewExtension = ".xk" + extension.Substring(4) };

                foreach (var legacyAsset in legacyAssets.ToArray())
                {
                    // Load asset data, so the renamed file will have it's AssetContent set
                    if (legacyAsset.AssetFile.AssetContent == null)
                        legacyAsset.AssetFile.AssetContent = File.ReadAllBytes(legacyAsset.AssetFile.FilePath);

                    // Change legacy namespaces and default effect names in all shader source files
                    // TODO: Use syntax analysis? What about shaders referenced in other assets?
                    if (legacyAsset.NewExtension == ".xksl" || legacyAsset.NewExtension == ".xkfx" || legacyAsset.NewExtension == ".xkeffectlog")
                    {
                        var sourceText = System.Text.Encoding.UTF8.GetString(legacyAsset.AssetFile.AssetContent);
                        var newSourceText = sourceText.Replace("Paradox", "Xenko");

                        if (newSourceText != sourceText)
                        {
                            legacyAsset.AssetFile.AssetContent = System.Text.Encoding.UTF8.GetBytes(newSourceText);
                        }
                    }

                    // Create asset copy with new extension
                    ChangeFileExtension(assetFiles, legacyAsset.AssetFile, legacyAsset.NewExtension);
                }

                // Force loading of user settings with old extension
                var userSettings = dependentPackage.UserSettings;

                // Change package extension
                dependentPackage.FullPath = new UFile(dependentPackage.FullPath.GetFullPathWithoutExtension(), Package.PackageFileExtension);

                // Make sure all assets are upgraded
                RunAssetUpgradersUntilVersion(log, dependentPackage, XenkoConfig.PackageName, assetFiles, PackageVersion.Parse("1.4.0-beta"));
            }

            if (dependency.Version.MinVersion < new PackageVersion("1.5.0-alpha01"))
            {
                RunAssetUpgradersUntilVersion(log, dependentPackage, XenkoConfig.PackageName, assetFiles, PackageVersion.Parse("1.5.0-alpha01"));
            }

            if (dependency.Version.MinVersion < new PackageVersion("1.5.0-alpha02"))
            {
                // Ideally, this should be part of asset upgrader but we can't upgrade multiple assets at once yet

                var modelAssets = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".xkm3d").Select(x => x.AsYamlAsset()).ToArray();
                var animAssets = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".xkanim").Select(x => x.AsYamlAsset()).ToArray();
                var sceneAssets = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".xkscene").Select(x => x.AsYamlAsset()).ToArray();

                // Select models with at least two nodes
                var modelAssetsWithSekeleton = modelAssets
                    .Where(model => ((IEnumerable)model.DynamicRootNode.Nodes).Cast<object>().Count() > 1).ToArray();

                var animToModelMapping = new Dictionary<PackageLoadingAssetFile.YamlAsset, PackageLoadingAssetFile.YamlAsset>();

                // Find associations in scene
                foreach (var sceneAsset in sceneAssets)
                {
                    var hierarchy = sceneAsset.DynamicRootNode.Hierarchy;
                    foreach (dynamic entity in hierarchy.Entities)
                    {
                        var components = entity.Entity.Components;
                        var animationComponent = components["AnimationComponent.Key"];
                        var model = components["ModelComponent.Key"]?.Model;
                        if (animationComponent != null && model != null)
                        {
                            var modelReference = DynamicYamlExtensions.ConvertTo<AssetReference<Asset>>(model);
                            var modelAsset = modelAssetsWithSekeleton.FirstOrDefault(x => x.Asset.AssetPath == modelReference.Location);

                            foreach (var animation in animationComponent.Animations)
                            {
                                var animationReference = DynamicYamlExtensions.ConvertTo<AssetReference<Asset>>(animation.Value);
                                var animationAsset = animAssets.FirstOrDefault(x => x.Asset.AssetPath == animationReference.Location);

                                if (modelAsset != null && animationAsset != null)
                                {
                                    animToModelMapping[animationAsset] = modelAsset;
                                }
                            }
                        }
                    }
                }

                // Find associations when sharing same source file
                foreach (var animationAsset in animAssets)
                {
                    // Comparing absolute path of assets
                    var modelAsset = modelAssetsWithSekeleton.FirstOrDefault(
                        x => UPath.Combine(animationAsset.Asset.AssetPath.GetParent(), new UFile((string)animationAsset.DynamicRootNode.Source))
                             == UPath.Combine(x.Asset.AssetPath.GetParent(), new UFile((string)x.DynamicRootNode.Source)));
                    if (modelAsset != null)
                    {
                        animToModelMapping[animationAsset] = modelAsset;
                    }
                }

                var modelToSkeletonMapping = new Dictionary<PackageLoadingAssetFile.YamlAsset, PackageLoadingAssetFile.YamlAsset>();

                // For each model asset, create skeleton assets
                foreach (var modelAsset in modelAssetsWithSekeleton)
                {
                    var skeletonAsset = new PackageLoadingAssetFile(modelAsset.Asset.FilePath.GetFullPathWithoutExtension() + " Skeleton.xkskel", modelAsset.Asset.SourceFolder)
                    {
                        AssetContent = System.Text.Encoding.UTF8.GetBytes("!Skeleton\r\nId: " + Guid.NewGuid())
                    };

                    using (var skeletonAssetYaml = skeletonAsset.AsYamlAsset())
                    {
                        // Set source
                        skeletonAssetYaml.DynamicRootNode.Source = modelAsset.DynamicRootNode.Source;
                        skeletonAssetYaml.DynamicRootNode.SourceHash = modelAsset.DynamicRootNode.SourceHash;

                        // To be on the safe side, mark everything as preserved
                        var nodes = modelAsset.DynamicRootNode.Nodes;
                        foreach (var node in nodes)
                        {
                            node.Preserve = true;
                        }

                        skeletonAssetYaml.DynamicRootNode.Nodes = nodes;
                        skeletonAssetYaml.DynamicRootNode.ScaleImport = modelAsset.DynamicRootNode.ScaleImport;

                        // Update model to point to this skeleton
                        modelAsset.DynamicRootNode.Skeleton = new AssetReference<Asset>(Guid.Parse((string)skeletonAssetYaml.DynamicRootNode.Id), skeletonAsset.AssetPath.MakeRelative(modelAsset.Asset.AssetPath.GetParent()));
                        modelToSkeletonMapping.Add(modelAsset, skeletonAssetYaml);
                    }

                    assetFiles.Add(skeletonAsset);
                }

                // Update animation to point to skeleton, and set preview default model
                foreach (var animToModelEntry in animToModelMapping)
                {
                    var animationAsset = animToModelEntry.Key;
                    var modelAsset = animToModelEntry.Value;

                    var skeletonAsset = modelToSkeletonMapping[modelAsset];
                    animationAsset.DynamicRootNode.Skeleton = new AssetReference<Asset>(Guid.Parse((string)skeletonAsset.DynamicRootNode.Id), skeletonAsset.Asset.AssetPath.MakeRelative(animationAsset.Asset.AssetPath.GetParent()));
                    animationAsset.DynamicRootNode.PreviewModel = new AssetReference<Asset>(Guid.Parse((string)modelAsset.DynamicRootNode.Id), modelAsset.Asset.AssetPath.MakeRelative(animationAsset.Asset.AssetPath.GetParent()));
                }

                // Remove Nodes from models
                foreach (var modelAsset in modelAssets)
                {
                    modelAsset.DynamicRootNode.Nodes = DynamicYamlEmpty.Default;
                    modelAsset.DynamicRootNode["~Base"].Asset.Nodes = DynamicYamlEmpty.Default;
                }

                // Save back
                foreach (var modelAsset in modelAssets)
                    modelAsset.Dispose();
                foreach (var animAsset in animAssets)
                    animAsset.Dispose();
            }

            return true;
        }
예제 #23
0
        private void RunAssetUpgradersUntilVersion(ILogger log, Package dependentPackage, string dependencyName, IList<PackageLoadingAssetFile> assetFiles, PackageVersion maxVersion)
        {
            foreach (var assetFile in assetFiles)
            {
                if (assetFile.Deleted)
                    continue;

                var context = new AssetMigrationContext(dependentPackage, log);
                AssetMigration.MigrateAssetIfNeeded(context, assetFile, dependencyName, maxVersion);
            }
        }
예제 #24
0
 /// <summary>
 /// Performs the package migration, before assets are loaded
 /// </summary>
 /// <param name="session">The session.</param>
 /// <param name="log">The log.</param>
 /// <param name="dependentPackage">The source package.</param>
 /// <param name="dependency">The dependency.</param>
 /// <param name="dependencyPackage">The dependency package.</param>
 /// <param name="assetFiles">The asset files.</param>
 /// <returns></returns>
 public abstract bool Upgrade(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, IList<PackageLoadingAssetFile> assetFiles);
예제 #25
0
 public static GraphicsProfile GetGraphicsProfile(Package package)
 {
     var packageSharedProfile = package.Profiles.FindSharedProfile();
     if (packageSharedProfile == null) return 0;
     return packageSharedProfile.Properties.Get(DefaultGraphicsProfile);
 }
예제 #26
0
        /// <summary>
        /// Saves a .props file for the specified package, containing the paradox version (only Major.Minor)
        /// used to compile the package. 
        /// </summary>
        /// <param name="package">The package.</param>
        public static void SaveProperties(Package package)
        {
            // Props file is in the same folder as the pdxpkg file, just with a ".props" extension.
            var packagePath = package.FullPath;
            var propsFilePath = UPath.Combine(packagePath.GetParent(), (UFile)(packagePath.GetFileName() + ".props")) ;

            var projectCollection = new Microsoft.Build.Evaluation.ProjectCollection();
            var project = new Microsoft.Build.Evaluation.Project(projectCollection);
            var commonPropertyGroup = project.Xml.AddPropertyGroup();

            var dependencies = package.FindDependencies(false, false, true);

            // Add Paradox version
            var pdxVersion = dependencies.FirstOrDefault(d => d.Meta.Name == "Paradox");
            if (pdxVersion != null)
            {
                var versionText = pdxVersion.Meta.Version.Version.Major + "." + pdxVersion.Meta.Version.Version.Minor;
                commonPropertyGroup.AddProperty("SiliconStudioPackageParadoxVersion", versionText);
            }

            if (File.Exists(propsFilePath))
            {
                File.Delete(propsFilePath);
            }
            project.Save(propsFilePath);
        }
예제 #27
0
 /// <summary>
 /// Performs a preprocessing step of package migration, before assembly references are loaded.
 /// </summary>
 /// <param name="session">The session.</param>
 /// <param name="log">The log.</param>
 /// <param name="dependentPackage">The source package.</param>
 /// <param name="dependency">The dependency.</param>
 /// <param name="dependencyPackage">The dependency package.</param>
 /// <returns></returns>
 public virtual bool UpgradeBeforeAssembliesLoaded(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage)
 {
     return true;
 }
예제 #28
0
 public static void MarkPackageDirty(Package package)
 {
     package.IsDirty = true;
 }
예제 #29
0
 /// <summary>
 /// Performs the second step of package migration, after assets have been loaded.
 /// </summary>
 /// <param name="session">The session.</param>
 /// <param name="log">The log.</param>
 /// <param name="dependentPackage">The source package.</param>
 /// <param name="dependency">The dependency.</param>
 /// <param name="dependencyPackage">The dependency package.</param>
 /// <param name="dependencyVersionBeforeUpdate">The version before the update.</param>
 /// <returns></returns>
 public virtual bool UpgradeAfterAssetsLoaded(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, PackageVersionRange dependencyVersionBeforeUpdate)
 {
     return true;
 }
예제 #30
0
        // Build a full GameSettings from a package
        public static GameSettings CreateFromPackage(Package package, PlatformType platform)
        {
            var result = new GameSettings();

            // Default settings
            var sharedProfile = package.Profiles.FindSharedProfile();
            if (sharedProfile != null)
            {
                var sceneAsset = sharedProfile.Properties.Get(DefaultScene);
                if (sceneAsset != null) result.DefaultSceneUrl = sceneAsset.Location;
                result.DefaultBackBufferWidth = sharedProfile.Properties.Get(BackBufferWidth);
                result.DefaultBackBufferHeight = sharedProfile.Properties.Get(BackBufferHeight);
                result.DefaultGraphicsProfileUsed = sharedProfile.Properties.Get(DefaultGraphicsProfile);
            }
            
            // Platform-specific settings have priority
            if (platform != PlatformType.Shared)
            {
                var platformProfile = package.Profiles.FirstOrDefault(o => o.Platform == platform);
                if (platformProfile != null)
                {
                    var customProfile = platformProfile.Properties.Get(DefaultGraphicsProfile);
                    if (customProfile > 0) result.DefaultGraphicsProfileUsed = customProfile;
                }
            }

            return result;
        }