Beispiel #1
0
        public void TestIsDirectoryOnly()
        {
            Assert.False(new UFile("/a/b/c.txt").IsDirectoryOnly);

            var dirPath = new UDirectory("/a/b/c");
            Assert.True(dirPath.IsDirectoryOnly);
            Assert.AreEqual("/a/b/c", dirPath.GetDirectory());

            var filePath = new UFile("/test.txt");
            Assert.AreEqual("/", filePath.GetDirectory());
            Assert.AreEqual("test.txt", filePath.GetFileNameWithExtension());
        }
Beispiel #2
0
        public static SolutionProject GenerateTemplate(TemplateGeneratorParameters parameters, ICollection <SelectedSolutionPlatform> platforms, UFile templateRelativePath, string projectName, PlatformType platformType, GraphicsPlatform?graphicsPlatform, ProjectType projectType, DisplayOrientation orientation, Guid?projectGuid = null)
        {
            AddOption(parameters, "Platforms", platforms.Select(x => x.Platform).ToList());
            AddOption(parameters, "CurrentPlatform", platformType);
            AddOption(parameters, "Orientation", orientation);

            List <string> generatedFiles;
            var           project = GenerateTemplate(parameters, templateRelativePath, projectName, platformType, graphicsPlatform, projectType, out generatedFiles, projectGuid);

            // Special case for sdfx files
            foreach (var file in generatedFiles)
            {
                if (file.EndsWith(".sdfx"))
                {
                    ConvertXkfxToCSharp(file);
                }
            }

            return(project);
        }
Beispiel #3
0
        public static ProjectTemplate PrepareTemplate(TemplateGeneratorParameters parameters, Package package, UFile templateRelativePath, PlatformType platformType, GraphicsPlatform?graphicsPlatform, ProjectType projectType)
        {
            if (platformType != PlatformType.Shared && !graphicsPlatform.HasValue)
            {
                throw new ArgumentException(@"Expecting a value for GraphicsPlatform when platformType is specified", nameof(graphicsPlatform));
            }

            var rootTemplateDir = parameters.Description.TemplateDirectory;

            var templateFilePath = UPath.Combine(rootTemplateDir, templateRelativePath);
            var projectTemplate  = ProjectTemplate.Load(templateFilePath);

            // TODO assemblies are not configurable from the outside
            projectTemplate.Assemblies.Add(typeof(ProjectType).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(StrideConfig).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(GraphicsPlatform).Assembly.FullName);
            projectTemplate.Assemblies.Add(typeof(DisplayOrientation).Assembly.FullName);

            AddOption(parameters, "Package", package);
            AddOption(parameters, "PackageName", package.Meta.Name);

            // PackageNameCode, same as PackageName without '.' and ' '.
            AddOption(parameters, "PackageNameCode", package.Meta.Name.Replace(" ", string.Empty).Replace(".", string.Empty));

            AddOption(parameters, "PackageDisplayName", package.Meta.Title ?? package.Meta.Name);
            // Escape illegal characters for the short name
            AddOption(parameters, "PackageNameShort", Utilities.BuildValidClassName(package.Meta.Name.Replace(" ", string.Empty)));

            AddOption(parameters, "CurrentPlatform", platformType);
            if (platformType != PlatformType.Shared)
            {
                AddOption(parameters, "CurrentGraphicsPlatform", graphicsPlatform);
            }

            AddOption(parameters, "ProjectType", projectType);
            AddOption(parameters, "Namespace", parameters.Namespace ?? Utilities.BuildValidNamespaceName(package.Meta.Name));

            if (platformType == PlatformType.Windows)
            {
                var isNETCore = RuntimeInformation.FrameworkDescription.StartsWith(".NET Core");
                AddOption(parameters, "TargetFramework", isNETCore ? "netcoreapp3.1" : "net461");
            }

            return(projectTemplate);
        }
Beispiel #4
0
 public abstract IEnumerable <AssetItem> Import(UFile rawAssetPath, AssetImporterParameters importParameters);
Beispiel #5
0
 /// <summary>
 ///   Initializes a new instance of the <see cref="ProjectReference"/> class.
 /// </summary>
 /// <param name="id">The project's unique identifier.</param>
 /// <param name="location">The project file location.</param>
 /// <param name="type">The project type.</param>
 public ProjectReference(Guid id, UFile location, ProjectType type)
 {
     Id       = id;
     Location = location;
     Type     = type;
 }
Beispiel #6
0
        public void TestMakeRelative()
        {
            UPath assetPath2 = null;
            UPath newAssetPath2 = null;
            var dir1 = new UDirectory("/a/b/c");

            var assetDir2 = new UDirectory("/a/b/c");
            newAssetPath2 = dir1.MakeRelative(assetDir2);
            Assert.AreEqual(".", newAssetPath2.FullPath);

            var assetDir3 = new UDirectory("/a/b");
            newAssetPath2 = dir1.MakeRelative(assetDir3);
            Assert.AreEqual("c", newAssetPath2.FullPath);

            var assetDir4 = new UDirectory("/a/b/c/d");
            newAssetPath2 = dir1.MakeRelative(assetDir4);
            Assert.AreEqual("..", newAssetPath2.FullPath);

            // Test direct relative
            assetPath2 = new UFile("/a/b/c/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("test.txt", newAssetPath2.FullPath);

            // Test direct relative + subdir
            assetPath2 = new UFile("/a/b/c/test/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("test/test.txt", newAssetPath2.FullPath);

            // Test relative 1
            assetPath2 = new UFile("/a/b/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../test.txt", newAssetPath2.FullPath);

            // Test relative 2
            assetPath2 = new UFile("/a/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../test.txt", newAssetPath2.FullPath);

            // Test relative 3
            assetPath2 = new UFile("/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../../test.txt", newAssetPath2.FullPath);

            // Test already relative
            assetPath2 = new UFile("../test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../test.txt", newAssetPath2.FullPath);

            // Test only root path in common
            assetPath2 = new UFile("/e/f/g/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../../e/f/g/test.txt", newAssetPath2.FullPath);

            // Test only root path in common with single file
            assetPath2 = new UFile("/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../../test.txt", newAssetPath2.FullPath);
        }
        public static void UpdateDependencies(SolutionProject project, bool directDependencies, bool flattenedDependencies)
        {
            if (flattenedDependencies)
            {
                project.FlattenedDependencies.Clear();
            }
            if (directDependencies)
            {
                project.DirectDependencies.Clear();
            }
            var projectAssetsJsonPath = Path.Combine(project.FullPath.GetFullDirectory(), @"obj", LockFileFormat.AssetsFileName);

            if (File.Exists(projectAssetsJsonPath))
            {
                var format        = new LockFileFormat();
                var projectAssets = format.Read(projectAssetsJsonPath);

                // Update dependencies
                if (flattenedDependencies)
                {
                    var libPaths = new Dictionary <ValueTuple <string, NuGet.Versioning.NuGetVersion>, LockFileLibrary>();
                    foreach (var lib in projectAssets.Libraries)
                    {
                        libPaths.Add(ValueTuple.Create(lib.Name, lib.Version), lib);
                    }

                    foreach (var targetLibrary in projectAssets.Targets.Last().Libraries)
                    {
                        if (!libPaths.TryGetValue(ValueTuple.Create(targetLibrary.Name, targetLibrary.Version), out var library))
                        {
                            continue;
                        }

                        var projectDependency = new Dependency(library.Name, library.Version.ToPackageVersion(), library.Type == "project" ? DependencyType.Project : DependencyType.Package)
                        {
                            MSBuildProject = library.Type == "project" ? library.MSBuildProject : null
                        };

                        if (library.Type == "package")
                        {
                            // Find library path by testing with each PackageFolders
                            var libraryPath = projectAssets.PackageFolders
                                              .Select(packageFolder => Path.Combine(packageFolder.Path, library.Path.Replace('/', Path.DirectorySeparatorChar)))
                                              .FirstOrDefault(x => Directory.Exists(x));

                            if (libraryPath != null)
                            {
                                // Build list of assemblies
                                foreach (var a in targetLibrary.RuntimeAssemblies)
                                {
                                    if (!a.Path.EndsWith("_._"))
                                    {
                                        var assemblyFile = Path.Combine(libraryPath, a.Path.Replace('/', Path.DirectorySeparatorChar));
                                        projectDependency.Assemblies.Add(assemblyFile);
                                    }
                                }
                                foreach (var a in targetLibrary.RuntimeTargets)
                                {
                                    if (!a.Path.EndsWith("_._"))
                                    {
                                        var assemblyFile = Path.Combine(libraryPath, a.Path.Replace('/', Path.DirectorySeparatorChar));
                                        projectDependency.Assemblies.Add(assemblyFile);
                                    }
                                }
                            }
                        }

                        project.FlattenedDependencies.Add(projectDependency);
                        // Try to resolve package if already loaded
                        projectDependency.Package = project.Session.Packages.Find(projectDependency);
                    }
                }

                if (directDependencies)
                {
                    foreach (var projectReference in projectAssets.PackageSpec.RestoreMetadata.TargetFrameworks.First().ProjectReferences)
                    {
                        var projectName = new UFile(projectReference.ProjectUniqueName).GetFileNameWithoutExtension();
                        project.DirectDependencies.Add(new DependencyRange(projectName, null, DependencyType.Project)
                        {
                            MSBuildProject = projectReference.ProjectPath
                        });
                    }

                    foreach (var dependency in projectAssets.PackageSpec.TargetFrameworks.First().Dependencies)
                    {
                        if (dependency.AutoReferenced)
                        {
                            continue;
                        }
                        project.DirectDependencies.Add(new DependencyRange(dependency.Name, dependency.LibraryRange.VersionRange.ToPackageVersionRange(), DependencyType.Package));
                    }
                }
            }
        }
Beispiel #8
0
        private async Task GeneratePrecompiledFont()
        {
            var font          = (SpriteFontAsset)AssetItem.Asset;
            var dialogService = ServiceProvider.Get <IDialogService>();

            // Dynamic font cannot be precompiled
            if (font.FontType is RuntimeRasterizedSpriteFontType)
            {
                // Note: Markdown (**, _) are used to format the text.
                await dialogService.MessageBox(Tr._p("Message", "**Only static fonts can be precompiled.**\r\n\r\nClear the _Is Dynamic_ property on this font and try again."), MessageBoxButton.OK, MessageBoxImage.Error);

                return;
            }
            // Compute unique name
            var precompiledName = NamingHelper.ComputeNewName($"{AssetItem.Location.GetFileNameWithoutExtension()} (Precompiled)", Directory.Assets, x => x.Name);

            // Ask location for generated texture
            var folderDialog = dialogService.CreateFolderOpenModalDialog();

            folderDialog.InitialDirectory = (Session.CurrentProject?.Package?.RootDirectory ?? Session.SolutionPath.GetFullDirectory()).ToWindowsPath() + "\\Resources";
            var dialogResult = await folderDialog.ShowModal();

            if (dialogResult != DialogResult.Ok)
            {
                return;
            }

            bool srgb;
            var  gameSettings = Session.CurrentProject?.Package.GetGameSettingsAsset();

            if (gameSettings == null)
            {
                var buttons = DialogHelper.CreateButtons(new[] { ColorSpace.Linear.ToString(), ColorSpace.Gamma.ToString(), Tr._p("Button", "Cancel") }, 1, 3);
                var result  = await dialogService.MessageBox(Tr._p("Message", "Which color space do you want to use?"), buttons, MessageBoxImage.Question);

                // Close without clicking a button or Cancel
                if (result == 0 || result == 3)
                {
                    return;
                }
                srgb = result == 2;
            }
            else
            {
                srgb = gameSettings.GetOrCreate <RenderingSettings>().ColorSpace == ColorSpace.Linear;
            }

            var precompiledFontAsset = (font.FontType is SignedDistanceFieldSpriteFontType) ?
                                       font.GeneratePrecompiledSDFSpriteFont(AssetItem, UFile.Combine(folderDialog.Directory, precompiledName)) :
                                       font.GeneratePrecompiledSpriteFont(AssetItem, UFile.Combine(folderDialog.Directory, precompiledName), srgb);

            // NOTE: following code could be factorized with AssetFactoryViewModel
            var            defaultLocation = UFile.Combine(Directory.Path, precompiledName);
            var            assetItem       = new AssetItem(defaultLocation, precompiledFontAsset);
            AssetViewModel assetViewModel;

            using (var transaction = UndoRedoService.CreateTransaction())
            {
                // FIXME: do we need to delete the generated file upon undo?
                assetViewModel = Directory.Package.CreateAsset(Directory, assetItem, true, null);
                UndoRedoService.SetName(transaction, $"Create Asset '{precompiledName}'");
            }

            Session.CheckConsistency();
            if (assetViewModel != null)
            {
                Session.ActiveAssetView.SelectAssetCommand.Execute(assetViewModel);
            }
        }
Beispiel #9
0
 protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, RenderFrameAsset asset, AssetCompilerResult result)
 {
     result.BuildSteps = new ListBuildStep {
         new RenderFrameCompileCommand(urlInStorage, asset)
     };
 }
        protected void WriteGitIgnore(SessionTemplateGeneratorParameters parameters)
        {
            var fileName = UFile.Combine(parameters.OutputDirectory, ".gitignore");

            File.WriteAllText(fileName.ToWindowsPath(), GitIgnore);
        }
Beispiel #11
0
 protected SingleFileImportCommand(UFile location, UFile sourcePath)
 {
     Location   = location;
     SourcePath = sourcePath;
 }
 public AssetSerializableLogMessage(AssetId assetId, UFile assetUrl, LogMessageType type, string text, ExceptionInfo exceptionInfo = null)
     : base("", type, text, exceptionInfo)
 {
     AssetId  = assetId;
     AssetUrl = assetUrl;
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="SettingsFileLoadedEventArgs"/> class.
 /// </summary>
 /// <param name="path"></param>
 public SettingsFileLoadedEventArgs(UFile path)
 {
     FilePath = path;
 }
 private bool RemoveFilePrivate(UFile filePath)
 {
     return(mruList.RemoveWhere(x => string.Equals(x.FilePath, filePath, StringComparison.OrdinalIgnoreCase)) > 0);
 }
Beispiel #15
0
        public void TestWithNormalization()
        {
            var assetPath = new UFile("/a/b/.././././//c.txt");
            Assert.AreEqual("/a", assetPath.GetDirectory());
            Assert.AreEqual("c", assetPath.GetFileName());
            Assert.AreEqual(".txt", assetPath.GetFileExtension());
            Assert.AreEqual("/a/c", assetPath.GetDirectoryAndFileName());
            Assert.AreEqual("/a/c.txt", assetPath.FullPath);

            assetPath = new UFile("../.././././//c.txt");
            Assert.AreEqual("../..", assetPath.GetDirectory());
            Assert.AreEqual("c", assetPath.GetFileName());
            Assert.AreEqual(".txt", assetPath.GetFileExtension());
            Assert.AreEqual("../../c", assetPath.GetDirectoryAndFileName());
            Assert.AreEqual("../../c.txt", assetPath.FullPath);

            assetPath = new UFile("a/../../../c.txt");
            Assert.AreEqual("../../c.txt", assetPath.FullPath);
        }
Beispiel #16
0
        protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, ModelAsset asset, AssetCompilerResult result)
        {
            if (!EnsureSourcesExist(result, asset, assetAbsolutePath))
            {
                return;
            }

            // Get absolute path of asset source on disk
            var assetDirectory = assetAbsolutePath.GetParent();
            var assetSource    = UPath.Combine(assetDirectory, asset.Source);

            var gameSettingsAsset         = context.GetGameSettingsAsset();
            var renderingSettings         = gameSettingsAsset.Get <RenderingSettings>();
            var allow32BitIndex           = renderingSettings.DefaultGraphicsProfile >= GraphicsProfile.Level_9_2;
            var allowUnsignedBlendIndices = context.GetGraphicsPlatform(AssetItem.Package) != GraphicsPlatform.OpenGLES;
            var extension = asset.Source.GetFileExtension();

            // Find skeleton asset, if any
            AssetItem skeleton = null;

            if (asset.Skeleton != null)
            {
                skeleton = AssetItem.Package.FindAssetFromAttachedReference(asset.Skeleton);
            }

            var importModelCommand = ImportModelCommand.Create(extension);

            if (importModelCommand == null)
            {
                result.Error("No importer found for model extension '{0}. The model '{1}' can't be imported.", extension, assetSource);
                return;
            }

            importModelCommand.Mode                      = ImportModelCommand.ExportMode.Model;
            importModelCommand.SourcePath                = assetSource;
            importModelCommand.Location                  = urlInStorage;
            importModelCommand.Allow32BitIndex           = allow32BitIndex;
            importModelCommand.AllowUnsignedBlendIndices = allowUnsignedBlendIndices;
            importModelCommand.Materials                 = asset.Materials;
            importModelCommand.ScaleImport               = asset.ScaleImport;
            importModelCommand.PivotPosition             = asset.PivotPosition;
            importModelCommand.SkeletonUrl               = skeleton?.Location;

            result.BuildSteps = new AssetBuildStep(AssetItem)
            {
                importModelCommand
            };
        }
Beispiel #17
0
 public void TestMixedSlash()
 {
     var assetPath1 = new UFile("/a\\b/c\\d.txt");
     var assetPath2 = new UFile("/a/b/c/d.txt");
     Assert.AreEqual(assetPath1.ToString(), assetPath2.ToString());
 }
Beispiel #18
0
        protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, UIImageGroupAsset asset, AssetCompilerResult result)
        {
            var imageToTextureIndex = CompileGroup(context, urlInStorage, assetAbsolutePath, asset, result);

            if (!result.HasErrors)
            {
                result.BuildSteps.Add(new UIImageGroupCommand(urlInStorage, new ImageGroupParameters <UIImageGroupAsset>(asset, context.Platform), imageToTextureIndex));
            }
        }
        protected override bool Generate(SessionTemplateGeneratorParameters parameters)
        {
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }
            parameters.Validate();

            var description = (TemplateSampleDescription)parameters.Description;
            var log         = parameters.Logger;

            // The package might depend on other packages which need to be copied together when instanciating it.
            //  However some of these packages might be in a parent folder, which can result in undesired behavior when copied.
            //  Setting this to true will enforce all package dependencies to be moved to a folder local to the project
            bool doMoveParentDependencies = true;

            var regexes     = new List <Tuple <Regex, MatchEvaluator> >();
            var patternName = description.PatternName ?? description.DefaultOutputName;

            // Samples don't support spaces and dot in name (we would need to separate package name, package short name and namespace renaming for that).
            var parametersName = parameters.Name.Replace(" ", string.Empty).Replace(".", string.Empty);

            if (patternName != parametersName)
            {
                // Make sure the target name is a safe for use everywhere, since both an asset or script might reference a filename
                //  in which case they should match and be valid in that context
                string validNamespaceName = Utilities.BuildValidNamespaceName(parametersName);

                // Rename for general occurences of template name
                regexes.Add(new Tuple <Regex, MatchEvaluator>(new Regex($@"\b{patternName}\b"), match => validNamespaceName));

                // Rename App as well (used in code) -- this is the only pattern of "package short name" that we have so far in Windows samples
                regexes.Add(new Tuple <Regex, MatchEvaluator>(new Regex($@"\b{patternName}App\b"), match => validNamespaceName));
            }

            var outputDirectory = parameters.OutputDirectory;

            if (!Directory.Exists(outputDirectory))
            {
                Directory.CreateDirectory(outputDirectory);
            }

            //write gitignore
            WriteGitIgnore(parameters);

            WriteGlobalJson(parameters);

            UFile projectOutputFile = null;
            UFile projectInputFile  = null;

            // Process files
            foreach (var directory in FileUtility.EnumerateDirectories(description.TemplateDirectory, SearchDirection.Down))
            {
                foreach (var file in directory.GetFiles())
                {
                    // If the file is ending with the Template extension or a directory with the sample extension, don;t copy it
                    if (file.FullName.EndsWith(TemplateDescription.FileExtension) ||
                        string.Compare(directory.Name, TemplateDescription.FileExtension, StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        continue;
                    }

                    var relativeFile = new UFile(file.FullName).MakeRelative(description.TemplateDirectory);

                    // Replace the name in the files if necessary
                    foreach (var nameRegex in regexes)
                    {
                        relativeFile = nameRegex.Item1.Replace(relativeFile, nameRegex.Item2);
                    }

                    // Create the output directory if needed
                    var outputFile          = UPath.Combine(outputDirectory, relativeFile);
                    var outputFileDirectory = outputFile.GetParent();

                    // Determine if we are processing the main game project
                    var isPackageFile = (projectOutputFile == null && Path.GetExtension(file.FullName).ToLowerInvariant() == ".csproj" && !Path.GetFileNameWithoutExtension(file.FullName).EndsWith(".Windows"));

                    if (isPackageFile)
                    {
                        projectInputFile  = file.FullName;
                        projectOutputFile = outputFile;
                    }

                    if (!Directory.Exists(outputFileDirectory))
                    {
                        Directory.CreateDirectory(outputFileDirectory);
                    }

                    if (IsBinaryFile(file.FullName))
                    {
                        File.Copy(file.FullName, outputFile, true);
                    }
                    else
                    {
                        ProcessTextFile(file.FullName, outputFile, regexes, (isPackageFile && doMoveParentDependencies));
                    }
                }
            }

            if (projectOutputFile != null)
            {
                var inputProject   = (SolutionProject)Package.LoadProject(log, projectInputFile);
                var outputProject  = (SolutionProject)Package.LoadProject(log, projectOutputFile);
                var msbuildProject = VSProjectHelper.LoadProject(outputProject.FullPath, platform: "NoPlatform");

                // If requested, add reference to Stride.Games.Testing
                if (parameters.TryGetTag(AddGamesTestingKey))
                {
                    var items = msbuildProject.AddItem("PackageReference", "Stride.Games.Testing", new[] { new KeyValuePair <string, string>("Version", StrideVersion.NuGetVersion), new KeyValuePair <string, string>("PrivateAssets", "contentfiles;analyzers") });
                    foreach (var item in items)
                    {
                        foreach (var metadata in item.Metadata)
                        {
                            metadata.Xml.ExpressedAsAttribute = true;
                        }
                    }
                }

                // Copy dependency files locally
                //  We only want to copy the asset files. The raw files are in Resources and the game assets are in Assets.
                //  If we copy each file locally they will be included in the package and we can then delete the dependency packages.
                foreach (var projectReference in msbuildProject.GetItems("ProjectReference").ToList())
                {
                    var packageDirectory = UPath.Combine(inputProject.FullPath.GetFullDirectory(), (UFile)projectReference.EvaluatedInclude).GetFullDirectory();
                    foreach (var directory in FileUtility.EnumerateDirectories(packageDirectory, SearchDirection.Down))
                    {
                        foreach (var file in directory.GetFiles())
                        {
                            // If the file is ending with the Template extension or a directory with the sample extension, don`t copy it
                            if (file.FullName.EndsWith(TemplateDescription.FileExtension) ||
                                string.Compare(directory.Name, TemplateDescription.FileExtension, StringComparison.OrdinalIgnoreCase) == 0)
                            {
                                continue;
                            }

                            var relativeFile     = new UFile(file.FullName).MakeRelative(packageDirectory);
                            var relativeFilename = relativeFile.ToString();

                            bool isAsset    = relativeFilename.Contains("Assets");
                            bool isResource = relativeFilename.Contains("Resources");

                            if (!isAsset && !isResource)
                            {
                                continue;
                            }

                            // Replace the name in the files if necessary
                            foreach (var nameRegex in regexes)
                            {
                                relativeFile = nameRegex.Item1.Replace(relativeFile, nameRegex.Item2);
                            }

                            var outputFile = UPath.Combine(outputDirectory, relativeFile);
                            {   // Create the output directory if needed
                                var outputFileDirectory = outputFile.GetParent();
                                if (!Directory.Exists(outputFileDirectory))
                                {
                                    Directory.CreateDirectory(outputFileDirectory);
                                }
                            }

                            if (IsBinaryFile(file.FullName))
                            {
                                File.Copy(file.FullName, outputFile, true);
                            }
                            else
                            {
                                ProcessTextFile(file.FullName, outputFile, regexes);
                            }
                        }
                    }

                    msbuildProject.RemoveItem(projectReference);
                }

                // Save csproj without ProjectReferences
                msbuildProject.Save();
                msbuildProject.ProjectCollection.UnloadAllProjects();
                msbuildProject.ProjectCollection.Dispose();

                // Add package to session
                var loadParams = PackageLoadParameters.Default();
                loadParams.GenerateNewAssetIds     = true;
                loadParams.LoadMissingDependencies = false;
                var session = parameters.Session;
                // We should switch to loading .csproj once all samples are upgraded
                var loadedProject = session.AddExistingProject(projectOutputFile, log, loadParams);

                RemoveUnusedAssets(loadedProject.Package, session);

                parameters.Tags.Add(GeneratedPackageKey, loadedProject.Package);
            }
            else
            {
                log.Error("Unable to find generated package for this template");
            }

            // Make sure we transfer overrides, etc. from what we deserialized to the asset graphs that we are going to save right after.
            ApplyMetadata(parameters);
            return(true);
        }
 private string GetPath(UFile imagePath)
 {
     return(UPath.Combine(Template.FullPath.GetFullDirectory(), imagePath));
 }
        private async Task PreLoadPackageDependencies(ILogger log, SolutionProject project, PackageLoadParameters loadParameters)
        {
            if (log == null)
            {
                throw new ArgumentNullException(nameof(log));
            }
            if (project == null)
            {
                throw new ArgumentNullException(nameof(project));
            }
            if (loadParameters == null)
            {
                throw new ArgumentNullException(nameof(loadParameters));
            }

            bool packageDependencyErrors = false;

            var package = project.Package;

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

            log.Verbose($"Process dependencies for {project.Name}...");

            var packageReferences = new Dictionary <string, PackageVersionRange>();

            // Check if there is any package upgrade to do
            var pendingPackageUpgrades = new List <PendingPackageUpgrade>();

            pendingPackageUpgradesPerPackage.Add(package, pendingPackageUpgrades);

            // Load some informations about the project
            try
            {
                var extraProperties = new Dictionary <string, string>();
                if (loadParameters.ExtraCompileProperties != null)
                {
                    foreach (var extraProperty in loadParameters.ExtraCompileProperties)
                    {
                        extraProperties.Add(extraProperty.Key, extraProperty.Value);
                    }
                }
                extraProperties.Add("SkipInvalidConfigurations", "true");
                var msProject = VSProjectHelper.LoadProject(project.FullPath, loadParameters.BuildConfiguration, extraProperties: extraProperties);
                try
                {
                    var packageVersion = msProject.GetPropertyValue("PackageVersion");

                    if (!string.IsNullOrEmpty(packageVersion))
                    {
                        package.Meta.Version = new PackageVersion(packageVersion);
                    }

                    project.TargetPath = msProject.GetPropertyValue("TargetPath");
                    project.AssemblyProcessorSerializationHashFile = msProject.GetProperty("StrideAssemblyProcessorSerializationHashFile")?.EvaluatedValue;
                    if (project.AssemblyProcessorSerializationHashFile != null)
                    {
                        project.AssemblyProcessorSerializationHashFile = Path.Combine(Path.GetDirectoryName(project.FullPath), project.AssemblyProcessorSerializationHashFile);
                    }
                    package.Meta.Name = (msProject.GetProperty("PackageId") ?? msProject.GetProperty("AssemblyName"))?.EvaluatedValue ?? package.Meta.Name;

                    var outputType = msProject.GetPropertyValue("OutputType");

                    project.Type = outputType.ToLowerInvariant() == "winexe" || outputType.ToLowerInvariant() == "exe" ||
                                   outputType.ToLowerInvariant() == "appcontainerexe" || // UWP
                                   msProject.GetPropertyValue("AndroidApplication").ToLowerInvariant() == "true" // Android
                        ? ProjectType.Executable
                        : ProjectType.Library;

                    // Note: Platform might be incorrect if Stride is not restored yet (it won't include Stride targets)
                    // Also, if already set, don't try to query it again
                    if (project.Type == ProjectType.Executable && project.Platform == PlatformType.Shared)
                    {
                        project.Platform = VSProjectHelper.GetPlatformTypeFromProject(msProject) ?? PlatformType.Shared;
                    }

                    foreach (var packageReference in msProject.GetItems("PackageReference").ToList())
                    {
                        if (packageReference.HasMetadata("Version") && PackageVersionRange.TryParse(packageReference.GetMetadataValue("Version"), out var packageRange))
                        {
                            packageReferences[packageReference.EvaluatedInclude] = packageRange;
                        }
                    }

                    // Need to go recursively
                    foreach (var projectReference in msProject.GetItems("ProjectReference").ToList())
                    {
                        var projectFile = new UFile(Path.Combine(Path.GetDirectoryName(project.FullPath), projectReference.EvaluatedInclude));
                        if (File.Exists(projectFile))
                        {
                            var referencedProject = Projects.OfType <SolutionProject>().FirstOrDefault(x => x.FullPath == new UFile(projectFile));
                            if (referencedProject != null)
                            {
                                await PreLoadPackageDependencies(log, referencedProject, loadParameters);

                                // Get package upgrader from dependency (a project might depend on another project rather than referencing Stride directly)
                                // A better system would be to evaluate nuget flattened dependencies WITHOUT doing the actual restore (dry-run).
                                // However I am not sure it's easy/possible to do it (using API) without doing a full restore/download, which we don't want to do
                                // with old version (it might be uninstalled already and we want to avoid re-downloading it again)
                                if (pendingPackageUpgradesPerPackage.TryGetValue(referencedProject.Package, out var dependencyPackageUpgraders))
                                {
                                    foreach (var dependencyPackageUpgrader in dependencyPackageUpgraders)
                                    {
                                        // Make sure this upgrader is not already added
                                        if (!pendingPackageUpgrades.Any(x => x.DependencyPackage == dependencyPackageUpgrader.DependencyPackage))
                                        {
                                            // Note: it's important to clone because once upgraded, each instance will have its Dependency.Version tested/updated
                                            pendingPackageUpgrades.Add(dependencyPackageUpgrader.Clone());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                finally
                {
                    msProject.ProjectCollection.UnloadAllProjects();
                    msProject.ProjectCollection.Dispose();
                }
            }
            catch (Exception ex)
            {
                log.Error($"Unexpected exception while loading project [{project.FullPath.ToWindowsPath()}]", ex);
            }

            foreach (var packageReference in packageReferences)
            {
                var dependencyName    = packageReference.Key;
                var dependencyVersion = packageReference.Value;

                var packageUpgrader = AssetRegistry.GetPackageUpgrader(dependencyName);
                if (packageUpgrader != null)
                {
                    // Check if this upgrader has already been added due to another package reference
                    if (pendingPackageUpgrades.Any(pendingPackageUpgrade => pendingPackageUpgrade.PackageUpgrader == packageUpgrader))
                    {
                        continue;
                    }

                    // Check if upgrade is necessary
                    if (dependencyVersion.MinVersion >= packageUpgrader.Attribute.UpdatedVersionRange.MinVersion)
                    {
                        continue;
                    }

                    // Check if upgrade is allowed
                    if (dependencyVersion.MinVersion < packageUpgrader.Attribute.PackageMinimumVersion)
                    {
                        // Throw an exception, because the package update is not allowed and can't be done
                        throw new InvalidOperationException($"Upgrading project [{project.Name}] to use [{dependencyName}] from version [{dependencyVersion}] to [{packageUpgrader.Attribute.UpdatedVersionRange.MinVersion}] is not supported (supported only from version [{packageUpgrader.Attribute.PackageMinimumVersion}]");
                    }

                    log.Info($"Upgrading project [{project.Name}] to use [{dependencyName}] from version [{dependencyVersion}] to [{packageUpgrader.Attribute.UpdatedVersionRange.MinVersion}] will be required");

                    pendingPackageUpgrades.Add(new PendingPackageUpgrade(packageUpgrader, new PackageDependency(dependencyName, dependencyVersion), null));
                }
            }

            if (pendingPackageUpgrades.Count > 0)
            {
                var upgradeAllowed = packageUpgradeAllowed != false ? PackageUpgradeRequestedAnswer.Upgrade : PackageUpgradeRequestedAnswer.DoNotUpgrade;

                // Need upgrades, let's ask user confirmation
                if (loadParameters.PackageUpgradeRequested != null && !packageUpgradeAllowed.HasValue)
                {
                    upgradeAllowed = loadParameters.PackageUpgradeRequested(package, pendingPackageUpgrades);
                    if (upgradeAllowed == PackageUpgradeRequestedAnswer.UpgradeAll)
                    {
                        packageUpgradeAllowed = true;
                    }
                    if (upgradeAllowed == PackageUpgradeRequestedAnswer.DoNotUpgradeAny)
                    {
                        packageUpgradeAllowed = false;
                    }
                }

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

                // Perform pre assembly load upgrade
                foreach (var pendingPackageUpgrade in pendingPackageUpgrades)
                {
                    var expectedVersion = pendingPackageUpgrade.PackageUpgrader.Attribute.UpdatedVersionRange.MinVersion.ToString();

                    // Update NuGet references
                    try
                    {
                        var projectFile    = project.FullPath;
                        var msbuildProject = VSProjectHelper.LoadProject(projectFile.ToWindowsPath());
                        var isProjectDirty = false;

                        foreach (var packageReference in msbuildProject.GetItems("PackageReference").ToList())
                        {
                            if (packageReference.EvaluatedInclude == pendingPackageUpgrade.Dependency.Name && packageReference.GetMetadataValue("Version") != expectedVersion)
                            {
                                packageReference.SetMetadataValue("Version", expectedVersion);
                                isProjectDirty = true;
                            }
                        }

                        if (isProjectDirty)
                        {
                            msbuildProject.Save();
                        }

                        msbuildProject.ProjectCollection.UnloadAllProjects();
                        msbuildProject.ProjectCollection.Dispose();
                    }
                    catch (Exception e)
                    {
                        log.Warning($"Unable to load project [{project.FullPath.GetFileName()}]", e);
                    }

                    var packageUpgrader   = pendingPackageUpgrade.PackageUpgrader;
                    var dependencyPackage = pendingPackageUpgrade.DependencyPackage;
                    if (!packageUpgrader.UpgradeBeforeAssembliesLoaded(loadParameters, package.Session, log, package, pendingPackageUpgrade.Dependency, dependencyPackage))
                    {
                        log.Error($"Error while upgrading package [{package.Meta.Name}] for [{dependencyPackage.Meta.Name}] from version [{pendingPackageUpgrade.Dependency.Version}] to [{dependencyPackage.Meta.Version}]");
                        return;
                    }
                }
            }

            // Now that our references are upgraded, let's do a real nuget restore (download files)
            log.Verbose($"Restore NuGet packages for {project.Name}...");
            if (loadParameters.AutoCompileProjects)
            {
                await VSProjectHelper.RestoreNugetPackages(log, project.FullPath);
            }

            // If platform was unknown (due to missing nuget packages during first pass), check it again
            if (project.Type == ProjectType.Executable && project.Platform == PlatformType.Shared)
            {
                try
                {
                    var msProject = VSProjectHelper.LoadProject(project.FullPath, extraProperties: new Dictionary <string, string> {
                        { "SkipInvalidConfigurations", "true" }
                    });
                    try
                    {
                        project.Platform = VSProjectHelper.GetPlatformTypeFromProject(msProject) ?? PlatformType.Shared;
                    }
                    finally
                    {
                        msProject.ProjectCollection.UnloadAllProjects();
                        msProject.ProjectCollection.Dispose();
                    }
                }
                catch (Exception ex)
                {
                    log.Error($"Unexpected exception while loading project [{project.FullPath.ToWindowsPath()}]", ex);
                }
            }

            UpdateDependencies(project, true, true);

            // 1. Load store package
            foreach (var projectDependency in project.FlattenedDependencies)
            {
                // Make all the assemblies known to the container to ensure that later assembly loads succeed
                foreach (var assembly in projectDependency.Assemblies)
                {
                    AssemblyContainer.RegisterDependency(assembly);
                }

                var loadedPackage = packages.Find(projectDependency);
                if (loadedPackage == null)
                {
                    string file = null;
                    switch (projectDependency.Type)
                    {
                    case DependencyType.Project:
                        if (Path.GetExtension(projectDependency.MSBuildProject).ToLowerInvariant() == ".csproj")
                        {
                            file = UPath.Combine(project.FullPath.GetFullDirectory(), (UFile)projectDependency.MSBuildProject);
                        }
                        break;

                    case DependencyType.Package:
                        file = PackageStore.Instance.GetPackageFileName(projectDependency.Name, new PackageVersionRange(projectDependency.Version), constraintProvider);
                        break;
                    }

                    if (file != null && File.Exists(file))
                    {
                        // Load package
                        var loadedProject = LoadProject(log, file, loadParameters);
                        loadedProject.Package.Meta.Name    = projectDependency.Name;
                        loadedProject.Package.Meta.Version = projectDependency.Version;
                        Projects.Add(loadedProject);

                        if (loadedProject is StandalonePackage standalonePackage)
                        {
                            standalonePackage.Assemblies.AddRange(projectDependency.Assemblies);
                        }

                        loadedPackage = loadedProject.Package;
                    }
                }

                if (loadedPackage != null)
                {
                    projectDependency.Package = loadedPackage;
                }
            }

            // 2. Load local packages

            /*foreach (var packageReference in package.LocalDependencies)
             * {
             *  // Check that the package was not already loaded, otherwise return the same instance
             *  if (Packages.ContainsById(packageReference.Id))
             *  {
             *      continue;
             *  }
             *
             *  // Expand the string of the location
             *  var newLocation = packageReference.Location;
             *
             *  var subPackageFilePath = package.RootDirectory != null ? UPath.Combine(package.RootDirectory, newLocation) : newLocation;
             *
             *  // Recursive load
             *  var loadedPackage = PreLoadPackage(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;
            }
        }
Beispiel #22
0
 protected abstract Task RestartAndOpenSession(UFile sessionPath);
        protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, AnimationAsset asset, AssetCompilerResult result)
        {
            if (!EnsureSourceExists(result, asset, assetAbsolutePath))
            {
                return;
            }

            // Get absolute path of asset source on disk
            var assetDirectory = assetAbsolutePath.GetParent();
            var assetSource    = GetAbsolutePath(assetAbsolutePath, asset.Source);
            var extension      = assetSource.GetFileExtension();
            var buildStep      = new AssetBuildStep(AssetItem);

            var additiveAnimationAsset = asset as AdditiveAnimationAsset;

            if (additiveAnimationAsset != null)
            {
                var baseUrlInStorage   = urlInStorage + "_animation_base";
                var sourceUrlInStorage = urlInStorage + "_animation_source";

                var baseAssetSource = UPath.Combine(assetDirectory, additiveAnimationAsset.BaseSource);

                // Import base and main animation
                if (ImportFbxCommand.IsSupportingExtensions(extension))
                {
                    buildStep.Add(new ImportFbxCommand {
                        SourcePath = assetSource, Location = sourceUrlInStorage, ExportType = "animation", AnimationRepeatMode = asset.RepeatMode, ScaleImport = asset.ScaleImport
                    });
                    buildStep.Add(new ImportFbxCommand {
                        SourcePath = baseAssetSource, Location = baseUrlInStorage, ExportType = "animation", AnimationRepeatMode = asset.RepeatMode, ScaleImport = asset.ScaleImport
                    });
                }
                else if (ImportAssimpCommand.IsSupportingExtensions(extension))
                {
                    buildStep.Add(new ImportAssimpCommand {
                        SourcePath = assetSource, Location = sourceUrlInStorage, ExportType = "animation", AnimationRepeatMode = asset.RepeatMode, ScaleImport = asset.ScaleImport
                    });
                    buildStep.Add(new ImportAssimpCommand {
                        SourcePath = baseAssetSource, Location = baseUrlInStorage, ExportType = "animation", AnimationRepeatMode = asset.RepeatMode, ScaleImport = asset.ScaleImport
                    });
                }
                // Wait for both import fbx commands to be completed
                buildStep.Add(new WaitBuildStep());

                // Generate the diff of those two animations
                buildStep.Add(new AdditiveAnimationCommand(urlInStorage, new AdditiveAnimationParameters(baseUrlInStorage, sourceUrlInStorage, additiveAnimationAsset.Mode)));
            }
            else
            {
                // Import the main animation
                if (ImportFbxCommand.IsSupportingExtensions(extension))
                {
                    buildStep.Add(new ImportFbxCommand {
                        SourcePath = assetSource, Location = urlInStorage, ExportType = "animation", AnimationRepeatMode = asset.RepeatMode, ScaleImport = asset.ScaleImport
                    });
                }
                else if (ImportAssimpCommand.IsSupportingExtensions(extension))
                {
                    buildStep.Add(new ImportAssimpCommand {
                        SourcePath = assetSource, Location = urlInStorage, ExportType = "animation", AnimationRepeatMode = asset.RepeatMode, ScaleImport = asset.ScaleImport
                    });
                }
            }

            result.BuildSteps = buildStep;
        }
Beispiel #24
0
 public PackageLoadingAssetFile(UFile filePath, UDirectory sourceFolder, UFile projectFile)
 {
     FilePath     = filePath;
     SourceFolder = sourceFolder;
     ProjectFile  = projectFile;
 }
Beispiel #25
0
 void RegisterItem(UFile targetFilePath)
 {
     generatedItems.Add((targetFilePath.ToWindowsPath(), UPath.Combine("stride", targetFilePath.MakeRelative(outputPath)).ToWindowsPath()));
 }
 public static string GenerateColorTextureURL(UFile originalLocation)
 {
     return(GenerateSeparateTextureURL(originalLocation, SplittedColorTextureNameSuffix));
 }
Beispiel #27
0
        public static SolutionProject GenerateTemplate(TemplateGeneratorParameters parameters, UFile templateRelativePath, string projectName, PlatformType platformType, GraphicsPlatform?graphicsPlatform, ProjectType projectType, out List <string> generatedFiles, Guid?projectGuidArg = null)
        {
            var options             = GetOptions(parameters);
            var outputDirectoryPath = UPath.Combine(parameters.OutputDirectory, (UDirectory)projectName);

            Directory.CreateDirectory(outputDirectoryPath);

            generatedFiles = new List <string>();
            parameters.Logger.Verbose($"Generating {projectName}...");

            var projectGuid     = projectGuidArg ?? Guid.NewGuid();
            var packagePath     = UPath.Combine(outputDirectoryPath, (UFile)(projectName + Package.PackageFileExtension));
            var projectFullPath = UPath.Combine(outputDirectoryPath, (UFile)(projectName + ".csproj"));

            var package = new Package
            {
                Meta =
                {
                    Name    = projectName,
                    Version = new PackageVersion("1.0.0.0")
                },
                FullPath = packagePath,
                IsDirty  = true,
            };

            package.AssetFolders.Add(new AssetFolder("Assets"));
            package.ResourceFolders.Add("Resources");

            var projectTemplate = PrepareTemplate(parameters, package, templateRelativePath, platformType, graphicsPlatform, projectType);

            projectTemplate.Generate(outputDirectoryPath, projectName, projectGuid, parameters.Logger, options, generatedFiles);

            var project = new SolutionProject(package, projectGuid, projectFullPath);

            project.Type     = projectType;
            project.Platform = platformType;

            return(project);
        }
 private static string GenerateSeparateTextureURL(UFile originalLocation, string suffixName)
 {
     return(originalLocation.GetDirectory() + "/" + SplittedTextureNamePrefix + originalLocation.GetFileName() + suffixName);
 }
Beispiel #29
0
        protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, SpriteFontAsset asset, AssetCompilerResult result)
        {
            var colorSpace = context.GetColorSpace();

            if (asset.FontType is SignedDistanceFieldSpriteFontType)
            {
                var fontTypeSDF = asset.FontType as SignedDistanceFieldSpriteFontType;

                // copy the asset and transform the source and character set file path to absolute paths
                var assetClone     = (SpriteFontAsset)AssetCloner.Clone(asset);
                var assetDirectory = assetAbsolutePath.GetParent();
                assetClone.FontSource    = asset.FontSource;
                fontTypeSDF.CharacterSet = !string.IsNullOrEmpty(fontTypeSDF.CharacterSet) ? UPath.Combine(assetDirectory, fontTypeSDF.CharacterSet) : null;

                result.BuildSteps = new AssetBuildStep(AssetItem)
                {
                    new SignedDistanceFieldFontCommand(urlInStorage, assetClone)
                };
            }
            else
            if (asset.FontType is RuntimeRasterizedSpriteFontType)
            {
                UFile fontPathOnDisk = asset.FontSource.GetFontPath(result);
                if (fontPathOnDisk == null)
                {
                    result.Error("Runtime rasterized font compilation failed. Font {0} was not found on this machine.", asset.FontSource.GetFontName());
                    result.BuildSteps = new AssetBuildStep(AssetItem)
                    {
                        new FailedFontCommand()
                    };
                    return;
                }

                var fontImportLocation = FontHelper.GetFontPath(asset.FontSource.GetFontName(), asset.FontSource.Style);

                result.BuildSteps = new AssetBuildStep(AssetItem)
                {
                    new ImportStreamCommand {
                        SourcePath = fontPathOnDisk, Location = fontImportLocation
                    },
                    new RuntimeRasterizedFontCommand(urlInStorage, asset)
                };
            }
            else
            {
                var fontTypeStatic = asset.FontType as OfflineRasterizedSpriteFontType;
                if (fontTypeStatic == null)
                {
                    throw new ArgumentException("Tried to compile a non-offline rasterized sprite font with the compiler for offline resterized fonts!");
                }

                // copy the asset and transform the source and character set file path to absolute paths
                var assetClone     = (SpriteFontAsset)AssetCloner.Clone(asset);
                var assetDirectory = assetAbsolutePath.GetParent();
                assetClone.FontSource       = asset.FontSource;
                fontTypeStatic.CharacterSet = !string.IsNullOrEmpty(fontTypeStatic.CharacterSet) ? UPath.Combine(assetDirectory, fontTypeStatic.CharacterSet): null;

                result.BuildSteps = new AssetBuildStep(AssetItem)
                {
                    new OfflineRasterizedFontCommand(urlInStorage, assetClone, colorSpace)
                };
            }
        }
Beispiel #30
0
 /// <summary>
 /// Initializes a new instance of the <see cref="AdditiveAnimationAsset"/> class.
 /// </summary>
 public AdditiveAnimationAsset()
 {
     BaseSource = new UFile("");
 }
Beispiel #31
0
 public void TestWithSimplePathWithExtension()
 {
     var assetPath = new UFile("/a/b/c.txt");
     Assert.AreEqual("/a/b", assetPath.GetDirectory());
     Assert.AreEqual("c", assetPath.GetFileName());
     Assert.AreEqual(".txt", assetPath.GetFileExtension());
     Assert.AreEqual("/a/b/c", assetPath.GetDirectoryAndFileName());
     Assert.AreEqual("/a/b/c.txt", assetPath.FullPath);
 }
Beispiel #32
0
        private static async void Startup(UFile initialSessionPath)
        {
            try
            {
                InitializeLanguageSettings();
                var serviceProvider = InitializeServiceProvider();

                try
                {
                    PackageSessionPublicHelper.FindAndSetMSBuildVersion();
                }
                catch (Exception e)
                {
                    var message = "Could not find a compatible version of MSBuild.\r\n\r\n" +
                                  "Check that you have a valid installation with the required workloads, or go to [www.visualstudio.com/downloads](https://www.visualstudio.com/downloads) to install a new one.\r\n\r\n" +
                                  e;
                    await serviceProvider.Get <IEditorDialogService>().MessageBox(message, Core.Presentation.Services.MessageBoxButton.OK, Core.Presentation.Services.MessageBoxImage.Error);

                    app.Shutdown();
                    return;
                }

                // We use a MRU that contains the older version projects to display in the editor
                var mru = new MostRecentlyUsedFileCollection(InternalSettings.LoadProfileCopy, InternalSettings.MostRecentlyUsedSessions, InternalSettings.WriteFile);
                mru.LoadFromSettings();
                var editor = new GameStudioViewModel(serviceProvider, mru);
                AssetsPlugin.RegisterPlugin(typeof(XenkoDefaultAssetsPlugin));
                AssetsPlugin.RegisterPlugin(typeof(XenkoEditorPlugin));

                // Attempt to load the startup session, if available
                if (!UPath.IsNullOrEmpty(initialSessionPath))
                {
                    var sessionLoaded = await editor.OpenInitialSession(initialSessionPath);

                    if (sessionLoaded == true)
                    {
                        var mainWindow = new GameStudioWindow(editor);
                        Application.Current.MainWindow = mainWindow;
                        WindowManager.ShowMainWindow(mainWindow);
                        return;
                    }
                }

                // No session successfully loaded, open the new/open project window
                bool?completed;
                // The user might cancel after chosing a template to instantiate, in this case we'll reopen the window
                var startupWindow = new ProjectSelectionWindow
                {
                    WindowStartupLocation = WindowStartupLocation.CenterScreen,
                    ShowInTaskbar         = true,
                };
                var viewModel = new NewOrOpenSessionTemplateCollectionViewModel(serviceProvider, startupWindow);
                startupWindow.Templates = viewModel;
                startupWindow.ShowDialog();

                // The user selected a template to instantiate
                if (startupWindow.NewSessionParameters != null)
                {
                    // Clean existing entry in the MRU data
                    var directory = startupWindow.NewSessionParameters.OutputDirectory;
                    var name      = startupWindow.NewSessionParameters.OutputName;
                    var mruData   = new MRUAdditionalDataCollection(InternalSettings.LoadProfileCopy, GameStudioInternalSettings.MostRecentlyUsedSessionsData, InternalSettings.WriteFile);
                    mruData.RemoveFile(UFile.Combine(UDirectory.Combine(directory, name), new UFile(name + SessionViewModel.SolutionExtension)));

                    completed = await editor.NewSession(startupWindow.NewSessionParameters);
                }
                // The user selected a path to open
                else if (startupWindow.ExistingSessionPath != null)
                {
                    completed = await editor.OpenSession(startupWindow.ExistingSessionPath);
                }
                // The user cancelled from the new/open project window, so exit the application
                else
                {
                    completed = true;
                }

                if (completed != true)
                {
                    var windowsClosed = new List <Task>();
                    foreach (var window in Application.Current.Windows.Cast <Window>().Where(x => x.IsLoaded))
                    {
                        var tcs = new TaskCompletionSource <int>();
                        window.Unloaded += (s, e) => tcs.SetResult(0);
                        windowsClosed.Add(tcs.Task);
                    }

                    await Task.WhenAll(windowsClosed);

                    // When a project has been partially loaded, it might already have initialized some plugin that could conflict with
                    // the next attempt to start something. Better start the application again.
                    var commandLine = string.Join(" ", Environment.GetCommandLineArgs().Skip(1).Select(x => $"\"{x}\""));
                    var process     = new Process {
                        StartInfo = new ProcessStartInfo(typeof(Program).Assembly.Location, commandLine)
                    };
                    process.Start();
                    app.Shutdown();
                    return;
                }

                if (editor.Session != null)
                {
                    // If a session was correctly loaded, show the main window
                    var mainWindow = new GameStudioWindow(editor);
                    Application.Current.MainWindow = mainWindow;
                    WindowManager.ShowMainWindow(mainWindow);
                }
                else
                {
                    // Otherwise, exit.
                    app.Shutdown();
                }
            }
            catch (Exception)
            {
                app.Shutdown();
            }
        }
Beispiel #33
0
        public void TestEquals()
        {
            var assetPath1 = new UFile(null);
            var assetPath2 = new UFile(null);
            Assert.AreEqual(assetPath1, assetPath2);

            assetPath1 = new UFile("/a/b/c.txt");
            assetPath2 = new UFile("/a/b/d/../c.txt");
            Assert.AreEqual(assetPath1, assetPath2);

            // Test is not done on Extensions
            assetPath1 = new UFile("/a/b/c.txt");
            assetPath2 = new UFile("/a/b/d/../c.png");
            Assert.AreNotEqual(assetPath1, assetPath2);
            Assert.AreEqual(assetPath1.GetDirectoryAndFileName(), assetPath2.GetDirectoryAndFileName());
        }
Beispiel #34
0
 private bool TextureFileIsValid(UFile file)
 {
     return(file != null && File.Exists(file));
 }
Beispiel #35
0
        public void TestGetParent()
        {
            var dirPath1 = new UDirectory(@"E:\a\b");

            var dirPathParent1 = dirPath1.GetParent();
            Assert.AreEqual(@"E:/a", dirPathParent1.FullPath);

            dirPathParent1 = dirPathParent1.GetParent();
            Assert.AreEqual(@"E:", dirPathParent1.FullPath);

            dirPathParent1 = dirPathParent1.GetParent();
            Assert.AreEqual(UDirectory.Empty, dirPathParent1);

            dirPath1 = new UDirectory(@"/a/b");

            dirPathParent1 = dirPath1.GetParent();
            Assert.AreEqual(@"/a", dirPathParent1.FullPath);

            dirPathParent1 = dirPathParent1.GetParent();
            Assert.AreEqual(@"/", dirPathParent1.FullPath);

            dirPathParent1 = dirPathParent1.GetParent();
            Assert.AreEqual(UDirectory.Empty, dirPathParent1);

            // Test on file
            var filePath1 = new UFile(@"/a/b.txt");

            dirPathParent1 = filePath1.GetParent();
            Assert.AreEqual(@"/a", dirPathParent1.FullPath);
        }
Beispiel #36
0
        protected override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, SpriteSheetAsset asset, AssetCompilerResult result)
        {
            var gameSettingsAsset = context.GetGameSettingsAsset();
            var renderingSettings = gameSettingsAsset.Get <RenderingSettings>(context.Platform);

            result.BuildSteps = new ListBuildStep();

            // create the registry containing the sprite assets texture index association
            var imageToTextureUrl = new Dictionary <SpriteInfo, string>();

            var colorSpace = context.GetColorSpace();

            // create and add import texture commands
            if (asset.Sprites != null && !asset.Packing.Enabled)
            {
                // sort sprites by referenced texture.
                var spriteByTextures = asset.Sprites.GroupBy(x => x.Source).ToArray();
                for (int i = 0; i < spriteByTextures.Length; i++)
                {
                    // skip the texture if the file is not valid.
                    var textureFile = spriteByTextures[i].Key;
                    if (!TextureFileIsValid(textureFile))
                    {
                        continue;
                    }

                    var textureUrl = SpriteSheetAsset.BuildTextureUrl(urlInStorage, i);

                    var spriteAssetArray = spriteByTextures[i].ToArray();
                    foreach (var spriteAsset in spriteAssetArray)
                    {
                        imageToTextureUrl[spriteAsset] = textureUrl;
                    }

                    // create an texture asset.
                    var textureAsset = new TextureAsset
                    {
                        Id               = Guid.Empty, // CAUTION: It is important to use an empty GUID here, as we don't want the command to be rebuilt (by default, a new asset is creating a new guid)
                        Alpha            = asset.Alpha,
                        Format           = asset.Format,
                        GenerateMipmaps  = asset.GenerateMipmaps,
                        PremultiplyAlpha = asset.PremultiplyAlpha,
                        ColorKeyColor    = asset.ColorKeyColor,
                        ColorKeyEnabled  = asset.ColorKeyEnabled,
                        ColorSpace       = asset.ColorSpace,
                        Hint             = TextureHint.Color
                    };

                    // Get absolute path of asset source on disk
                    var assetDirectory = assetAbsolutePath.GetParent();
                    var assetSource    = UPath.Combine(assetDirectory, spriteAssetArray[0].Source);

                    // add the texture build command.
                    result.BuildSteps.Add(new AssetBuildStep(new AssetItem(textureUrl, textureAsset))
                    {
                        new TextureAssetCompiler.TextureConvertCommand(
                            textureUrl,
                            new TextureConvertParameters(assetSource, textureAsset, context.Platform, context.GetGraphicsPlatform(AssetItem.Package), renderingSettings.DefaultGraphicsProfile, gameSettingsAsset.Get <TextureSettings>().TextureQuality, colorSpace))
                    });
                }
            }

            if (!result.HasErrors)
            {
                var parameters = new SpriteSheetParameters(asset, imageToTextureUrl, context.Platform, context.GetGraphicsPlatform(AssetItem.Package), renderingSettings.DefaultGraphicsProfile, gameSettingsAsset.Get <TextureSettings>().TextureQuality, colorSpace);
                result.BuildSteps.Add(new AssetBuildStep(AssetItem)
                {
                    new SpriteSheetCommand(urlInStorage, parameters)
                });
            }
        }
Beispiel #37
0
        public void TestMakeRelativeWithDrive()
        {
            UPath assetPath2 = null;
            UPath newAssetPath2 = null;
            var dir1 = new UDirectory("C:/a/b/c");

            // Test direct relative
            assetPath2 = new UFile("C:/a/b/c/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("test.txt", newAssetPath2.FullPath);

            // Test direct relative + subdir
            assetPath2 = new UFile("C:/a/b/c/test/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("test/test.txt", newAssetPath2.FullPath);

            // Test relative 1
            assetPath2 = new UFile("C:/a/b/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../test.txt", newAssetPath2.FullPath);

            // Test relative 2
            assetPath2 = new UFile("C:/a/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../test.txt", newAssetPath2.FullPath);

            // Test relative 3
            assetPath2 = new UFile("C:/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../../test.txt", newAssetPath2.FullPath);

            // Test already relative
            assetPath2 = new UFile("../test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../test.txt", newAssetPath2.FullPath);

            // Test no path in common
            assetPath2 = new UFile("E:/e/f/g/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("E:/e/f/g/test.txt", newAssetPath2.FullPath);

            // Test no root path single file
            assetPath2 = new UFile("E:/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("E:/test.txt", newAssetPath2.FullPath);
        }
        public void TestMakeRelative()
        {
            UPath assetPath2    = null;
            UPath newAssetPath2 = null;
            var   dir1          = new UDirectory("/a/b/c");

            var assetDir2 = new UDirectory("/a/b/c");

            newAssetPath2 = dir1.MakeRelative(assetDir2);
            Assert.AreEqual(".", newAssetPath2.FullPath);

            var assetDir3 = new UDirectory("/a/b");

            newAssetPath2 = dir1.MakeRelative(assetDir3);
            Assert.AreEqual("c", newAssetPath2.FullPath);

            var assetDir4 = new UDirectory("/a/b/c/d");

            newAssetPath2 = dir1.MakeRelative(assetDir4);
            Assert.AreEqual("..", newAssetPath2.FullPath);

            // Test direct relative
            assetPath2    = new UFile("/a/b/c/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("test.txt", newAssetPath2.FullPath);

            // Test direct relative + subdir
            assetPath2    = new UFile("/a/b/c/test/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("test/test.txt", newAssetPath2.FullPath);

            // Test relative 1
            assetPath2    = new UFile("/a/b/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../test.txt", newAssetPath2.FullPath);

            // Test relative 2
            assetPath2    = new UFile("/a/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../test.txt", newAssetPath2.FullPath);

            // Test relative 3
            assetPath2    = new UFile("/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../../test.txt", newAssetPath2.FullPath);

            // Test already relative
            assetPath2    = new UFile("../test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../test.txt", newAssetPath2.FullPath);

            // Test only root path in common
            assetPath2    = new UFile("/e/f/g/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../../e/f/g/test.txt", newAssetPath2.FullPath);

            // Test only root path in common with single file
            assetPath2    = new UFile("/test.txt");
            newAssetPath2 = assetPath2.MakeRelative(dir1);
            Assert.AreEqual("../../../test.txt", newAssetPath2.FullPath);
        }