Example #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;
        }
 /// <inheritdoc/>
 public IEnumerable<IReference> EnumerateCompileTimeDependencies(PackageSession session)
 {
     var reference = AttachedReferenceManager.GetAttachedReference(Skeleton);
     if (reference != null)
     {
         yield return new AssetReference(reference.Id, reference.Url);
     }
 }
        /// <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;
        }
        /// <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);
        }
        public static AssetItem FindAssetFromAttachedReference(this PackageSession session, object obj)
        {
            if (obj == null)
            {
                return(null);
            }

            var reference = AttachedReferenceManager.GetAttachedReference(obj);

            return(reference != null ? (FindAsset(session, reference.Id) ?? FindAsset(session, reference.Url)) : null);
        }
        /// <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();
            //the following line is necessary to attach a session to the package
            // ReSharper disable once UnusedVariable
            var compilePackageSession = new PackageSession(assetPackageCloned);

            AddAssetToCompilePackage(session, originalAssetItem, assetPackageCloned);

            return(assetPackageCloned);
        }
        /// <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;
        }
        public IEnumerable<IReference> EnumerateCompileTimeDependencies(PackageSession session)
        {
            if (Prefab != null)
            {
                // Return the prefab itself
                yield return Prefab;
                // Then we need to return used models and materials because they affects how the meshes are generated
                var prefab = session.FindAsset(Prefab.Location)?.Asset as PrefabAsset;
                if (prefab != null)
                {
                    // Use a dictionary to ensure each reference is yielded only once
                    var references = new Dictionary<AssetId, IReference>();
                    foreach (var entity in prefab.Hierarchy.Parts)
                    {
                        // Gather all entities with a model component and a valid model
                        var modelComponent = entity.Entity.Get<ModelComponent>();
                        if (modelComponent?.Model != null)
                        {
                            var modelReference = AttachedReferenceManager.GetAttachedReference(modelComponent.Model);
                            var model = session.FindAsset(modelReference.Url)?.Asset as IModelAsset;
                            if (model != null)
                            {
                                // Build the list of material for this model
                                var materialList = model.Materials.Select(x => x.MaterialInstance.Material).ToList();
                                for (var i = 0; i < modelComponent.Materials.Count && i < materialList.Count; i++)
                                foreach (var material in modelComponent.Materials)
                                {
                                    // Apply any material override from the model component
                                    materialList[material.Key] = material.Value;
                                }

                                // Add the model and the related materials to the list of reference
                                references[modelReference.Id] = modelReference;
                                foreach (var material in materialList)
                                {
                                    var materialReference = AttachedReferenceManager.GetAttachedReference(material);
                                    references[materialReference.Id] = materialReference;
                                }
                            }
                        }
                    }
                    // Finally return all the referenced models and materials
                    foreach (var reference in references.Values)
                    {
                        yield return reference;
                    }
                }
            }
        }
        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);
                }
            }
        }
        /// <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);
        }
        /// <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 IEnumerable<IReference> EnumerateCompileTimeDependencies(PackageSession session)
        {
            if (Scene != null)
            {
                var reference = AttachedReferenceManager.GetAttachedReference(Scene);
                var sceneAsset = (SceneAsset)session.FindAsset(reference.Url)?.Asset;

                var referencedColliderShapes = new HashSet<AssetId>();

                // Find collider assets to reference
                if (sceneAsset != null)
                {
                    List<Entity> sceneEntities = sceneAsset.Hierarchy.Parts.Select(x => x.Entity).ToList();
                    foreach (var entity in sceneEntities)
                    {
                        StaticColliderComponent collider = entity.Get<StaticColliderComponent>();
                        bool colliderEnabled = collider != null && ((CollisionFilterGroupFlags)collider.CollisionGroup & IncludedCollisionGroups) != 0 && collider.Enabled;
                        if (colliderEnabled)
                        {
                            var assetShapes = collider.ColliderShapes.OfType<ColliderShapeAssetDesc>();
                            foreach (var assetShape in assetShapes)
                            {
                                if (assetShape.Shape == null)
                                    continue;

                                // Reference all asset collider shapes
                                reference = AttachedReferenceManager.GetAttachedReference(assetShape.Shape);

                                // Only need to reference each shape once
                                if (referencedColliderShapes.Contains(reference.Id))
                                    continue;

                                yield return new AssetReference(reference.Id, reference.Url);
                                referencedColliderShapes.Add(reference.Id);
                            }
                        }
                    }
                }
            }
        }
Example #13
0
        public static void LoadSolution(PackageSession session, string filePath, List<string> packagePaths, ILogger sessionResult)
        {
            var solutionDirectory = Path.GetDirectoryName(filePath);
            if (solutionDirectory == null)
            {
                throw new ArgumentException("Must be absolute", "filePath");
            }

            // The session should save back its changes to the solution
            session.SolutionPath = filePath;

            var solution = Solution.FromFile(filePath);

            foreach (var project in solution.Projects)
            {
                string packagePath;
                if (IsPackage(project, out packagePath))
                {
                    var packageFullPath = Path.Combine(solutionDirectory, packagePath);
                    packagePaths.Add(packageFullPath);
                }
            }
        }
Example #14
0
        public static void LoadSolution(PackageSession session, string filePath, List <string> packagePaths, ILogger sessionResult)
        {
            var solutionDirectory = Path.GetDirectoryName(filePath);

            if (solutionDirectory == null)
            {
                throw new ArgumentException("Must be absolute", "filePath");
            }

            // The session should save back its changes to the solution
            session.SolutionPath = filePath;

            var solution = Solution.FromFile(filePath);

            foreach (var project in solution.Projects)
            {
                string packagePath;
                if (IsPackage(project, out packagePath))
                {
                    var packageFullPath = Path.Combine(solutionDirectory, packagePath);
                    packagePaths.Add(packageFullPath);
                }
            }

            var     versionHeader = solution.Properties.FirstOrDefault(x => x.Name == "VisualStudioVersion");
            Version version;

            if (versionHeader != null && Version.TryParse(versionHeader.Value, out version))
            {
                session.VisualStudioVersion = version;
            }
            else
            {
                session.VisualStudioVersion = null;
            }
        }
        public static void LoadSolution(PackageSession session, string filePath, List <string> packagePaths, ILogger sessionResult)
        {
            var solutionDirectory = Path.GetDirectoryName(filePath);

            if (solutionDirectory == null)
            {
                throw new ArgumentException("Must be absolute", "filePath");
            }

            // The session should save back its changes to the solution
            session.SolutionPath = filePath;

            var solution = Solution.FromFile(filePath);

            foreach (var project in solution.Projects)
            {
                string packagePath;
                if (IsPackage(project, out packagePath))
                {
                    var packageFullPath = Path.Combine(solutionDirectory, packagePath);
                    packagePaths.Add(packageFullPath);
                }
            }
        }
Example #16
0
 public IEnumerable<IReference> EnumerateCompileTimeDependencies(PackageSession session)
 {
     var gameSettings = session.CurrentPackage?.Assets.Find(GameSettingsAsset.GameSettingsLocation);
     if (gameSettings != null)
     {
         yield return new AssetReference(gameSettings.Id, gameSettings.Location);
     }
 }
        public static void SaveSolution(PackageSession session, ILogger log)
        {
            // If the solution path is not set, we can't save a solution (sln)
            if (session.SolutionPath == null)
            {
                return;
            }

            var solutionPath = UPath.Combine(Environment.CurrentDirectory, session.SolutionPath);

            try
            {
                Solution solution;

                var solutionDir = solutionPath.GetParent();

                // If the solution already exists, we need to update it
                if (File.Exists(solutionPath))
                {
                    solution = Solution.FromFile(solutionPath);
                }
                else
                {
                    solution = new Solution {
                        FullPath = solutionPath
                    };
                    solution.Headers.Add(SolutionHeader);
                }

                // Pre-create solution wide global sections
                if (!solution.GlobalSections.Contains("SolutionConfigurationPlatforms"))
                {
                    solution.GlobalSections.Add(new Section("SolutionConfigurationPlatforms", "GlobalSection", "preSolution", Enumerable.Empty <PropertyItem>()));
                }
                if (!solution.GlobalSections.Contains("ProjectConfigurationPlatforms"))
                {
                    solution.GlobalSections.Add(new Section("ProjectConfigurationPlatforms", "GlobalSection", "postSolution", Enumerable.Empty <PropertyItem>()));
                }
                if (!solution.GlobalSections.Contains("NestedProjects"))
                {
                    solution.GlobalSections.Add(new Section("NestedProjects", "GlobalSection", "preSolution", Enumerable.Empty <PropertyItem>()));
                }

                // ---------------------------------------------
                // 0. Pre-select only platforms effectively used by this session
                // ---------------------------------------------
                var platformsUsedBySession = new SolutionPlatformCollection();
                platformsUsedBySession.AddRange(AssetRegistry.SupportedPlatforms.Where(platform => platform.Type == PlatformType.Windows));

                foreach (var package in session.LocalPackages)
                {
                    foreach (var profile in package.Profiles.Where(profile => profile.Platform != PlatformType.Shared && profile.ProjectReferences.Count > 0))
                    {
                        var platformType = profile.Platform;
                        if (!platformsUsedBySession.Contains(platformType))
                        {
                            platformsUsedBySession.AddRange(AssetRegistry.SupportedPlatforms.Where(platform => platform.Type == platformType));
                        }
                    }
                }

                // ---------------------------------------------
                // 1. Update configuration/platform
                // ---------------------------------------------
                var configs = new List <Tuple <string, SolutionPlatform, SolutionPlatformPart> >();
                foreach (var configName in platformsUsedBySession.SelectMany(solutionPlatform => solutionPlatform.Configurations).Select(config => config.Name).Distinct())
                {
                    foreach (var platform in platformsUsedBySession)
                    {
                        foreach (var platformPart in platform.GetParts())
                        {
                            // Skip platforms with IncludeInSolution == false
                            if (!platformPart.IncludeInSolution)
                            {
                                continue;
                            }

                            configs.Add(new Tuple <string, SolutionPlatform, SolutionPlatformPart>(configName, platform, platformPart));
                        }
                    }
                }

                // Order per config and then per platform names
                configs = configs.OrderBy(part => part.Item1, StringComparer.InvariantCultureIgnoreCase).ThenBy(part => part.Item3.SafeSolutionName, StringComparer.InvariantCultureIgnoreCase).ToList();

                // Write configs in alphabetical order to avoid changes in sln after it is generated
                var solutionPlatforms = solution.GlobalSections["SolutionConfigurationPlatforms"];
                solutionPlatforms.Properties.Clear();
                foreach (var config in configs)
                {
                    var solutionConfigPlatform = string.Format("{0}|{1}", config.Item1, config.Item3.SafeSolutionName);
                    if (!solutionPlatforms.Properties.Contains(solutionConfigPlatform))
                    {
                        solutionPlatforms.Properties.Add(new PropertyItem(solutionConfigPlatform, solutionConfigPlatform));
                    }
                }

                // Remove projects that are no longer available on the disk
                var projectToRemove = solution.Projects.Where(project => !project.IsSolutionFolder && !File.Exists(project.FullPath)).ToList();
                foreach (var project in projectToRemove)
                {
                    solution.Projects.Remove(project);
                }

                // ---------------------------------------------
                // 2. Update each package
                // ---------------------------------------------
                foreach (var package in session.LocalPackages)
                {
                    if (string.IsNullOrWhiteSpace(package.Meta.Name))
                    {
                        log.Error($"Error while saving solution [{solutionPath}]. Package [{package.FullPath}] should have a Meta.Name");
                        continue;
                    }

                    var packageFolder = solution.Projects.FindByGuid((Guid)package.Id);

                    // Packages are created as solution folders in VisualStudio
                    if (packageFolder == null)
                    {
                        // Create this package as a Solution Folder
                        packageFolder = new Project(solution,
                                                    (Guid)package.Id,
                                                    KnownProjectTypeGuid.SolutionFolder,
                                                    package.Meta.Name,
                                                    package.Meta.Name,
                                                    Guid.Empty,
                                                    Enumerable.Empty <Section>(),
                                                    Enumerable.Empty <PropertyItem>(),
                                                    Enumerable.Empty <PropertyItem>());

                        // As it is making a copy, we need to get it back
                        solution.Projects.Add(packageFolder);
                        packageFolder = solution.Projects[package.Id];
                    }

                    // Update the path to the solution everytime we save a package
                    packageFolder.Sections.Clear();
                    var relativeUrl = package.FullPath.MakeRelative(solutionDir);
                    packageFolder.Sections.Add(new Section(SiliconStudioPackage, "ProjectSection", "preProject", new[] { new PropertyItem(relativeUrl, relativeUrl) }));

                    // ---------------------------------------------
                    // 2.1. Update each project
                    // ---------------------------------------------
                    foreach (var profile in package.Profiles.OrderBy(x => x.Platform == PlatformType.Windows ? 0 : 1))
                    {
                        foreach (var project in profile.ProjectReferences)
                        {
                            var projectInSolution = solution.Projects.FindByGuid(project.Id);

                            if (projectInSolution == null)
                            {
                                var projectRelativePath = project.Location.MakeRelative(solutionDir);

                                // Create this package as a Solution Folder
                                projectInSolution = new Project(solution,
                                                                project.Id,
                                                                KnownProjectTypeGuid.CSharp,
                                                                project.Location.GetFileNameWithoutExtension(),
                                                                projectRelativePath.ToWindowsPath(),
                                                                package.Id,
                                                                Enumerable.Empty <Section>(),
                                                                Enumerable.Empty <PropertyItem>(),
                                                                Enumerable.Empty <PropertyItem>());

                                solution.Projects.Add(projectInSolution);

                                // Resolve it again, as the original code is making a clone of it (why?)
                                projectInSolution = solution.Projects.FindByGuid(project.Id);
                            }

                            // Projects are always in a package (solution folder) in the solution
                            projectInSolution.ParentGuid = package.Id;

                            // Update platforms per project (active solution and build flag per platform)

                            // Clear all platform properties for this project and recompute them here
                            projectInSolution.PlatformProperties.Clear();

                            foreach (var config in configs)
                            {
                                var configName   = config.Item1;
                                var platform     = config.Item2;
                                var platformPart = config.Item3;

                                // Filter exe project types
                                if (project.Type == ProjectType.Executable && !platformPart.UseWithExecutables)
                                {
                                    continue;
                                }

                                var platformName = platformPart.SafeSolutionName;

                                var solutionConfigPlatform = string.Format("{0}|{1}", configName, platformName);

                                var configNameInProject   = configName;
                                var platformNameInProject = platformPart.GetProjectName(project.Type);

                                var platformTarget = platform;
                                if (profile.Platform != PlatformType.Shared)
                                {
                                    platformTarget = platformsUsedBySession.FirstOrDefault(plat => plat.Type == profile.Platform);
                                    if (platformTarget == null)
                                    {
                                        // This should not happen as we control our platforms, but when we develop a new one
                                        // we might get it and it is better to cleary state why we are failing.
                                        log.Error("Project contains an unsupported platform " + profile.Platform);
                                        throw new InvalidOperationException("Unsupported platform " + profile.Platform);
                                    }
                                }

                                bool isPartOfBuild = platformTarget == platform;
                                // If the config doesn't exist for this platform, just use the default config name
                                if (!platformTarget.Configurations.Contains(configName))
                                {
                                    configNameInProject = platformTarget.Configurations.FirstOrDefault().Name;
                                    isPartOfBuild       = false;
                                }

                                // If the config doesn't exist for this platform, just use the default config name
                                if (platformTarget.GetParts().All(part => part.GetProjectName(project.Type) != platformNameInProject))
                                {
                                    platformNameInProject = platformTarget.GetParts().FirstOrDefault(part => part.IsProjectHandled(project.Type)).SafeSolutionName;
                                    isPartOfBuild         = false;
                                }

                                var projectConfigPlatform = string.Format("{0}|{1}", configNameInProject, platformNameInProject);

                                var propertyActive = solutionConfigPlatform + ".ActiveCfg";
                                var propertyBuild  = solutionConfigPlatform + ".Build.0";

                                if (!projectInSolution.PlatformProperties.Contains(propertyActive))
                                {
                                    projectInSolution.PlatformProperties.Remove(propertyActive);
                                    projectInSolution.PlatformProperties.Add(new PropertyItem(propertyActive, projectConfigPlatform));
                                }

                                // Only add Build and Deploy for supported configs
                                if (isPartOfBuild)
                                {
                                    projectInSolution.PlatformProperties.Remove(propertyBuild);
                                    projectInSolution.PlatformProperties.Add(new PropertyItem(propertyBuild, projectConfigPlatform));

                                    // If the project is an executable, mark it as deploy
                                    if (project.Type == ProjectType.Executable)
                                    {
                                        var propertyDeploy = solutionConfigPlatform + ".Deploy.0";
                                        projectInSolution.PlatformProperties.Remove(propertyDeploy);
                                        projectInSolution.PlatformProperties.Add(new PropertyItem(propertyDeploy, projectConfigPlatform));
                                    }
                                }
                            }
                        }
                    }

                    // ---------------------------------------------
                    // 3. Remove unused packages from the solution
                    // ---------------------------------------------
                    for (int i = solution.Projects.Count - 1; i >= 0; i--)
                    {
                        var project = solution.Projects[i];
                        if (IsPackage(project) && !session.Packages.ContainsById(project.Guid))
                        {
                            solution.Projects.RemoveAt(i);
                        }
                    }
                }

                solution.Save();
            }
            catch (Exception ex)
            {
                log.Error($"Error while saving solution [{solutionPath}]", ex);
            }
        }
Example #18
0
        public static void SaveSolution(PackageSession session, ILogger log)
        {
            // If the solution path is not set, we can't save a solution (sln)
            if (session.SolutionPath == null)
            {
                return;
            }

            var solutionPath = UPath.Combine(Environment.CurrentDirectory, session.SolutionPath);

            try
            {
                Solution solution;

                var solutionDir = solutionPath.GetParent();

                // If the solution already exists, we need to update it
                if (File.Exists(solutionPath))
                {
                    solution = Solution.FromFile(solutionPath);
                }
                else
                {
                    solution = new Solution { FullPath = solutionPath };
                    solution.Headers.Add(SolutionHeader);
                }

                // Pre-create solution wide global sections
                if (!solution.GlobalSections.Contains("SolutionConfigurationPlatforms"))
                {
                    solution.GlobalSections.Add(new Section("SolutionConfigurationPlatforms", "GlobalSection", "preSolution", Enumerable.Empty<PropertyItem>()));
                }
                if (!solution.GlobalSections.Contains("ProjectConfigurationPlatforms"))
                {
                    solution.GlobalSections.Add(new Section("ProjectConfigurationPlatforms", "GlobalSection", "postSolution", Enumerable.Empty<PropertyItem>()));
                }
                if (!solution.GlobalSections.Contains("NestedProjects"))
                {
                    solution.GlobalSections.Add(new Section("NestedProjects", "GlobalSection", "preSolution", Enumerable.Empty<PropertyItem>()));
                }

                // ---------------------------------------------
                // 0. Pre-select only platforms effectively used by this session
                // ---------------------------------------------
                var platformsUsedBySession = new SolutionPlatformCollection();
                platformsUsedBySession.AddRange(AssetRegistry.SupportedPlatforms.Where(platform => platform.Type == PlatformType.Windows));

                foreach (var package in session.LocalPackages)
                {
                    foreach (var profile in package.Profiles.Where(profile => profile.Platform != PlatformType.Shared && profile.ProjectReferences.Count > 0))
                    {
                        var platformType = profile.Platform;
                        if (!platformsUsedBySession.Contains(platformType))
                        {
                            platformsUsedBySession.AddRange(AssetRegistry.SupportedPlatforms.Where(platform => platform.Type == platformType));
                        }
                    }
                }

                // ---------------------------------------------
                // 1. Update configuration/platform
                // ---------------------------------------------
                var configs = new List<Tuple<string, SolutionPlatform, SolutionPlatformPart>>();
                foreach (var configName in platformsUsedBySession.SelectMany(solutionPlatform => solutionPlatform.Configurations).Select(config => config.Name).Distinct())
                {
                    foreach (var platform in platformsUsedBySession)
                    {
                        foreach (var platformPart in platform.GetParts())
                        {
                            // Skip platforms with IncludeInSolution == false
                            if (!platformPart.IncludeInSolution)
                                continue;

                            configs.Add(new Tuple<string, SolutionPlatform, SolutionPlatformPart>(configName, platform, platformPart));
                        }
                    }
                }

                // Order per config and then per platform names
                configs = configs.OrderBy(part => part.Item1, StringComparer.InvariantCultureIgnoreCase).ThenBy(part => part.Item3.SafeSolutionName, StringComparer.InvariantCultureIgnoreCase).ToList();

                // Write configs in alphabetical order to avoid changes in sln after it is generated
                var solutionPlatforms = solution.GlobalSections["SolutionConfigurationPlatforms"];
                solutionPlatforms.Properties.Clear();
                foreach (var config in configs)
                {
                    var solutionConfigPlatform = string.Format("{0}|{1}", config.Item1, config.Item3.SafeSolutionName);
                    if (!solutionPlatforms.Properties.Contains(solutionConfigPlatform))
                    {
                        solutionPlatforms.Properties.Add(new PropertyItem(solutionConfigPlatform, solutionConfigPlatform));
                    }                    
                }

                // Remove projects that are no longer available on the disk
                var projectToRemove = solution.Projects.Where(project => !project.IsSolutionFolder && !File.Exists(project.FullPath)).ToList();
                foreach (var project in projectToRemove)
                {
                    solution.Projects.Remove(project);
                }

                // ---------------------------------------------
                // 2. Update each package
                // ---------------------------------------------
                foreach (var package in session.LocalPackages)
                {
                    if (string.IsNullOrWhiteSpace(package.Meta.Name))
                    {
                        log.Error("Error while saving solution [{0}]. Package [{1}] should have a Meta.Name", solutionPath, package.FullPath);
                        continue;
                    }

                    var packageFolder = solution.Projects.FindByGuid(package.Id);

                    // Packages are created as solution folders in VisualStudio
                    if (packageFolder == null)
                    {
                        // Create this package as a Solution Folder 
                        packageFolder = new Project(solution,
                            package.Id,
                            KnownProjectTypeGuid.SolutionFolder,
                            package.Meta.Name,
                            package.Meta.Name,
                            Guid.Empty,
                            Enumerable.Empty<Section>(),
                            Enumerable.Empty<PropertyItem>(),
                            Enumerable.Empty<PropertyItem>());

                        // As it is making a copy, we need to get it back
                        solution.Projects.Add(packageFolder);
                        packageFolder = solution.Projects[package.Id];
                    }

                    // Update the path to the solution everytime we save a package
                    packageFolder.Sections.Clear();
                    var relativeUrl = package.FullPath.MakeRelative(solutionDir);
                    packageFolder.Sections.Add(new Section(SiliconStudioPackage, "ProjectSection", "preProject", new[] { new PropertyItem(relativeUrl, relativeUrl) }));

                    // ---------------------------------------------
                    // 2.1. Update each project
                    // ---------------------------------------------
                    foreach (var profile in package.Profiles.OrderBy(x => x.Platform == PlatformType.Windows ? 0 : 1))
                    {
                        foreach (var project in profile.ProjectReferences)
                        {
                            var projectInSolution = solution.Projects.FindByGuid(project.Id);

                            if (projectInSolution == null)
                            {
                                var projectRelativePath = project.Location.MakeRelative(solutionDir);

                                // Create this package as a Solution Folder 
                                projectInSolution = new Project(solution,
                                    project.Id,
                                    KnownProjectTypeGuid.CSharp,
                                    project.Location.GetFileName(),
                                    projectRelativePath.ToWindowsPath(),
                                    package.Id,
                                    Enumerable.Empty<Section>(),
                                    Enumerable.Empty<PropertyItem>(),
                                    Enumerable.Empty<PropertyItem>());

                                solution.Projects.Add(projectInSolution);

                                // Resolve it again, as the original code is making a clone of it (why?)
                                projectInSolution = solution.Projects.FindByGuid(project.Id);
                            }

                            // Projects are always in a package (solution folder) in the solution
                            projectInSolution.ParentGuid = package.Id;

                            // Update platforms per project (active solution and build flag per platform)

                            // Clear all platform properties for this project and recompute them here
                            projectInSolution.PlatformProperties.Clear();

                            foreach (var config in configs)
                            {
                                var configName = config.Item1;
                                var platform = config.Item2;
                                var platformPart = config.Item3;

                                // Filter exe project types
                                if (project.Type == ProjectType.Executable && !platformPart.UseWithExecutables)
                                {
                                    continue;
                                }

                                var platformName = platformPart.SafeSolutionName;

                                var solutionConfigPlatform = string.Format("{0}|{1}", configName, platformName);

                                var configNameInProject = configName;
                                var platformNameInProject = platformPart.GetProjectName(project.Type);

                                var platformTarget = platform;
                                if (profile.Platform != PlatformType.Shared)
                                {
                                    platformTarget = platformsUsedBySession.First(plat => plat.Type == profile.Platform);
                                }

                                bool isPartOfBuild = platformTarget == platform;
                                // If the config doesn't exist for this platform, just use the default config name 
                                if (!platformTarget.Configurations.Contains(configName))
                                {
                                    configNameInProject = platformTarget.Configurations.FirstOrDefault().Name;
                                    isPartOfBuild = false;
                                }

                                // If the config doesn't exist for this platform, just use the default config name 
                                if (platformTarget.GetParts().All(part => part.GetProjectName(project.Type) != platformNameInProject))
                                {
                                    platformNameInProject = platformTarget.GetParts().FirstOrDefault(part => part.IsProjectHandled(project.Type)).SafeSolutionName;
                                    isPartOfBuild = false;
                                }

                                var projectConfigPlatform = string.Format("{0}|{1}", configNameInProject, platformNameInProject);

                                var propertyActive = solutionConfigPlatform + ".ActiveCfg";
                                var propertyBuild = solutionConfigPlatform + ".Build.0";

                                if (!projectInSolution.PlatformProperties.Contains(propertyActive))
                                {
                                    projectInSolution.PlatformProperties.Remove(propertyActive);
                                    projectInSolution.PlatformProperties.Add(new PropertyItem(propertyActive, projectConfigPlatform));
                                }

                                // Only add Build and Deploy for supported configs
                                if (isPartOfBuild)
                                {
                                    projectInSolution.PlatformProperties.Remove(propertyBuild);
                                    projectInSolution.PlatformProperties.Add(new PropertyItem(propertyBuild, projectConfigPlatform));

                                    // If the project is an executable, mark it as deploy
                                    if (project.Type == ProjectType.Executable)
                                    {
                                        var propertyDeploy = solutionConfigPlatform + ".Deploy.0";
                                        projectInSolution.PlatformProperties.Remove(propertyDeploy);
                                        projectInSolution.PlatformProperties.Add(new PropertyItem(propertyDeploy, projectConfigPlatform));
                                    }
                                }
                            }
                        }
                    }

                    // ---------------------------------------------
                    // 3. Remove unused packages from the solution
                    // ---------------------------------------------
                    for (int i = solution.Projects.Count - 1; i >=0; i--)
                    {
                        var project = solution.Projects[i];
                        if (IsPackage(project) && !session.Packages.ContainsById(project.Guid))
                        {
                            solution.Projects.RemoveAt(i);
                        }
                    }
                }

                solution.Save();
            }
            catch (Exception ex)
            {
                log.Error("Error while saving solution [{0}]", ex, solutionPath);
            }
        }
        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;
        }
Example #20
0
        public void TestImportModelSimple()
        {
            var file = Path.Combine(Environment.CurrentDirectory, @"scenes\goblin.fbx");

            // Create a project with an asset reference a raw file
            var project = new Package { FullPath = Path.Combine(Environment.CurrentDirectory, "ModelAssets", "ModelAssets" + Package.PackageFileExtension) };
            using (var session = new PackageSession(project))
            {
                var importSession = new AssetImportSession(session);

                // ------------------------------------------------------------------
                // Step 1: Add files to session
                // ------------------------------------------------------------------
                importSession.AddFile(file, project, UDirectory.Empty);

                // ------------------------------------------------------------------
                // Step 2: Stage assets
                // ------------------------------------------------------------------
                var stageResult = importSession.Stage();
                Assert.IsTrue(stageResult);
                Assert.AreEqual(0, project.Assets.Count);

                // ------------------------------------------------------------------
                // Step 3: Import asset directly
                // ------------------------------------------------------------------
                importSession.Import();
                Assert.AreEqual(4, project.Assets.Count);
                var assetItem = project.Assets.FirstOrDefault(item => item.Asset is EntityAsset);
                Assert.NotNull(assetItem);

                EntityAnalysis.UpdateEntityReferences(((EntityAsset)assetItem.Asset).Hierarchy);

                var assetCollection = new AssetItemCollection();
                // Remove directory from the location
                assetCollection.Add(assetItem);

                Console.WriteLine(assetCollection.ToText());

                //session.Save();

                // Create and mount database file system
                var objDatabase = new ObjectDatabase("/data/db", "index", "/local/db");
                var databaseFileProvider = new DatabaseFileProvider(objDatabase);
                AssetManager.GetFileProvider = () => databaseFileProvider;

                ((EntityAsset)assetItem.Asset).Hierarchy.Entities[0].Components.RemoveWhere(x => x.Key != TransformComponent.Key);
                //((EntityAsset)assetItem.Asset).Data.Entities[1].Components.RemoveWhere(x => x.Key != SiliconStudio.Paradox.Engine.TransformComponent.Key);

                var assetManager = new AssetManager();
                assetManager.Save("Entity1", ((EntityAsset)assetItem.Asset).Hierarchy);

                assetManager = new AssetManager();
                var entity = assetManager.Load<Entity>("Entity1");

                var entity2 = entity.Clone();

                var entityAsset = (EntityAsset)assetItem.Asset;
                entityAsset.Hierarchy.Entities[0].Components.Add(TransformComponent.Key, new TransformComponent());

                var entityAsset2 = (EntityAsset)AssetCloner.Clone(entityAsset);
                entityAsset2.Hierarchy.Entities[0].Components.Get(TransformComponent.Key).Position = new Vector3(10.0f, 0.0f, 0.0f);

                AssetMerge.Merge(entityAsset, entityAsset2, null, AssetMergePolicies.MergePolicyAsset2AsNewBaseOfAsset1);
            }
        }
Example #21
0
        /// <summary>
        /// Loads a package from specified file path.
        /// </summary>
        /// <param name="filePath">The file path to a package file.</param>
        /// <param name="sessionResult">The session result.</param>
        /// <param name="loadParameters">The load parameters.</param>
        /// <returns>A package.</returns>
        /// <exception cref="System.ArgumentNullException">filePath</exception>
        /// <exception cref="System.ArgumentException">File [{0}] must exist.ToFormat(filePath);filePath</exception>
        public static void Load(string filePath, PackageSessionResult sessionResult, PackageLoadParameters loadParameters = null)
        {
            if (filePath == null) throw new ArgumentNullException("filePath");
            if (sessionResult == null) throw new ArgumentNullException("sessionResult");

            // Make sure with have valid parameters
            loadParameters = loadParameters ?? PackageLoadParameters.Default();

            // Make sure to use a full path.
            filePath = FileUtility.GetAbsolutePath(filePath);

            if (!File.Exists(filePath)) throw new ArgumentException("File [{0}] must exist".ToFormat(filePath), "filePath");

            try
            {
                // Enable reference analysis caching during loading
                AssetReferenceAnalysis.EnableCaching = true;

                using (var profile = Profiler.Begin(PackageSessionProfilingKeys.Loading))
                {
                    sessionResult.Clear();
                    sessionResult.Progress("Loading..", 0, 1);

                    var session = new PackageSession();

                    var packagePaths = new List<string>();

                    // If we have a solution, load all packages
                    if (PackageSessionHelper.IsSolutionFile(filePath))
                    {
                        PackageSessionHelper.LoadSolution(session, filePath, packagePaths, sessionResult);
                    }
                    else if (PackageSessionHelper.IsPackageFile(filePath))
                    {
                        packagePaths.Add(filePath);
                    }
                    else
                    {
                        sessionResult.Error("Unsupported file extension (only .sln or {0} are supported)", Package.PackageFileExtension);
                        return;
                    }

                    var cancelToken = loadParameters.CancelToken;

                    // Load all packages
                    var packagesLoaded = new PackageCollection();
                    foreach (var packageFilePath in packagePaths)
                    {
                        PreLoadPackage(session, sessionResult, packageFilePath, false, packagesLoaded, loadParameters);

                        // Output the session only if there is no cancellation
                        if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested)
                        {
                            return;
                        }
                    }

                    // Load all missing references/dependencies
                    session.LoadMissingReferences(sessionResult, loadParameters);

                    // Fix relative references
                    var analysis = new PackageSessionAnalysis(session, GetPackageAnalysisParametersForLoad());
                    var analysisResults = analysis.Run();
                    analysisResults.CopyTo(sessionResult);

                    // Run custom package session analysis
                    foreach (var type in AssetRegistry.GetPackageSessionAnalysisTypes())
                    {
                        var pkgAnalysis = (PackageSessionAnalysisBase)Activator.CreateInstance(type);
                        pkgAnalysis.Session = session;
                        var results = pkgAnalysis.Run();
                        results.CopyTo(sessionResult);
                    }

                    // Output the session only if there is no cancellation
                    if (!cancelToken.HasValue || !cancelToken.Value.IsCancellationRequested)
                    {
                        sessionResult.Session = session;

                        // Defer the initialization of the dependency manager
                        //session.DependencyManager.InitializeDeferred();
                    }

                    // Setup the current package when loading it
                    if (packagePaths.Count == 1)
                    {
                        var currentPackagePath = new UFile(packagePaths[0]);
                        foreach (var package in packagesLoaded)
                        {
                            if (package.FullPath == currentPackagePath)
                            {
                                session.CurrentPackage = package;
                                break;
                            }
                        }
                    }

                    // The session is not dirty when loading it
                    session.IsDirty = false;
                }
            }
            finally
            {
                // Disable reference analysis caching after loading
                AssetReferenceAnalysis.EnableCaching = false;
            }
        }
Example #22
0
        private static bool TryLoadAssets(PackageSession session, ILogger log, Package package, PackageLoadParameters loadParameters)
        {
            // Already loaded
            if (package.State >= PackageState.AssetsReady)
                return true;

            // Dependencies could not properly be loaded
            if (package.State < PackageState.DependenciesReady)
                return false;

            // A package upgrade has previously been tried and denied, so let's keep the package in this state
            if (package.State == PackageState.UpgradeFailed)
                return false;

            try
            {
                // First, check that dependencies have their assets loaded
                bool dependencyError = false;
                foreach (var dependency in package.FindDependencies(false, false))
                {
                    if (!TryLoadAssets(session, log, dependency, loadParameters))
                        dependencyError = true;
                }

                if (dependencyError)
                    return false;

                var pendingPackageUpgrades = new List<PendingPackageUpgrade>();

                // Note: Default state is upgrade failed (for early exit on error/exceptions)
                // We will update to success as soon as loading is finished.
                package.State = PackageState.UpgradeFailed;

                // Process store dependencies for upgraders
                foreach (var packageDependency in package.Meta.Dependencies)
                {
                    var dependencyPackage = session.Packages.Find(packageDependency);
                    if (dependencyPackage == null)
                    {
                        continue;
                    }

                    // Check for upgraders
                    var packageUpgrader = session.CheckPackageUpgrade(log, package, packageDependency, dependencyPackage);
                    if (packageUpgrader != null)
                    {
                        pendingPackageUpgrades.Add(new PendingPackageUpgrade(packageUpgrader, packageDependency, dependencyPackage));
                    }
                }

                // Prepare asset loading
                var newLoadParameters = loadParameters.Clone();
                newLoadParameters.AssemblyContainer = session.assemblyContainer;

                // Default package version override
                newLoadParameters.ExtraCompileProperties = new Dictionary<string, string>();
                var defaultPackageOverride = NugetStore.GetPackageVersionVariable(PackageStore.Instance.DefaultPackageName) + "Override";
                var defaultPackageVersion = PackageStore.Instance.DefaultPackageVersion.Version;
                newLoadParameters.ExtraCompileProperties.Add(defaultPackageOverride, new Version(defaultPackageVersion.Major, defaultPackageVersion.Minor).ToString());
                if (loadParameters.ExtraCompileProperties != null)
                {
                    foreach (var property in loadParameters.ExtraCompileProperties)
                    {
                        newLoadParameters.ExtraCompileProperties[property.Key] = property.Value;
                    }
                }

                if (pendingPackageUpgrades.Count > 0)
                {
                    var upgradeAllowed = true;
                    // Need upgrades, let's ask user confirmation
                    if (loadParameters.PackageUpgradeRequested != null)
                    {
                        upgradeAllowed = loadParameters.PackageUpgradeRequested(package, pendingPackageUpgrades);
                    }

                    if (!upgradeAllowed)
                    {
                        log.Error("Necessary package migration for [{0}] has not been allowed", package.Meta.Name);
                        return false;
                    }

                    // Perform pre assembly load upgrade
                    foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                    {
                        var packageUpgrader = pendingPackageUpgrade.PackageUpgrader;
                        var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                        if (!packageUpgrader.UpgradeBeforeAssembliesLoaded(session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage))
                        {
                            log.Error("Error while upgrading package [{0}] for [{1}] from version [{2}] to [{3}]", package.Meta.Name, dependencyPackage.Meta.Name, pendingPackageUpgrade.Dependency.Version, dependencyPackage.Meta.Version);
                            return false;
                        }
                    }
                }

                // Load assemblies. Set the package filename to the path on disk, in case of renaming.
                // TODO: Could referenced projects be associated to other packages than this one?
                newLoadParameters.ExtraCompileProperties.Add("SiliconStudioCurrentPackagePath", package.FullPath);
                package.LoadAssemblies(log, newLoadParameters);

                // Load list of assets
                newLoadParameters.AssetFiles = Package.ListAssetFiles(log, package, loadParameters.CancelToken);

                if (pendingPackageUpgrades.Count > 0)
                {
                    // Perform upgrades
                    foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                    {
                        var packageUpgrader = pendingPackageUpgrade.PackageUpgrader;
                        var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                        if (!packageUpgrader.Upgrade(session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage, newLoadParameters.AssetFiles))
                        {
                            log.Error("Error while upgrading package [{0}] for [{1}] from version [{2}] to [{3}]", package.Meta.Name, dependencyPackage.Meta.Name, pendingPackageUpgrade.Dependency.Version, dependencyPackage.Meta.Version);
                            return false;
                        }

                        // Update dependency to reflect new requirement
                        pendingPackageUpgrade.Dependency.Version = pendingPackageUpgrade.PackageUpgrader.Attribute.PackageUpdatedVersionRange;
                    }

                    // Mark package as dirty
                    package.IsDirty = true;
                }

                // Load assets
                package.LoadAssets(log, newLoadParameters);

                // Validate assets from package
                package.ValidateAssets(newLoadParameters.GenerateNewAssetIds);

                if (pendingPackageUpgrades.Count > 0)
                {
                    // Perform post asset load upgrade
                    foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                    {
                        var packageUpgrader = pendingPackageUpgrade.PackageUpgrader;
                        var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                        if (!packageUpgrader.UpgradeAfterAssetsLoaded(session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage, pendingPackageUpgrade.DependencyVersionBeforeUpgrade))
                        {
                            log.Error("Error while upgrading package [{0}] for [{1}] from version [{2}] to [{3}]", package.Meta.Name, dependencyPackage.Meta.Name, pendingPackageUpgrade.Dependency.Version, dependencyPackage.Meta.Version);
                            return false;
                        }
                    }

                    // Mark package as dirty
                    package.IsDirty = true;
                }

                // Mark package as ready
                package.State = PackageState.AssetsReady;

                // Freeze the package after loading the assets
                session.FreezePackage(package);

                return true;
            }
            catch (Exception ex)
            {
                log.Error("Error while loading package [{0}]", ex, package);
                return false;
            }
        }
Example #23
0
        private static Package PreLoadPackage(PackageSession session, ILogger log, string filePath, bool isSystemPackage, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }
            if (log == null)
            {
                throw new ArgumentNullException("log");
            }
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }
            if (loadedPackages == null)
            {
                throw new ArgumentNullException("loadedPackages");
            }
            if (loadParameters == null)
            {
                throw new ArgumentNullException("loadParameters");
            }

            try
            {
                var packageId = Package.GetPackageIdFromFile(filePath);

                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageId))
                {
                    return(session.Packages.Find(packageId));
                }

                // Package is already loaded, use the instance
                if (loadedPackages.ContainsById(packageId))
                {
                    return(loadedPackages.Find(packageId));
                }

                // Load the package without loading assets
                var newLoadParameters = loadParameters.Clone();
                newLoadParameters.AssemblyContainer = session.assemblyContainer;

                // Load the package
                var package = Package.Load(log, filePath, newLoadParameters);
                package.IsSystem = isSystemPackage;

                // Add the package has loaded before loading dependencies
                loadedPackages.Add(package);

                // Load package dependencies
                PreLoadPackageDependencies(session, log, package, loadedPackages, loadParameters);

                // Add the package to the session but don't freeze it yet
                session.Packages.Add(package);

                // Validate assets from package
                package.ValidateAssets(loadParameters.GenerateNewAssetIds);

                // Freeze the package after loading the assets
                session.FreezePackage(package);

                return(package);
            }
            catch (Exception ex)
            {
                log.Error("Error while pre-loading package [{0}]", ex, filePath);
            }

            return(null);
        }
Example #24
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);
 }
Example #25
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);
Example #26
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);
 }
Example #27
0
        private static void GenerateUnitTestProject(string outputDirectory, string templateFile, string name)
        {
            var projectTemplate = ProjectTemplate.Load(templateFile);

            // Force reference to Paradox.Assets (to have acess to SolutionPlatform)
            projectTemplate.Assemblies.Add(typeof(GraphicsProfile).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(ParadoxConfig).Assembly.FullName);

            var options = new Dictionary<string, object>();

            var session = new PackageSession();
            var result = new LoggerResult();

            var templateGeneratorParameters = new TemplateGeneratorParameters();
            templateGeneratorParameters.OutputDirectory = outputDirectory;
            templateGeneratorParameters.Session = session;
            templateGeneratorParameters.Name = name;
            templateGeneratorParameters.Logger = result;
            templateGeneratorParameters.Description = new TemplateDescription();

            PackageUnitTestGenerator.Default.Generate(templateGeneratorParameters);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating package: {0}", result.ToText());
                return;
            }

            var package = templateGeneratorParameters.Package;

            var previousCurrent = session.CurrentPackage;
            session.CurrentPackage = package;

            // Compute Paradox Sdk relative path
            // We are supposed to be in standard output binary folder, so Paradox root should be at ..\..
            var paradoxPath = UDirectory.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), new UDirectory(@"..\.."));
            var paradoxRelativePath = new UDirectory(paradoxPath)
                .MakeRelative(outputDirectory)
                .ToString()
                .Replace('/', '\\');
            paradoxRelativePath = paradoxRelativePath.TrimEnd('\\');

            options["Namespace"] = name;
            options["Package"] = package;
            options["Platforms"] = new List<SolutionPlatform>(AssetRegistry.SupportedPlatforms);
            options["ParadoxSdkRelativeDir"] = paradoxRelativePath;

            // Generate project template
            var projectGuid = Guid.NewGuid();
            result = projectTemplate.Generate(outputDirectory, name, projectGuid, options);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating solution: {0}", result.ToText());
                return;
            }

            var sharedProfile = package.Profiles[PlatformType.Shared];

            // Setup the assets folder
            Directory.CreateDirectory(UPath.Combine(outputDirectory, (UDirectory)"Assets/Shared"));

            // Add Windows test as Shared library
            var projectWindowsRef = new ProjectReference();
            projectWindowsRef.Id = projectGuid;
            projectWindowsRef.Location = UPath.Combine(outputDirectory, (UFile)(name + ".Windows.csproj"));
            projectWindowsRef.Type = SiliconStudio.Assets.ProjectType.Library;
            sharedProfile.ProjectReferences.Add(projectWindowsRef);

            // Generate executable projects for each platform
            foreach (var platform in AssetRegistry.SupportedPlatforms)
            {
                var platformProfile = new PackageProfile(platform.Name) { Platform = platform.Type };
                platformProfile.AssetFolders.Add(new AssetFolder("Assets/"+ platform.Name));
                
                // Log progress
                var projectName = name + "." + platform.Type;

                // Create project reference
                var projectPlatformRef = new ProjectReference();
                projectPlatformRef.Id = projectGuid;
                projectPlatformRef.Location = UPath.Combine(outputDirectory, (UFile)(projectName + ".csproj"));
                projectPlatformRef.Type = SiliconStudio.Assets.ProjectType.Executable;

                platformProfile.ProjectReferences.Add(projectPlatformRef);

                // Add build configuration per platform
                platform.Properties.CopyTo(platformProfile.Properties, true);

                package.Profiles.Add(platformProfile);
            }

            session.CurrentPackage = previousCurrent;

            result = session.Save();
            if (result.HasErrors)
            {
                Console.WriteLine("Error saving package: {0}", result.ToText());
                return;
            }
        }
 public TextureAlphaComponentSplitter(PackageSession assetSession)
 {
     this.assetSession = assetSession;
 }
        public override bool Upgrade(PackageSession session, ILogger log, Package dependentPackage, PackageDependency dependency, Package dependencyPackage, IList<PackageLoadingAssetFile> assetFiles)
        {
            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>(model);
                            var modelAsset = modelAssetsWithSekeleton.FirstOrDefault(x => x.Asset.AssetPath == modelReference.Location);

                            foreach (var animation in animationComponent.Animations)
                            {
                                var animationReference = DynamicYamlExtensions.ConvertTo<AssetReference>(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(AssetId.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(AssetId.Parse((string)skeletonAsset.DynamicRootNode.Id), skeletonAsset.Asset.AssetPath.MakeRelative(animationAsset.Asset.AssetPath.GetParent()));
                    animationAsset.DynamicRootNode.PreviewModel = new AssetReference(AssetId.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();
            }

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

            if (dependency.Version.MinVersion < new PackageVersion("1.7.0-alpha02"))
            {
                foreach (var assetFile in assetFiles)
                {
                    if (!IsYamlAsset(assetFile))
                        continue;

                    using (var assetYaml = assetFile.AsYamlAsset())
                    {
                        if (assetYaml == null)
                            continue;

                        var sourceNode = assetYaml.DynamicRootNode.Source;
                        var sourceHashNode = assetYaml.DynamicRootNode.SourceHash;
                        if (sourceHashNode != null)
                        {
                            var source = DynamicYamlExtensions.ConvertTo<UFile>(sourceNode);
                            var sourceHash = DynamicYamlExtensions.ConvertTo<ObjectId>(sourceHashNode);
                            var dictionary = new Dictionary<UFile, ObjectId> { { source, sourceHash } };
                            var yamlDic = DynamicYamlExtensions.ConvertFrom(dictionary);
                            yamlDic.Node.Tag = null;
                            assetYaml.DynamicRootNode["~SourceHashes"] = yamlDic;
                            assetYaml.DynamicRootNode.SourceHash = DynamicYamlEmpty.Default;
                        }
                        assetYaml.DynamicRootNode.ImporterId = DynamicYamlEmpty.Default;
                        assetYaml.DynamicRootNode.SourceKeepSideBySide = DynamicYamlEmpty.Default;

                        var assetBase = assetYaml.DynamicRootNode["~Base"];
                        if (assetBase != null)
                        {
                            if (assetBase.Location == "--import--")
                                assetYaml.DynamicRootNode["~Base"] = DynamicYamlEmpty.Default;
                        }
                    }
                }
            }

            //Audio refactor
            if (dependency.Version.MinVersion < new PackageVersion("1.7.0-alpha03"))
            {
                var audioAssets = assetFiles.Where(f => f.FilePath.GetFileExtension() == ".xksnd").Select(x => x.AsYamlAsset()).ToArray();
                foreach (var assetFile in audioAssets)
                {
                    //dispose will save back
                    using (var assetYaml = assetFile)
                    {
                        if (assetYaml == null)
                            continue;

                        if (assetYaml.RootNode.Tag == "!SoundMusic")
                        {
                            assetYaml.RootNode.Tag = "!Sound";
                            assetYaml.DynamicRootNode.Spatialized = false;
                            assetYaml.DynamicRootNode.StreamFromDisk = true;  
                        }
                        else
                        {
                            assetYaml.RootNode.Tag = "!Sound";
                            assetYaml.DynamicRootNode.Spatialized = true;
                            assetYaml.DynamicRootNode.StreamFromDisk = false;
                        }
                    }
                }
            }

            if (dependency.Version.MinVersion < new PackageVersion("1.7.0-alpha03"))
            {
                // Delete EffectLogAsset (now, most of it is auto generated automatically by drawing one frame of the game)
                foreach (var assetFile in assetFiles)
                {
                    if (assetFile.FilePath.GetFileName() == EffectLogAsset.DefaultFile)
                    {
                        assetFile.Deleted = true;
                    }
                }
            }

            if (dependency.Version.MinVersion < new PackageVersion("1.8.4-beta"))
            {
                // Add new generic parameter of MaterialSurfaceNormalMap to effect logs
                var regex = new Regex(@"(?<=ClassName:\s+MaterialSurfaceNormalMap\s+GenericArguments:\s+\[[^\]]*)(?=\])");
                foreach (var assetFile in assetFiles.Where(f => f.FilePath.GetFileExtension() == ".xkeffectlog"))
                {
                    var filePath = assetFile.FilePath;

                    // Load asset data, so the renamed file will have it's AssetContent set
                    if (assetFile.AssetContent == null)
                        assetFile.AssetContent = File.ReadAllBytes(filePath);

                    var sourceText = System.Text.Encoding.UTF8.GetString(assetFile.AssetContent);
                    var newSourceText = regex.Replace(sourceText, ", true");
                    var newAssetContent = System.Text.Encoding.UTF8.GetBytes(newSourceText);

                    if (newSourceText != sourceText)
                    {
                        assetFile.AssetContent = newAssetContent;
                    }

                    //File.WriteAllBytes(newFileName, newAssetContent);
                }
            }

            if (dependency.Version.MinVersion < new PackageVersion("1.9.0-beta"))
            {
                foreach (var assetFile in assetFiles)
                {
                    if (!IsYamlAsset(assetFile))
                        continue;

                    // This upgrader will also mark every yaml asset as dirty. We want to re-save everything with the new serialization system
                    using (var assetYaml = assetFile.AsYamlAsset())
                    {
                        if (assetYaml == null)
                            continue;

                        try
                        {
                            if (assetYaml.DynamicRootNode["~Base"] != null)
                            {
                                var location = ((YamlScalarNode)assetYaml.DynamicRootNode["~Base"].Location.Node).Value;
                                if (location != "--import--")
                                {
                                    var id = ((YamlScalarNode)assetYaml.DynamicRootNode["~Base"].Asset.Id.Node).Value;
                                    var assetUrl = $"{id}:{location}";
                                    assetYaml.DynamicRootNode["Archetype"] = assetUrl;
                                }
                                assetYaml.DynamicRootNode["~Base"] = DynamicYamlEmpty.Default;
                            }
                        }
                        catch
                            (Exception e)
                        {
                            e.Ignore();
                        }
                    }
                }
            }

            return true;
        }
Example #30
0
 protected AssetTracker(PackageSession session)
 {
     this.session = session;
 }
        public void TestMultiplePrefabsInheritanceAndChildren()
        {
            // The purpose of this test is to check that modifying a prefab base is correctly propagated through all 
            // derived prefabs. We use the following scenario:
            //
            // a1: base asset
            // a2: inherit from a1 by composition with 2 instances (baseParts: a1 => 2 instances)
            // a3: inherit from a1 by composition with 1 instances (baseParts: a1 => 1 instances)
            // a4: inherit from a2 and a3 by composition with 1 instances for each (baseParts: a1 => 1 instance, a2 => 1 instance)
            //
            // Unlike TestMultiplePrefabsMixedInheritance, we use only inheritance by composition for this scenario to match current use cases

            var package = new Package();

            var assetItems = package.Assets;


            // First we create assets with the following configuration:
            // a1:                  a2: (baseParts: a1, 2 instances)     a3: (baseParts: a1)               a4: (baseParts: a2 x 1, a3 x 1)
            //  | er                 | er1 (base: er)                     | er1' (base: er)                 | eRoot
            //    | ea                 | ea1 (base: ea)                     | ea1' (base: ea)                 | er1* (base: er)  
            //    | eb                 | eb1 (base: eb)                     | eb1' (base: eb)                   | ea1* (base: ea)
            //    | ec                 | ec1 (base: ec)                     | ec1' (base: ec)                   | eb1* (base: eb)
            //                       | er2 (base: er)                                                           | ec1* (base: ec)
            //                         | ea2 (base: ea)                                                       | er2* (base: er)  
            //                         | eb2 (base: eb)                                                         | ea2* (base: ea)
            //                         | ec2 (base: ec)                                                         | eb2* (base: eb)
            //                                                                                                  | ec2* (base: ec)  
            //                                                                                              | er1'* (base: er)     
            //                                                                                                | ea1'* (base: ea)    
            //                                                                                                | eb1'* (base: eb)  
            //                                                                                                | ec1'* (base: ec)
            var a1 = new PrefabAsset();
            var er = new Entity("er");
            var ea = new Entity("ea");
            var eb = new Entity("eb");
            var ec = new Entity("ec");
            a1.Hierarchy.Parts.Add(new EntityDesign(er));
            a1.Hierarchy.Parts.Add(new EntityDesign(ea));
            a1.Hierarchy.Parts.Add(new EntityDesign(eb));
            a1.Hierarchy.Parts.Add(new EntityDesign(ec));
            a1.Hierarchy.RootPartIds.Add(er.Id);
            er.AddChild(ea);
            er.AddChild(eb);
            er.AddChild(ec);

            assetItems.Add(new AssetItem("a1", a1));

            var member = (IMemberDescriptor)TypeDescriptorFactory.Default.Find(typeof(Entity))[nameof(Entity.Name)];
            
            var a2 = new PrefabAsset();
            var a2PartInstance1 = a1.CreatePrefabInstance(a2, "a1");
            foreach (var entity in a2PartInstance1.Parts)
            {
                entity.Entity.Name += "1";
            }

            var a2PartInstance2 = a1.CreatePrefabInstance(a2, "a1");
            foreach (var entity in a2PartInstance2.Parts)
            {
                entity.Entity.Name += "2";
            }

            a2.Hierarchy.Parts.AddRange(a2PartInstance1.Parts);
            a2.Hierarchy.Parts.AddRange(a2PartInstance2.Parts);
            a2.Hierarchy.RootPartIds.AddRange(a2PartInstance1.RootPartIds);
            a2.Hierarchy.RootPartIds.AddRange(a2PartInstance2.RootPartIds);
            Assert.AreEqual(8, a2.Hierarchy.Parts.Count);
            Assert.AreEqual(2, a2.Hierarchy.RootPartIds.Count);
            assetItems.Add(new AssetItem("a2", a2));

            var a3 = new PrefabAsset();
            var a3PartInstance1 = a1.CreatePrefabInstance(a3, "a1");
            foreach (var entity in a3PartInstance1.Parts)
            {
                entity.Entity.Name += "1'";
            }
            a3.Hierarchy.Parts.AddRange(a3PartInstance1.Parts);
            a3.Hierarchy.RootPartIds.AddRange(a3PartInstance1.RootPartIds);
            Assert.AreEqual(4, a3.Hierarchy.Parts.Count);
            Assert.AreEqual(1, a3.Hierarchy.RootPartIds.Count);
            assetItems.Add(new AssetItem("a3", a3));

            var a4 = new PrefabAsset();
            var eRoot = new Entity("eRoot");
            var a2PartInstance3 = a2.CreatePrefabInstance(a4, "a2");

            foreach (var entity in a2PartInstance3.Parts)
            {
                entity.Entity.Name += "*";
            }
            foreach (var entity in a2PartInstance3.Parts.Where(t => a2PartInstance3.RootPartIds.Contains(t.Entity.Id)))
            {
                eRoot.AddChild(entity.Entity);
            }
            var a3PartInstance2 = a3.CreatePrefabInstance(a4, "a3");
            foreach (var entity in a3PartInstance2.Parts)
            {
                entity.Entity.Name += "*";
            }

            a4.Hierarchy.Parts.Add(new EntityDesign(eRoot));
            a4.Hierarchy.Parts.AddRange(a2PartInstance3.Parts);
            a4.Hierarchy.Parts.AddRange(a3PartInstance2.Parts);
            a4.Hierarchy.RootPartIds.Add(eRoot.Id);
            a4.Hierarchy.RootPartIds.AddRange(a3PartInstance2.RootPartIds);

            Assert.AreEqual(13, a4.Hierarchy.Parts.Count);
            Assert.AreEqual(2, a4.Hierarchy.RootPartIds.Count);

            assetItems.Add(new AssetItem("a4", a4));

            Assert.True(a1.DumpTo(Console.Out, "a1 BEFORE PrefabMergeAsset"));
            Assert.True(a2.DumpTo(Console.Out, "a2 BEFORE PrefabMergeAsset"));
            Assert.True(a3.DumpTo(Console.Out, "a3 BEFORE PrefabMergeAsset"));
            Assert.True(a4.DumpTo(Console.Out, "a4 BEFORE PrefabMergeAsset"));


            // Then we simulate a concurrent change to a1 by someone that didn't have a2/a3/a4
            // - Add one component to a1, linking to an existing entity ea
            // - Add a root entity to a1 with a link to an existing entity eb
            //
            // a1:                  a2: (baseParts: a1, 2 instances)     a3: (baseParts: a1)                a4: (baseParts: a2 x 1, a3 x 1)
            //  | er                 | er1 (base: er)                     | er1' (base: er)                  | eRoot
            //    | ea                 | ea1 (base: ea)                     | ea1' (base: ea)                  | er1* (base: er)  
            //    | eb                 | eb1 (base: eb)                     | eb1' (base: eb)                    | ea1* (base: ea)
            //    | ec + link ea       | ec1 + link ea1 (base: ec)          | ec1' + link ea1' (base: ec)        | eb1* (base: eb)
            //  | ex                 | er2 (base: er)                     | ex(1') (base: ex)                    | ec1* + link ea1* (base: ec)
            //    | ey + link eb       | ea2 (base: ea)                     | ey(1') + link eb1'               | er2* (base: er)  
            //                         | eb2 (base: eb)                                                          | ea2* (base: ea)
            //                         | ec2 + link ea2 (base: ec)                                               | eb2* (base: eb)
            //                       | ex(1)                                                                     | ec2* + link ea2* (base: ec)  
            //                         | ey(1) + link eb1                                                    | er1'* (base: er)     
            //                       | ex(2)                                                                   | ea1'* (base: ea)
            //                         | ey(2) + link eb2                                                      | eb1'* (base: eb)  
            //                                                                                                 | ec1'* + link ea1'* (base: ec)  
            //                                                                                               | ex(1*)
            //                                                                                                 | ey(1*) + link eb1*
            //                                                                                               | ex(2*)
            //                                                                                                 | ey(2*) + link eb2*
            //                                                                                               | ex(1') (base: ex)   
            //                                                                                                 | ey(1') + link eb1'*
            ec.Components.Add(new TestEntityComponent() { EntityLink = ea });

            var ex = new Entity("ex");
            var ey = new Entity("ey");
            ey.Components.Add(new TestEntityComponent() { EntityLink = eb });
            ex.AddChild(ey);
            a1.Hierarchy.Parts.Add(new EntityDesign(ex));
            a1.Hierarchy.Parts.Add(new EntityDesign(ey));
            a1.Hierarchy.RootPartIds.Add(ex.Id);
            Assert.AreEqual(6, a1.Hierarchy.Parts.Count);
            Assert.AreEqual(2, a1.Hierarchy.RootPartIds.Count);

            // Simulates the loading of this package
            using (var session = new PackageSession())
            {
                var logger = new LoggerResult();
                session.AddExistingPackage(package, logger);

                Assert.False(logger.HasErrors);

                Assert.True(a1.DumpTo(Console.Out, "a1 AFTER PrefabMergeAsset"));

                // ------------------------------------------------
                // Check for a2
                // ------------------------------------------------
                // a2: (baseParts: a1, 2 instances)
                //  | er1 (base: er)               
                //    | ea1 (base: ea)             
                //    | eb1 (base: eb)             
                //    | ec1 + link ea1 (base: ec)  
                //  | er2 (base: er)               
                //    | ea2 (base: ea)             
                //    | eb2 (base: eb)             
                //    | ec2 + link ea2 (base: ec)  
                //  | ex(1)                          
                //    | ey(1) + link eb1             
                //  | ex(2)                          
                //    | ey(2) + link eb2             
                {
                    Assert.True(a2.DumpTo(Console.Out, "a2 AFTER PrefabMergeAsset"));
                    Assert.AreEqual(4, a2.Hierarchy.RootPartIds.Count);
                    Assert.True(a2.Hierarchy.Parts.All(it => it.Base != null));

                    // Check that we have all expected entities
                    Assert.AreEqual(12, a2.Hierarchy.Parts.Count);

                    var eb1 = a2.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "eb1")?.Entity;
                    var eb2 = a2.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "eb2")?.Entity;
                    Assert.NotNull(eb1);
                    Assert.NotNull(eb2);

                    // Check that we have ex and ey
                    var exList = a2.Hierarchy.Parts.Where(it => it.Entity.Name == ex.Name).ToList();
                    Assert.AreEqual(2, exList.Count);

                    // Check that both [ex] have both 1 element [ey] and the links to eb1/eb2 are correct
                    {
                        var expecting = new List<Entity>() { eb1, eb2 };
                        for (int i = 0; i < exList.Count; i++)
                        {
                            var ex1 = exList[i].Entity;
                            Assert.AreEqual(1, ex1.Transform.Children.Count);
                            var ey1 = ex1.Transform.Children[0].Entity;
                            Assert.AreEqual(ey.Name, ey1.Name);
                            Assert.NotNull(ey1.Get<TestEntityComponent>());

                            var entityLink = ey1.Get<TestEntityComponent>().EntityLink;
                            Assert.True(expecting.Contains(entityLink));
                            expecting.Remove(entityLink);
                        }
                    }

                    // Check link from ec1 to ea1
                    {
                        var ec1 = a2.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "ec1")?.Entity;
                        Assert.NotNull(ec1);

                        var ea1 = a2.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "ea1")?.Entity;
                        Assert.NotNull(ea1);

                        Assert.NotNull(ec1.Get<TestEntityComponent>());
                        Assert.AreEqual(ea1, ec1.Get<TestEntityComponent>().EntityLink);
                    }

                    // Check link from ec2 to ea2
                    {
                        var ec2 = a2.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "ec2")?.Entity;
                        Assert.NotNull(ec2);

                        var ea2 = a2.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "ea2")?.Entity;
                        Assert.NotNull(ea2);

                        Assert.NotNull(ec2.Get<TestEntityComponent>());
                        Assert.AreEqual(ea2, ec2.Get<TestEntityComponent>().EntityLink);
                    }
                }

                // ------------------------------------------------
                // Check for a3
                // ------------------------------------------------
                // a3: (baseParts: a1)             
                //  | er1' (base: er)              
                //    | ea1' (base: ea)            
                //    | eb1' (base: eb)            
                //    | ec1' + link ea1' (base: ec)
                //  | ex1' (base: ex)              
                //    | ey1' + link eb1'           
                {
                    Assert.True(a3.DumpTo(Console.Out, "a3 AFTER PrefabMergeAsset"));

                    Assert.AreEqual(2, a3.Hierarchy.RootPartIds.Count);
                    Assert.True(a3.Hierarchy.Parts.All(it => it.Base != null));

                    // Check that we have all expected entities
                    Assert.AreEqual(6, a3.Hierarchy.Parts.Count);

                    var eb1 = a3.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "eb1'")?.Entity;
                    Assert.NotNull(eb1);

                    // Check that we have ex and ey
                    var exList = a3.Hierarchy.Parts.Where(it => it.Entity.Name == ex.Name).ToList();
                    Assert.AreEqual(1, exList.Count);

                    // Check that [ex] have 1 element [ey] and the link to eb1 is correct
                    {
                        var ex1 = exList[0].Entity;
                        Assert.AreEqual(1, ex1.Transform.Children.Count);
                        var ey1 = ex1.Transform.Children[0].Entity;
                        Assert.AreEqual(ey.Name, ey1.Name);
                        Assert.NotNull(ey1.Get<TestEntityComponent>());

                        Assert.AreEqual(eb1, ey1.Get<TestEntityComponent>().EntityLink);
                    }

                    {
                        var ec1 = a3.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "ec1'")?.Entity;
                        Assert.NotNull(ec1);

                        var ea1 = a3.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "ea1'")?.Entity;
                        Assert.NotNull(ea1);

                        Assert.NotNull(ec1.Get<TestEntityComponent>());
                        Assert.AreEqual(ea1, ec1.Get<TestEntityComponent>().EntityLink);
                    }
                }

                // ------------------------------------------------
                // Check for a4
                // ------------------------------------------------
                // a4: (baseParts: a2 x 1, a3 x 1)
                //  | eNewRoot
                //    | er1* (base: er)  
                //      | ea1* (base: ea)
                //      | eb1* (base: eb)
                //      | ec1* + link ea1* (base: ec)
                //    | er2* (base: er)  
                //      | ea2* (base: ea)
                //      | eb2* (base: eb)
                //      | ec2* + link ea2* (base: ec)
                //  | er1'* (base: er)     
                //    | ea1'* (base: ea)
                //    | eb1'* (base: eb)  
                //    | ec1'* + link ea1'* (base: ec)
                //  | ex(1*)
                //    | ey(1*) + link eb1*
                //  | ex(2*)
                //    | ey(2*) + link eb2*
                //  | ex(1') (base: ex)   
                //    | ey(1') + link eb1'*
                {
                    Assert.True(a4.DumpTo(Console.Out, "a4 AFTER PrefabMergeAsset"));

                    Assert.AreEqual(5, a4.Hierarchy.RootPartIds.Count);
                    Assert.True(a4.Hierarchy.Parts.Where(it => it.Entity.Name != "eRoot").All(it => it.Entity.Name != "eRoot" && it.Base != null));

                    // Check that we have all expected entities
                    Assert.AreEqual(19, a4.Hierarchy.Parts.Count);

                    var eb1 = a4.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "eb1*")?.Entity;
                    var eb1_2 = a4.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "eb1'*")?.Entity;
                    var eb2 = a4.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == "eb2*")?.Entity;
                    Assert.NotNull(eb1);
                    Assert.NotNull(eb1_2);
                    Assert.NotNull(eb2);

                    // Check that we have ex and ey
                    var exList = a4.Hierarchy.Parts.Where(it => it.Entity.Name == ex.Name).ToList();
                    Assert.AreEqual(3, exList.Count);

                    // Check that both [ex] have both 1 element [ey] and the links to eb1/eb2 are correct
                    {
                        var expecting = new List<Entity>() { eb1, eb1_2, eb2 };

                        for (int i = 0; i < exList.Count; i++)
                        {
                            var ex1 = exList[i].Entity;
                            Assert.AreEqual(1, ex1.Transform.Children.Count);
                            var ey1 = ex1.Transform.Children[0].Entity;
                            Assert.AreEqual(ey.Name, ey1.Name);
                            Assert.NotNull(ey1.Get<TestEntityComponent>());

                            var entityLink = ey1.Get<TestEntityComponent>().EntityLink;
                            Assert.True(expecting.Contains(entityLink));
                            expecting.Remove(entityLink);
                        }
                    }

                    // Check all [er] entities
                    Action<string> checkErX = (erName) =>
                    {
                        var er1 = a4.Hierarchy.Parts.FirstOrDefault(it => it.Entity.Name == erName)?.Entity;
                        Assert.NotNull(er1);
                        Assert.AreEqual(3, er1.Transform.Children.Count);

                        var ec1 = er1.Transform.Children.FirstOrDefault(it => it.Entity.Name.StartsWith("ec"))?.Entity;
                        Assert.NotNull(ec1);
                        var ea1 = er1.Transform.Children.FirstOrDefault(it => it.Entity.Name.StartsWith("ea"))?.Entity;
                        Assert.NotNull(ea1);

                        Assert.NotNull(ec1.Get<TestEntityComponent>());

                        Assert.AreEqual(ea1, ec1.Get<TestEntityComponent>().EntityLink);
                    };

                    checkErX("er1*");
                    checkErX("er2*");
                    checkErX("er1'*");
                }
            }
        }
Example #32
0
 public abstract IEnumerable <string> Select(PackageSession packageSession, IAssetIndexMap assetIndexMap);
Example #33
0
        private static void PreLoadPackageDependencies(PackageSession session, ILogger log, Package package, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null) throw new ArgumentNullException("session");
            if (log == null) throw new ArgumentNullException("log");
            if (package == null) throw new ArgumentNullException("package");
            if (loadParameters == null) throw new ArgumentNullException("loadParameters");

            bool packageDependencyErrors = false;

            // TODO: Remove and recheck Dependencies Ready if some secondary packages are removed?
            if (package.State >= PackageState.DependenciesReady)
                return;

            // 1. Load store package
            foreach (var packageDependency in package.Meta.Dependencies)
            {
                var loadedPackage = session.Packages.Find(packageDependency);
                if (loadedPackage == null)
                {
                    var file = PackageStore.Instance.GetPackageFileName(packageDependency.Name, packageDependency.Version, session.constraintProvider);

                    if (file == null)
                    {
                        // TODO: We need to support automatic download of packages. This is not supported yet when only Xenko
                        // package is supposed to be installed, but It will be required for full store
                        log.Error("Unable to find package {0} not installed", packageDependency);
                        packageDependencyErrors = true;
                        continue;
                    }

                    // Recursive load of the system package
                    loadedPackage = PreLoadPackage(session, log, file, true, loadedPackages, loadParameters);
                }

                if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
                    packageDependencyErrors = true;
            }

            // 2. Load local packages
            foreach (var packageReference in package.LocalDependencies)
            {
                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageReference.Id))
                {
                    continue;
                }

                // Expand the string of the location
                var newLocation = (UFile)AssetRegistry.ExpandString(session, packageReference.Location);

                var subPackageFilePath = package.RootDirectory != null ? UPath.Combine(package.RootDirectory, newLocation) : newLocation;

                // Recursive load
                var loadedPackage = PreLoadPackage(session, log, subPackageFilePath.FullPath, false, loadedPackages, loadParameters);

                if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
                    packageDependencyErrors = true;
            }

            // 3. Update package state
            if (!packageDependencyErrors)
            {
                package.State = PackageState.DependenciesReady;
            }
        }
Example #34
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);
Example #35
0
        private static Package PreLoadPackage(PackageSession session, ILogger log, string filePath, bool isSystemPackage, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null) throw new ArgumentNullException("session");
            if (log == null) throw new ArgumentNullException("log");
            if (filePath == null) throw new ArgumentNullException("filePath");
            if (loadedPackages == null) throw new ArgumentNullException("loadedPackages");
            if (loadParameters == null) throw new ArgumentNullException("loadParameters");

            try
            {
                var packageId = Package.GetPackageIdFromFile(filePath);

                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageId))
                {
                    return session.Packages.Find(packageId);
                }

                // Package is already loaded, use the instance 
                if (loadedPackages.ContainsById(packageId))
                {
                    return loadedPackages.Find(packageId);
                }

                // Load the package without loading any assets
                var package = Package.LoadRaw(log, filePath);
                package.IsSystem = isSystemPackage;

                // Convert UPath to absolute (Package only)
                // Removed for now because it is called again in PackageSession.LoadAssembliesAndAssets (and running it twice result in dirty package)
                // If we remove it from here (and call it only in the other method), templates are not loaded (Because they are loaded via the package store that do not use PreLoadPackage)
                //if (loadParameters.ConvertUPathToAbsolute)
                //{
                //    var analysis = new PackageAnalysis(package, new PackageAnalysisParameters()
                //    {
                //        ConvertUPathTo = UPathType.Absolute,
                //        SetDirtyFlagOnAssetWhenFixingAbsoluteUFile = true,
                //        IsProcessingUPaths = true,
                //    });
                //    analysis.Run(log);
                //}
                // If the package doesn't have a meta name, fix it here (This is supposed to be done in the above disabled analysis - but we still need to do it!)
                if (string.IsNullOrWhiteSpace(package.Meta.Name) && package.FullPath != null)
                {
                    package.Meta.Name = package.FullPath.GetFileName();
                    package.IsDirty = true;
                }

                // Add the package has loaded before loading dependencies
                loadedPackages.Add(package);

                // Package has been loaded, register it in constraints so that we force each subsequent loads to use this one (or fails if version doesn't match)
                session.constraintProvider.AddConstraint(package.Meta.Name, new VersionSpec(package.Meta.Version.ToSemanticVersion()));

                // Load package dependencies
                // This will perform necessary asset upgrades
                // TODO: We should probably split package loading in two recursive top-level passes (right now those two passes are mixed, making it more difficult to make proper checks)
                //   - First, load raw packages with their dependencies recursively, then resolve dependencies and constraints (and print errors/warnings)
                //   - Then, if everything is OK, load the actual references and assets for each packages
                PreLoadPackageDependencies(session, log, package, loadedPackages, loadParameters);

                // Add the package to the session but don't freeze it yet
                session.Packages.Add(package);

                return package;
            }
            catch (Exception ex)
            {
                log.Error("Error while pre-loading package [{0}]", ex, filePath);
            }

            return null;
        }
        public void TestPackageAssetTemplatingAnalysis()
        {
            var package = new Package();

            var assetItems = package.Assets;

            // Before Adding Package
            // a1:      a2: (baseParts: a1, 2 instances)     a3: (base: a2)
            //  | ea     | ea1 (base: ea)                     | ea1' (base: ea1)
            //  | eb     | eb1 (base: eb)                     | eb1' (base: eb1)
            //           | ea2 (base: ea)                     | ea2' (base: ea2)
            //           | eb2 (base: eb)                     | eb2' (base: eb2)


            // After adding the package to the session 
            // We add one entity to the base a1 
            // a1:      a2: (baseParts: a1, 2 instances)     a3: (base: a2)
            //  | ea     | ea1 (base: ea)                     | ea1' (base: ea1)
            //  | eb     | eb1 (base: eb)                     | eb1' (base: eb1)
            //  | ec     | ec1 (base: ec)                     | ec1' (base: ec1)
            //           | ea2 (base: ea)                     | ea2' (base: ea2)
            //           | eb2 (base: eb)                     | eb2' (base: eb2)
            //           | ec2 (base: ec)                     | ec2' (base: ec2)

            var a1 = new EntityGroupAsset();
            var ea = new Entity("ea");
            var eb = new Entity("eb");
            a1.Hierarchy.Entities.Add(ea);
            a1.Hierarchy.Entities.Add(eb);
            a1.Hierarchy.RootEntities.Add(ea.Id);
            a1.Hierarchy.RootEntities.Add(eb.Id);

            assetItems.Add(new AssetItem("a1", a1));

            var a2 = new EntityGroupAsset();
            var aPartInstance1 = (EntityGroupAsset)a1.CreateChildAsset("a1");
            var aPartInstance2 = (EntityGroupAsset)a1.CreateChildAsset("a1");
            a2.AddPart(aPartInstance1);
            a2.AddPart(aPartInstance2);
            assetItems.Add(new AssetItem("a2", a2));

            // Modify a1 to add entity ec
            var ec = new Entity("ec");
            a1.Hierarchy.Entities.Add(ec);
            a1.Hierarchy.RootEntities.Add(ec.Id);

            var a3 = (EntityGroupAsset)a2.CreateChildAsset("a2");

            assetItems.Add(new AssetItem("a3", a3));

            // Create a session with this project
            using (var session = new PackageSession())
            {
                var logger = new LoggerResult();
                session.AddExistingPackage(package, logger);

                Assert.False(logger.HasErrors);

                Assert.AreEqual(6, a2.Hierarchy.RootEntities.Count);
                Assert.True(a2.Hierarchy.Entities.All(it => it.Design.BaseId.HasValue && it.Design.BasePartInstanceId.HasValue));

                Assert.AreEqual(6, a3.Hierarchy.RootEntities.Count);
                Assert.True(a3.Hierarchy.Entities.All(it => !it.Design.BasePartInstanceId.HasValue));
                Assert.True(a3.Hierarchy.Entities.All(it => it.Design.BaseId.HasValue && a2.Hierarchy.Entities.ContainsKey(it.Design.BaseId.Value)));
            }
        }
        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;
        }
Example #38
0
        /// <summary>
        /// Finds an asset from all the packages by its location.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="location">The location of the asset.</param>
        /// <returns>An <see cref="AssetItem" /> or <c>null</c> if not found.</returns>
        public static AssetItem FindAsset(this PackageSession session, UFile location)
        {
            var packages = session.CurrentPackage != null?session.GetPackagesFromCurrent() : session.Packages;

            return(packages.Select(packageItem => packageItem.Assets.Find(location)).FirstOrDefault(asset => asset != null));
        }
Example #39
0
 public abstract IEnumerable<string> Select(PackageSession packageSession, IAssetIndexMap assetIndexMap);
Example #40
0
        private static void PreLoadPackageDependencies(PackageSession session, ILogger log, Package package, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }
            if (log == null)
            {
                throw new ArgumentNullException("log");
            }
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }
            if (loadParameters == null)
            {
                throw new ArgumentNullException("loadParameters");
            }

            bool packageDependencyErrors = false;

            // TODO: Remove and recheck Dependencies Ready if some secondary packages are removed?
            if (package.State >= PackageState.DependenciesReady)
            {
                return;
            }

            // 1. Load store package
            foreach (var packageDependency in package.Meta.Dependencies)
            {
                var loadedPackage = session.Packages.Find(packageDependency);
                if (loadedPackage == null)
                {
                    var file = PackageStore.Instance.GetPackageFileName(packageDependency.Name, packageDependency.Version, session.constraintProvider);

                    if (file == null)
                    {
                        // TODO: We need to support automatic download of packages. This is not supported yet when only Paradox
                        // package is supposed to be installed, but It will be required for full store
                        log.Error("Unable to find package {0} not installed", packageDependency);
                        packageDependencyErrors = true;
                        continue;
                    }

                    // Recursive load of the system package
                    loadedPackage = PreLoadPackage(session, log, file, true, loadedPackages, loadParameters);
                }

                if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
                {
                    packageDependencyErrors = true;
                }
            }

            // 2. Load local packages
            foreach (var packageReference in package.LocalDependencies)
            {
                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageReference.Id))
                {
                    continue;
                }

                // Expand the string of the location
                var newLocation = (UFile)AssetRegistry.ExpandString(session, packageReference.Location);

                var subPackageFilePath = package.RootDirectory != null?UPath.Combine(package.RootDirectory, newLocation) : newLocation;

                // Recursive load
                var loadedPackage = PreLoadPackage(session, log, subPackageFilePath.FullPath, false, loadedPackages, loadParameters);

                if (loadedPackage == null || loadedPackage.State < PackageState.DependenciesReady)
                {
                    packageDependencyErrors = true;
                }
            }

            // 3. Update package state
            if (!packageDependencyErrors)
            {
                package.State = PackageState.DependenciesReady;
            }
        }
Example #41
0
        /// <summary>
        /// Loads a package from specified file path.
        /// </summary>
        /// <param name="filePath">The file path to a package file.</param>
        /// <param name="sessionResult">The session result.</param>
        /// <param name="loadParameters">The load parameters.</param>
        /// <returns>A package.</returns>
        /// <exception cref="System.ArgumentNullException">filePath</exception>
        /// <exception cref="System.ArgumentException">File [{0}] must exist.ToFormat(filePath);filePath</exception>
        public static void Load(string filePath, PackageSessionResult sessionResult, PackageLoadParameters loadParameters = null)
        {
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }
            if (sessionResult == null)
            {
                throw new ArgumentNullException("sessionResult");
            }

            // Make sure with have valid parameters
            loadParameters = loadParameters ?? PackageLoadParameters.Default();

            // Make sure to use a full path.
            filePath = FileUtility.GetAbsolutePath(filePath);

            if (!File.Exists(filePath))
            {
                throw new ArgumentException("File [{0}] must exist".ToFormat(filePath), "filePath");
            }

            try
            {
                // Enable reference analysis caching during loading
                AssetReferenceAnalysis.EnableCaching = true;

                using (var profile = Profiler.Begin(PackageSessionProfilingKeys.Loading))
                {
                    sessionResult.Clear();
                    sessionResult.Progress("Loading..", 0, 1);

                    var session = new PackageSession();

                    var packagePaths = new List <string>();

                    // If we have a solution, load all packages
                    if (PackageSessionHelper.IsSolutionFile(filePath))
                    {
                        PackageSessionHelper.LoadSolution(session, filePath, packagePaths, sessionResult);
                    }
                    else if (PackageSessionHelper.IsPackageFile(filePath))
                    {
                        packagePaths.Add(filePath);
                    }
                    else
                    {
                        sessionResult.Error("Unsupported file extension (only .sln or {0} are supported)", Package.PackageFileExtension);
                        return;
                    }

                    var cancelToken = loadParameters.CancelToken;

                    // Load all packages
                    var packagesLoaded = new PackageCollection();
                    foreach (var packageFilePath in packagePaths)
                    {
                        PreLoadPackage(session, sessionResult, packageFilePath, false, packagesLoaded, loadParameters);

                        // Output the session only if there is no cancellation
                        if (cancelToken.HasValue && cancelToken.Value.IsCancellationRequested)
                        {
                            return;
                        }
                    }

                    // Load all missing references/dependencies
                    session.LoadMissingReferences(sessionResult, loadParameters);

                    // Fix relative references
                    var analysis        = new PackageSessionAnalysis(session, GetPackageAnalysisParametersForLoad());
                    var analysisResults = analysis.Run();
                    analysisResults.CopyTo(sessionResult);

                    // Run custom package session analysis
                    foreach (var type in AssetRegistry.GetPackageSessionAnalysisTypes())
                    {
                        var pkgAnalysis = (PackageSessionAnalysisBase)Activator.CreateInstance(type);
                        pkgAnalysis.Session = session;
                        var results = pkgAnalysis.Run();
                        results.CopyTo(sessionResult);
                    }

                    // Output the session only if there is no cancellation
                    if (!cancelToken.HasValue || !cancelToken.Value.IsCancellationRequested)
                    {
                        sessionResult.Session = session;

                        // Defer the initialization of the dependency manager
                        //session.DependencyManager.InitializeDeferred();
                    }

                    // The session is not dirty when loading it
                    session.IsDirty = false;
                }
            }
            finally
            {
                // Disable reference analysis caching after loading
                AssetReferenceAnalysis.EnableCaching = false;
            }
        }
Example #42
0
        private static Package PreLoadPackage(PackageSession session, ILogger log, string filePath, bool isSystemPackage, PackageCollection loadedPackages, PackageLoadParameters loadParameters)
        {
            if (session == null)
            {
                throw new ArgumentNullException("session");
            }
            if (log == null)
            {
                throw new ArgumentNullException("log");
            }
            if (filePath == null)
            {
                throw new ArgumentNullException("filePath");
            }
            if (loadedPackages == null)
            {
                throw new ArgumentNullException("loadedPackages");
            }
            if (loadParameters == null)
            {
                throw new ArgumentNullException("loadParameters");
            }

            try
            {
                var packageId = Package.GetPackageIdFromFile(filePath);

                // Check that the package was not already loaded, otherwise return the same instance
                if (session.Packages.ContainsById(packageId))
                {
                    return(session.Packages.Find(packageId));
                }

                // Package is already loaded, use the instance
                if (loadedPackages.ContainsById(packageId))
                {
                    return(loadedPackages.Find(packageId));
                }

                // Load the package without loading any assets
                var package = Package.LoadRaw(log, filePath);
                package.IsSystem = isSystemPackage;

                // Convert UPath to absolute (Package only)
                // Removed for now because it is called again in PackageSession.LoadAssembliesAndAssets (and running it twice result in dirty package)
                // If we remove it from here (and call it only in the other method), templates are not loaded (Because they are loaded via the package store that do not use PreLoadPackage)
                //if (loadParameters.ConvertUPathToAbsolute)
                //{
                //    var analysis = new PackageAnalysis(package, new PackageAnalysisParameters()
                //    {
                //        ConvertUPathTo = UPathType.Absolute,
                //        SetDirtyFlagOnAssetWhenFixingAbsoluteUFile = true,
                //        IsProcessingUPaths = true,
                //    });
                //    analysis.Run(log);
                //}
                // If the package doesn't have a meta name, fix it here (This is supposed to be done in the above disabled analysis - but we still need to do it!)
                if (string.IsNullOrWhiteSpace(package.Meta.Name) && package.FullPath != null)
                {
                    package.Meta.Name = package.FullPath.GetFileName();
                    package.IsDirty   = true;
                }

                // Add the package has loaded before loading dependencies
                loadedPackages.Add(package);

                // Package has been loaded, register it in constraints so that we force each subsequent loads to use this one (or fails if version doesn't match)
                session.constraintProvider.AddConstraint(package.Meta.Name, new VersionSpec(package.Meta.Version.ToSemanticVersion()));

                // Load package dependencies
                // This will perform necessary asset upgrades
                // TODO: We should probably split package loading in two recursive top-level passes (right now those two passes are mixed, making it more difficult to make proper checks)
                //   - First, load raw packages with their dependencies recursively, then resolve dependencies and constraints (and print errors/warnings)
                //   - Then, if everything is OK, load the actual references and assets for each packages
                PreLoadPackageDependencies(session, log, package, loadedPackages, loadParameters);

                // Add the package to the session but don't freeze it yet
                session.Packages.Add(package);

                return(package);
            }
            catch (Exception ex)
            {
                log.Error("Error while pre-loading package [{0}]", ex, filePath);
            }

            return(null);
        }
        /// <summary>
        /// Finds an asset from all the packages by its id.
        /// </summary>
        /// <param name="session">The session.</param>
        /// <param name="assetId">The assetId of the asset.</param>
        /// <returns>An <see cref="AssetItem" /> or <c>null</c> if not found.</returns>
        public static AssetItem FindAsset(this PackageSession session, AssetId assetId)
        {
            var packages = session.Packages;

            return(packages.Select(packageItem => packageItem.Assets.Find(assetId)).FirstOrDefault(asset => asset != null));
        }
Example #44
0
        private static bool TryLoadAssets(PackageSession session, ILogger log, Package package, PackageLoadParameters loadParameters)
        {
            // Already loaded
            if (package.State >= PackageState.AssetsReady)
            {
                return(true);
            }

            // Dependencies could not properly be loaded
            if (package.State < PackageState.DependenciesReady)
            {
                return(false);
            }

            // A package upgrade has previously been tried and denied, so let's keep the package in this state
            if (package.State == PackageState.UpgradeFailed)
            {
                return(false);
            }

            try
            {
                // First, check that dependencies have their assets loaded
                bool dependencyError = false;
                foreach (var dependency in package.FindDependencies(false, false))
                {
                    if (!TryLoadAssets(session, log, dependency, loadParameters))
                    {
                        dependencyError = true;
                    }
                }

                if (dependencyError)
                {
                    return(false);
                }

                var pendingPackageUpgrades = new List <PendingPackageUpgrade>();

                // Note: Default state is upgrade failed (for early exit on error/exceptions)
                // We will update to success as soon as loading is finished.
                package.State = PackageState.UpgradeFailed;

                // Process store dependencies for upgraders
                foreach (var packageDependency in package.Meta.Dependencies)
                {
                    var dependencyPackage = session.Packages.Find(packageDependency);
                    if (dependencyPackage == null)
                    {
                        continue;
                    }

                    // Check for upgraders
                    var packageUpgrader = session.CheckPackageUpgrade(log, package, packageDependency, dependencyPackage);
                    if (packageUpgrader != null)
                    {
                        pendingPackageUpgrades.Add(new PendingPackageUpgrade(packageUpgrader, packageDependency, dependencyPackage));
                    }
                }

                // Load list of assets
                var assetFiles = Package.ListAssetFiles(log, package, loadParameters.CancelToken);

                if (pendingPackageUpgrades.Count > 0)
                {
                    var upgradeAllowed = true;
                    // Need upgrades, let's ask user confirmation
                    if (loadParameters.PackageUpgradeRequested != null)
                    {
                        upgradeAllowed = loadParameters.PackageUpgradeRequested(package, pendingPackageUpgrades);
                    }

                    if (!upgradeAllowed)
                    {
                        log.Error("Necessary package migration for [{0}] has not been allowed", package.Meta.Name);
                        return(false);
                    }

                    // Perform upgrades
                    foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                    {
                        var packageUpgrader   = pendingPackageUpgrade.PackageUpgrader;
                        var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                        if (!packageUpgrader.Upgrade(session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage, assetFiles))
                        {
                            log.Error("Error while upgrading package [{0}] for [{1}] from version [{2}] to [{3}]", package.Meta.Name, dependencyPackage.Meta.Name, pendingPackageUpgrade.Dependency.Version, dependencyPackage.Meta.Version);
                            return(false);
                        }

                        // Update dependency to reflect new requirement
                        pendingPackageUpgrade.Dependency.Version = pendingPackageUpgrade.PackageUpgrader.Attribute.PackageUpdatedVersionRange;
                    }

                    // Mark package as dirty
                    package.IsDirty = true;
                }

                // Process the package for assets
                var newLoadParameters = loadParameters.Clone();
                newLoadParameters.AssetFiles        = assetFiles;
                newLoadParameters.AssemblyContainer = session.assemblyContainer;

                // Default package version override
                newLoadParameters.ExtraCompileProperties = new Dictionary <string, string>();
                var defaultPackageOverride = NugetStore.GetPackageVersionVariable(PackageStore.Instance.DefaultPackageName) + "Override";
                var defaultPackageVersion  = PackageStore.Instance.DefaultPackageVersion.Version;
                newLoadParameters.ExtraCompileProperties.Add(defaultPackageOverride, new Version(defaultPackageVersion.Major, defaultPackageVersion.Minor).ToString());
                if (loadParameters.ExtraCompileProperties != null)
                {
                    foreach (var property in loadParameters.ExtraCompileProperties)
                    {
                        newLoadParameters.ExtraCompileProperties[property.Key] = property.Value;
                    }
                }

                // Load assemblies and assets
                package.LoadAssembliesAndAssets(log, newLoadParameters);

                // Validate assets from package
                package.ValidateAssets(newLoadParameters.GenerateNewAssetIds);

                // Mark package as ready
                package.State = PackageState.AssetsReady;

                // Freeze the package after loading the assets
                session.FreezePackage(package);

                return(true);
            }
            catch (Exception ex)
            {
                log.Error("Error while loading package [{0}]", ex, package);
                return(false);
            }
        }
 public override void Clear()
 {
     base.Clear();
     Session = null;
 }
Example #46
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"))
            {
                UpgradeCode(dependentPackage, log, new RenameToXenkoCodeUpgrader());
            }
            else if (dependency.Version.MinVersion < new PackageVersion("1.6.0-beta"))
            {
                UpgradeCode(dependentPackage, log, new NewComponentsCodeUpgrader());
            }

            return true;
        }
Example #47
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;
 }
        public void TestMultiplePrefabsMixedInheritance()
        {
            // The purpose of this test is to check that modifying a prefab base is correctly propagated through all 
            // derived prefabs. We use the following scenario:
            // a1: base asset)
            // a2: inherit from a1 by composition with 2 instances (baseParts: a1, 2 instances)
            // a3: direct inheritance from a2 (base: a2)
            // This scenario doesn't happen in practice, as we have restricted only to inheritance by composition for prefabs
            // but we verify that the code is actually working for this scenario

            var package = new Package();

            var assetItems = package.Assets;

            // Before Adding Package
            // a1:      a2: (baseParts: a1, 2 instances)     a3: (base: a2)
            //  | ea     | ea1 (base: ea)                     | ea1' (base: ea1)
            //  | eb     | eb1 (base: eb)                     | eb1' (base: eb1)
            //           | ea2 (base: ea)                     | ea2' (base: ea2)
            //           | eb2 (base: eb)                     | eb2' (base: eb2)


            // After adding the package to the session 
            // We add one entity to the base a1 
            // a1:      a2: (baseParts: a1, 2 instances)     a3: (base: a2)
            //  | ea     | ea1 (base: ea)                     | ea1' (base: ea1)
            //  | eb     | eb1 (base: eb)                     | eb1' (base: eb1)
            //  | ec     | ec1 (base: ec)                     | ec1' (base: ec1)
            //           | ea2 (base: ea)                     | ea2' (base: ea2)
            //           | eb2 (base: eb)                     | eb2' (base: eb2)
            //           | ec2 (base: ec)                     | ec2' (base: ec2)

            var a1 = new PrefabAsset();
            var ea = new Entity("ea");
            var eb = new Entity("eb");
            a1.Hierarchy.Parts.Add(new EntityDesign(ea));
            a1.Hierarchy.Parts.Add(new EntityDesign(eb));
            a1.Hierarchy.RootPartIds.Add(ea.Id);
            a1.Hierarchy.RootPartIds.Add(eb.Id);

            assetItems.Add(new AssetItem("a1", a1));

            var a2 = new PrefabAsset();
            var aPartInstance1 = a1.CreatePrefabInstance(a2, "a1");
            var aPartInstance2 = a1.CreatePrefabInstance(a2, "a1");
            a2.Hierarchy.Parts.AddRange(aPartInstance1.Parts);
            a2.Hierarchy.Parts.AddRange(aPartInstance2.Parts);
            a2.Hierarchy.RootPartIds.AddRange(aPartInstance1.RootPartIds);
            a2.Hierarchy.RootPartIds.AddRange(aPartInstance2.RootPartIds);
            assetItems.Add(new AssetItem("a2", a2));

            // Modify a1 to add entity ec
            var ec = new Entity("ec");
            a1.Hierarchy.Parts.Add(new EntityDesign(ec));
            a1.Hierarchy.RootPartIds.Add(ec.Id);

            var a3 = (PrefabAsset)a2.CreateDerivedAsset("a2");

            assetItems.Add(new AssetItem("a3", a3));

            // Create a session with this project
            using (var session = new PackageSession())
            {
                var logger = new LoggerResult();
                session.AddExistingPackage(package, logger);

                Assert.False(logger.HasErrors);

                Assert.AreEqual(6, a2.Hierarchy.RootPartIds.Count);
                Assert.True(a2.Hierarchy.Parts.All(it => it.Base != null));

                Assert.AreEqual(6, a3.Hierarchy.RootPartIds.Count);
                Assert.True(a3.Hierarchy.Parts.All(it => it.Base != null && a2.Hierarchy.Parts.ContainsKey(it.Base.BasePartId)));
            }
        }
Example #49
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;
 }
Example #50
0
 public abstract IEnumerable <string> Select(PackageSession packageSession, IContentIndexMap contentIndexMap);
 public abstract IEnumerable<string> Select(PackageSession packageSession, IContentIndexMap contentIndexMap);
Example #52
0
        private static void GenerateUnitTestProject(string outputDirectory, string templateFile, string name, string projectNamespace)
        {
            var projectTemplate = ProjectTemplate.Load(templateFile);

            // Force reference to Xenko.Assets (to have acess to SolutionPlatform)
            projectTemplate.Assemblies.Add(typeof(GraphicsProfile).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(XenkoConfig).Assembly.FullName);

            var options = new Dictionary<string, object>();

            // When generating over an existing set of files, retrieve the existing IDs
            // for better incrementality
            Guid projectGuid, assetId;
            GetExistingGuid(outputDirectory, name + ".Windows.csproj", out projectGuid);
            GetExistingAssetId(outputDirectory, name + ".xkpkg", out assetId);

            var session = new PackageSession();
            var result = new LoggerResult();

            var templateGeneratorParameters = new SessionTemplateGeneratorParameters();
            templateGeneratorParameters.OutputDirectory = outputDirectory;
            templateGeneratorParameters.Session = session;
            templateGeneratorParameters.Name = name;
            templateGeneratorParameters.Logger = result;
            templateGeneratorParameters.Description = new TemplateDescription();
            templateGeneratorParameters.Id = assetId;

            if (!PackageUnitTestGenerator.Default.PrepareForRun(templateGeneratorParameters).Result)
            {
                Console.WriteLine(@"Error generating package: PackageUnitTestGenerator.PrepareForRun returned false");
                return;
            }
            if (!PackageUnitTestGenerator.Default.Run(templateGeneratorParameters))
            {
                Console.WriteLine(@"Error generating package: PackageUnitTestGenerator.Run returned false");
                return;
            }
            if (result.HasErrors)
            {
                Console.WriteLine($"Error generating package: {result.ToText()}");
                return;
            }

            var package = session.LocalPackages.Single();

            var previousCurrent = session.CurrentPackage;
            session.CurrentPackage = package;

            // Compute Xenko Sdk relative path
            // We are supposed to be in standard output binary folder, so Xenko root should be at ..\..
            var xenkoPath = UPath.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), new UDirectory(@"..\.."));
            var xenkoRelativePath = new UDirectory(xenkoPath)
                .MakeRelative(outputDirectory)
                .ToString()
                .Replace('/', '\\');
            xenkoRelativePath = xenkoRelativePath.TrimEnd('\\');

            options["Namespace"] = projectNamespace ?? name;
            options["Package"] = package;
            options["Platforms"] = new List<SolutionPlatform>(AssetRegistry.SupportedPlatforms);
            options["XenkoSdkRelativeDir"] = xenkoRelativePath;

            // Generate project template
            result = projectTemplate.Generate(outputDirectory, name, projectGuid, options);
            if (result.HasErrors)
            {
                Console.WriteLine("Error generating solution: {0}", result.ToText());
                return;
            }

            var sharedProfile = package.Profiles.FindSharedProfile();

            // Setup the assets folder
            Directory.CreateDirectory(UPath.Combine(outputDirectory, (UDirectory)"Assets/Shared"));

            // Add Windows test as Shared library
            var projectWindowsRef = new ProjectReference
            {
                Id = projectGuid,
                Location = UPath.Combine(outputDirectory, (UFile)(name + ".Windows.csproj")),
                Type = SiliconStudio.Assets.ProjectType.Library
            };
            sharedProfile.ProjectReferences.Add(projectWindowsRef);

            // Generate executable projects for each platform
            foreach (var platform in AssetRegistry.SupportedPlatforms)
            {
                var platformProfile = new PackageProfile(platform.Name) { Platform = platform.Type };
                platformProfile.AssetFolders.Add(new AssetFolder("Assets/"+ platform.Name));
                
                // Log progress
                var projectName = name + "." + platform.Type;

                // Create project reference
                var projectPlatformRef = new ProjectReference
                {
                    Id = projectGuid,
                    Location = UPath.Combine(outputDirectory, (UFile)(projectName + ".csproj")),
                    Type = SiliconStudio.Assets.ProjectType.Executable
                };

                platformProfile.ProjectReferences.Add(projectPlatformRef);

                // Add build configuration per platform
                platform.Properties.CopyTo(platformProfile.Properties, true);

                package.Profiles.Add(platformProfile);
            }

            session.CurrentPackage = previousCurrent;

            result = session.Save();
            if (result.HasErrors)
            {
                Console.WriteLine("Error saving package: {0}", result.ToText());
                return;
            }
        }