protected override async Task <bool> AfterSave(SessionTemplateGeneratorParameters parameters) { // If package was not generated Package package; parameters.Tags.TryGetValue(GeneratedPackageKey, out package); if (package == null) { return(false); } // Update platforms for the sample var updateSample = TemplateManager.FindTemplates(package.Session).FirstOrDefault(template => template.Id == UpdatePlatformsTemplateGenerator.TemplateId); parameters.Description = updateSample; var updateParameters = new PackageTemplateGeneratorParameters(parameters, package); updateParameters.Unattended = true; var orientation = package.GetGameSettingsAsset()?.GetOrCreate <RenderingSettings>().DisplayOrientation ?? RequiredDisplayOrientation.Default; UpdatePlatformsTemplateGenerator.SetOrientation(updateParameters, (DisplayOrientation)orientation); UpdatePlatformsTemplateGenerator.SetPlatforms(updateParameters, parameters.GetTag(PlatformsKey)); // We want to force regeneration of Windows platform in case the sample .csproj is outdated UpdatePlatformsTemplateGenerator.SetForcePlatformRegeneration(updateParameters, true); var updateTemplate = UpdatePlatformsTemplateGenerator.Default; if (!await updateTemplate.PrepareForRun(updateParameters) || !updateTemplate.Run(updateParameters)) { // Remove the created project var path = Path.GetDirectoryName(parameters.Session.SolutionPath.ToWindowsPath()); try { Directory.Delete(path ?? "", true); } catch (IOException ex) { parameters.Logger.Error("Error when removing generated project.", ex); } catch (UnauthorizedAccessException ex) { parameters.Logger.Error("Error when removing generated project.", ex); } // Notify cancellation return(false); } // Save again post update SaveSession(parameters); // Restore NuGet packages again parameters.Logger.Verbose("Restore NuGet packages..."); await VSProjectHelper.RestoreNugetPackages(parameters.Logger, parameters.Session.SolutionPath); return(true); }
public async Task UpdatePackageTemplate(TemplateDescription template) { var loggerResult = new LoggerResult(); var workProgress = new WorkProgressViewModel(ServiceProvider, loggerResult) { Title = "Updating package...", KeepOpen = KeepOpen.OnWarningsOrErrors, IsIndeterminate = true, IsCancellable = false }; workProgress.RegisterProgressStatus(loggerResult, true); var parameters = new PackageTemplateGeneratorParameters { Name = Package.Meta.Name, OutputDirectory = Package.FullPath.GetFullDirectory(), Description = template, Package = Package, Logger = loggerResult, }; var generator = TemplateManager.FindTemplateGenerator(parameters); if (generator == null) { await ServiceProvider.Get <IDialogService>().MessageBox(Tr._p("Message", "Unable to retrieve template generator for the selected template. Aborting."), MessageBoxButton.OK, MessageBoxImage.Error); return; } // Errors might occur when generating the template. For the moment we consider them non-fatal and allow to open the project anyway. await TemplateGeneratorHelper.RunTemplateGeneratorSafe(generator, parameters, workProgress); RefreshProjects(); await workProgress.NotifyWorkFinished(false, loggerResult.HasErrors); Package.IsDirty = true; }
public static IEnumerable <SolutionProject> UpdatePackagePlatforms(PackageTemplateGeneratorParameters packageParameters, ICollection <SelectedSolutionPlatform> platforms, DisplayOrientation orientation, bool forcePlatformRegeneration) { if (platforms == null) { throw new ArgumentNullException(nameof(platforms)); } var logger = packageParameters.Logger; var package = packageParameters.Package; var name = packageParameters.Name; var addedProjects = new List <SolutionProject>(); // Adjust output directory var parameters = new SessionTemplateGeneratorParameters { Logger = logger, Name = name, OutputDirectory = package.FullPath.GetFullDirectory().GetParent(), Session = package.Session, Description = packageParameters.Description, Namespace = packageParameters.Namespace }; // Setup the ProjectGameGuid to be accessible from exec (in order to be able to link to the game project. AddOption(parameters, "ProjectGameGuid", (package.Container as SolutionProject)?.Id ?? Guid.Empty); AddOption(parameters, "ProjectGameRelativePath", (package.Container as SolutionProject)?.FullPath.MakeRelative(parameters.OutputDirectory).ToWindowsPath()); AddOption(parameters, "PackageGameAssemblyName", package.Meta.Name); // Sample templates still have .Game in their name var packageNameWithoutGame = package.Meta.Name; if (packageNameWithoutGame.EndsWith(".Game")) { packageNameWithoutGame = packageNameWithoutGame.Substring(0, packageNameWithoutGame.Length - ".Game".Length); } AddOption(parameters, "PackageGameName", packageNameWithoutGame); AddOption(parameters, "PackageGameDisplayName", package.Meta.Title ?? packageNameWithoutGame); // Escape illegal characters for the short name AddOption(parameters, "PackageGameNameShort", Utilities.BuildValidClassName(packageNameWithoutGame.Replace(" ", string.Empty))); AddOption(parameters, "PackageGameRelativePath", package.FullPath.MakeRelative(parameters.OutputDirectory).ToWindowsPath()); // Override namespace AddOption(parameters, "Namespace", parameters.Namespace ?? Utilities.BuildValidNamespaceName(packageNameWithoutGame)); // Add projects var stepIndex = 0; var stepCount = platforms.Count + 1; var projectsToRemove = AssetRegistry.SupportedPlatforms .Where(platform => !platforms.Select(x => x.Platform).Contains(platform)) .Select(platform => { var projectFullPath = GeneratePlatformProjectLocation(name, package, platform); return(package.Session.Projects.OfType <SolutionProject>().FirstOrDefault(project => project.FullPath == projectFullPath)); }) .NotNull() .ToList(); foreach (var platform in platforms) { stepIndex++; var projectFullPath = GeneratePlatformProjectLocation(name, package, platform.Platform); var projectName = projectFullPath.GetFileNameWithoutExtension(); // Don't add a platform that is already in the package var existingProject = package.Session.Projects.OfType <SolutionProject>().FirstOrDefault(x => x.FullPath == projectFullPath); var projectGuid = Guid.NewGuid(); if (existingProject != null) { if (!forcePlatformRegeneration) { continue; } projectGuid = existingProject.Id; // We are going to regenerate this platform, so we are removing it before package.Session.Projects.Remove(existingProject); } var projectDirectory = Path.GetDirectoryName(projectFullPath.ToWindowsPath()); if (projectDirectory != null && Directory.Exists(projectDirectory)) { try { Directory.Delete(projectDirectory, true); } catch (Exception) { logger.Warning($"Unable to delete directory [{projectDirectory}]"); } } var templatePath = platform.Template?.TemplatePath ?? $"ProjectExecutable.{platform.Platform.Name}/ProjectExecutable.{platform.Platform.Name}.ttproj"; // Log progress Progress(logger, $"Generating {projectName}...", stepIndex - 1, stepCount); var graphicsPlatform = platform.Platform.Type.GetDefaultGraphicsPlatform(); var newExeProject = GenerateTemplate(parameters, platforms, templatePath, projectName, platform.Platform.Type, graphicsPlatform, ProjectType.Executable, orientation, projectGuid); package.Session.Projects.Add(newExeProject); package.Session.IsDirty = true; addedProjects.Add(newExeProject); } foreach (var project in projectsToRemove) { var projectFullPath = project.FullPath; var projectDirectory = Path.GetDirectoryName(projectFullPath.ToWindowsPath()); if (projectDirectory != null && Directory.Exists(projectDirectory)) { try { Directory.Delete(projectDirectory, true); } catch (Exception) { logger.Warning($"Unable to delete directory [{projectDirectory}]"); } } package.Session.Projects.Remove(project); package.Session.IsDirty = true; } return(addedProjects); }
protected override bool Generate(SessionTemplateGeneratorParameters parameters) { if (parameters == null) { throw new ArgumentNullException(nameof(parameters)); } // Structure of files to generate: // $Name$.sdpkg // $Name$.targets // Assets\ // $Name$.Game\ // $Name$.Windows\ // $Name$.Android\ // $Name$.iOS\ var logger = parameters.Logger; var platforms = parameters.GetTag(PlatformsKey); var name = parameters.Name; var outputDirectory = parameters.OutputDirectory; var orientation = parameters.GetTag(OrientationKey); // Generate the package //var package = NewPackageTemplateGenerator.GeneratePackage(parameters); // Generate projects for this package var session = parameters.Session; var projectGameName = Utilities.BuildValidNamespaceName(name); var stepIndex = 0; var stepCount = platforms.Count + 1; // Log progress ProjectTemplateGeneratorHelper.Progress(logger, $"Generating {projectGameName}...", stepIndex++, stepCount); // Generate the Game library var project = ProjectTemplateGeneratorHelper.GenerateTemplate(parameters, platforms, "ProjectLibrary.Game/ProjectLibrary.Game.ttproj", projectGameName, PlatformType.Shared, null, ProjectType.Library, orientation); var package = project.Package; //write gitignore WriteGitIgnore(parameters); // Setup the assets folder //Directory.CreateDirectory(UPath.Combine(package.RootDirectory, (UDirectory)"Assets/Shared")); session.Projects.Add(project); // Load missing references session.LoadMissingDependencies(parameters.Logger); // Load dependency assets (needed for camera script template) session.LoadMissingAssets(parameters.Logger, project.FlattenedDependencies.Select(x => x.Package).NotNull()); // Add Effects as an asset folder in order to load sdsl package.AssetFolders.Add(new AssetFolder("Effects")); var packageParameters = new PackageTemplateGeneratorParameters { Name = package.Meta.Name, OutputDirectory = package.FullPath.GetFullDirectory(), Description = parameters.Description, Package = package, Logger = parameters.Logger, Namespace = parameters.Namespace }; // Generate executable projects for each platform var platformProjects = ProjectTemplateGeneratorHelper.UpdatePackagePlatforms(packageParameters, platforms, orientation, false).ToList(); // Add asset packages CopyAssetPacks(parameters, package); // Create camera script var cameraScriptTemplate = TemplateManager.FindTemplates(package.Session).OfType <TemplateAssetDescription>().FirstOrDefault(x => x.DefaultOutputName == CameraScriptDefaultOutputName); if (cameraScriptTemplate == null) { throw new InvalidOperationException($"Could not find template for script '{CameraScriptDefaultOutputName}'"); } var cameraScriptParameters = new AssetTemplateGeneratorParameters(string.Empty) { Name = cameraScriptTemplate.DefaultOutputName, Description = cameraScriptTemplate, Namespace = parameters.Namespace, Package = package, Logger = logger, Unattended = true, }; ScriptTemplateGenerator.SetClassName(cameraScriptParameters, cameraScriptTemplate.DefaultOutputName); if (!ScriptTemplateGenerator.Default.PrepareForRun(cameraScriptParameters).Result || !ScriptTemplateGenerator.Default.Run(cameraScriptParameters)) { throw new InvalidOperationException($"Could not create script '{CameraScriptDefaultOutputName}'"); } // Force save after having created the script // Note: We do that AFTER GameSettings is dirty, otherwise it would ask for an assembly reload (game settings saved might mean new graphics API) SaveSession(parameters); // Load missing references session.LoadMissingReferences(parameters.Logger); // Setup GraphicsCompositor using DefaultGraphicsCompositor var graphicsProfile = parameters.GetTag(GraphicsProfileKey); var defaultCompositorUrl = graphicsProfile >= GraphicsProfile.Level_10_0 ? StridePackageUpgrader.DefaultGraphicsCompositorLevel10Url : StridePackageUpgrader.DefaultGraphicsCompositorLevel9Url; var defaultCompositor = session.FindAsset(defaultCompositorUrl); var graphicsCompositor = new AssetItem("GraphicsCompositor", defaultCompositor.CreateDerivedAsset()); package.Assets.Add(graphicsCompositor); graphicsCompositor.IsDirty = true; // Setup GameSettingsAsset var gameSettingsAsset = GameSettingsFactory.Create(); gameSettingsAsset.GetOrCreate <EditorSettings>().RenderingMode = parameters.GetTag(IsHDRKey) ? RenderingMode.HDR : RenderingMode.LDR; gameSettingsAsset.GraphicsCompositor = AttachedReferenceManager.CreateProxyObject <GraphicsCompositor>(graphicsCompositor.ToReference()); var renderingSettings = gameSettingsAsset.GetOrCreate <RenderingSettings>(); renderingSettings.DefaultGraphicsProfile = parameters.GetTag(GraphicsProfileKey); renderingSettings.DisplayOrientation = (RequiredDisplayOrientation)orientation; var gameSettingsAssetItem = new AssetItem(GameSettingsAsset.GameSettingsLocation, gameSettingsAsset); package.Assets.Add(gameSettingsAssetItem); gameSettingsAssetItem.IsDirty = true; // Add assets to the package AddAssets(parameters, package, projectGameName); // Log done ProjectTemplateGeneratorHelper.Progress(logger, "Done", stepCount, stepCount); // Set current project session.CurrentProject = platformProjects.FirstOrDefault(x => x.Platform == PlatformType.Windows) ?? project; return(true); }