Nerfed/Nerfed.Builder/Builder/Builder.cs

120 lines
4.1 KiB
C#
Raw Normal View History

2024-07-06 23:33:04 +02:00
using System.Diagnostics;
namespace Nerfed.Builder;
public class Builder : IDisposable
{
private readonly Dictionary<string, IImporter> importers = new Dictionary<string, IImporter>();
private readonly RawFileImporter rawFileImporter;
public Builder()
{
rawFileImporter = new RawFileImporter();
ShaderImporter shaderImporter = new ShaderImporter();
importers.Add(".vert", shaderImporter); // Vertex shader
importers.Add(".frag", shaderImporter); // Fragment shader
importers.Add(".tesc", shaderImporter); // Tessellation control shader
importers.Add(".tese", shaderImporter); // Tessellation evaluation shader
importers.Add(".geom", shaderImporter); // Geometry shader
importers.Add(".comp", shaderImporter); // Compute shader
}
public void Run(BuildArgs args)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
List<string> contentFiles = args.ContentFiles;
string absContentPath = $"{args.ProjectPath}/{PathUtil.ContentFolderName}";
// If no files are provided, build all content.
if (args.ContentFiles == null)
{
contentFiles = [];
CollectAssetFiles(absContentPath, absContentPath, ref contentFiles);
}
string importPath = $"{args.ProjectPath}/{PathUtil.ImportFolderName}";
ParallelOptions parallelOptions = new ParallelOptions
{
MaxDegreeOfParallelism = contentFiles.Count
};
Parallel.ForEach(contentFiles, parallelOptions, relativeFile =>
{
try
{
string inFile = $"{args.ProjectPath}/{PathUtil.ContentFolderName}/{relativeFile}";
if (!File.Exists(inFile))
{
Console.Error.WriteLine($"Asset file '{relativeFile}' not found");
return;
}
string outFile = $"{importPath}/{relativeFile}{PathUtil.ImportedFileExtension}";
FileInfo inFileInfo = new FileInfo(inFile);
FileInfo outFileInfo = new FileInfo(outFile);
if (!FileUtil.IsNewer(inFileInfo, outFileInfo))
{
// File has not changed since last build, no need to build this one.
return;
}
string outDir = Path.GetDirectoryName(outFile);
if (!Directory.Exists(outDir))
{
Directory.CreateDirectory(outDir);
}
string ext = Path.GetExtension(inFile).ToLower();
if (importers.TryGetValue(ext, out IImporter importer))
{
importer.Import(inFile, outFile);
}
else
{
rawFileImporter.Import(inFile, outFile);
}
Console.WriteLine(relativeFile);
}
catch (Exception e)
{
Console.Error.WriteLine($"Import error on asset '{relativeFile}': {e.Message}");
}
});
Console.WriteLine($"Build content completed in {stopwatch.Elapsed.TotalSeconds:F2} seconds");
}
private void CollectAssetFiles(string assetDir, string dir, ref List<string> files)
{
foreach (string file in Directory.EnumerateFiles(dir))
{
if (Path.GetExtension(file).Equals(PathUtil.ImportFileExtension, StringComparison.CurrentCultureIgnoreCase))
{
continue;
}
string relativeFile = file.Substring(assetDir.Length, file.Length - assetDir.Length);
if (relativeFile[0] == Path.DirectorySeparatorChar || relativeFile[0] == Path.AltDirectorySeparatorChar)
{
relativeFile = relativeFile.Substring(1, relativeFile.Length - 1);
}
files.Add(relativeFile);
}
foreach (string subDir in Directory.EnumerateDirectories(dir))
{
CollectAssetFiles(assetDir, subDir, ref files);
}
}
public void Dispose() { }
}