// Copyright (c) 2012-2023 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, string solutionPath);
///
/// 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);
case TargetType.DotNetCore: return new CSSDKProjectGenerator(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.");
}
}
}
}