// Copyright (c) 2012-2020 Flax Engine. All rights reserved. using System; using System.Collections.Generic; using Flax.Build.Projects.VisualStudio; using Flax.Build.Projects.VisualStudioCode; namespace Flax.Build.Projects { /// /// The project files generators base class. /// public abstract class ProjectGenerator { /// /// Gets the project file extension (excluding the leading dot). /// public abstract string ProjectFileExtension { get; } /// /// Gets the solution file extension (excluding the leading dot). /// public abstract string SolutionFileExtension { get; } /// /// Gets the generator projects target type. /// public abstract TargetType? Type { get; } /// /// Creates the empty project (factory design pattern). /// /// The empty project. public virtual Project CreateProject() { return new Project { Generator = this, }; } /// /// Creates the empty solution (factory design pattern). /// /// The empty solution. public virtual Solution CreateSolution() { return new Solution(); } /// /// Generates the project. /// /// The project. public abstract void GenerateProject(Project project); /// /// Generates the solution. /// /// The solution. public abstract void GenerateSolution(Solution solution); /// /// Generates the custom projects for the solution. /// /// The projects. public virtual void GenerateCustomProjects(List projects) { } /// /// The custom project types factories. Key is the custom project format name and the value is the factory function used to spawn it. /// public static readonly Dictionary> CustomProjectTypes = new Dictionary>(); /// /// Creates the project files generator for the specified project format. /// /// The format. /// The target project type. /// The generator. public static ProjectGenerator Create(ProjectFormat format, TargetType type) { // Pick the newest installed Visual Studio version if (format == ProjectFormat.VisualStudio) { if (VisualStudioInstance.HasIDE(VisualStudioVersion.VisualStudio2022)) { format = ProjectFormat.VisualStudio2022; } else if (VisualStudioInstance.HasIDE(VisualStudioVersion.VisualStudio2019)) { format = ProjectFormat.VisualStudio2019; } else if (VisualStudioInstance.HasIDE(VisualStudioVersion.VisualStudio2017)) { format = ProjectFormat.VisualStudio2017; } else if (VisualStudioInstance.HasIDE(VisualStudioVersion.VisualStudio2015)) { format = ProjectFormat.VisualStudio2015; } else { Log.Warning("Failed to find default Visual Studio installation"); format = ProjectFormat.VisualStudio2015; } } switch (format) { case ProjectFormat.VisualStudio2015: case ProjectFormat.VisualStudio2017: case ProjectFormat.VisualStudio2019: case ProjectFormat.VisualStudio2022: { VisualStudioVersion vsVersion; switch (format) { case ProjectFormat.VisualStudio2015: vsVersion = VisualStudioVersion.VisualStudio2015; break; case ProjectFormat.VisualStudio2017: vsVersion = VisualStudioVersion.VisualStudio2017; break; case ProjectFormat.VisualStudio2019: vsVersion = VisualStudioVersion.VisualStudio2019; break; case ProjectFormat.VisualStudio2022: vsVersion = VisualStudioVersion.VisualStudio2022; break; default: throw new ArgumentOutOfRangeException(nameof(format), format, null); } switch (type) { case TargetType.NativeCpp: return new VCProjectGenerator(vsVersion); case TargetType.DotNet: return new CSProjectGenerator(vsVersion); default: throw new ArgumentOutOfRangeException(nameof(type), type, null); } } case ProjectFormat.VisualStudioCode: return type == TargetType.DotNet ? (ProjectGenerator)new CSProjectGenerator(VisualStudioVersion.VisualStudio2015) : (ProjectGenerator)new VisualStudioCodeProjectGenerator(); case ProjectFormat.XCode: return new XCodeProjectGenerator(); case ProjectFormat.Custom: if (CustomProjectTypes.TryGetValue(Configuration.ProjectFormatCustom, out var factory)) return factory(type); throw new Exception($"Unknown custom project format type '{Configuration.ProjectFormatCustom}'"); default: throw new ArgumentOutOfRangeException(nameof(format), "Unknown project format."); } } } }