using System.Diagnostics; namespace Nerfed.Builder; public class Builder : IDisposable { private readonly Dictionary importers = new Dictionary(); private readonly RawFileImporter rawFileImporter; public Builder() { rawFileImporter = new RawFileImporter(); importers.Add(".vert", new ShaderImporter(ShaderStage.Vertex)); // Vertex shader importers.Add(".frag", new ShaderImporter(ShaderStage.Fragment)); // 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(); //CopyLibs(args.ResourcePath); List contentFiles = args.ResourceFiles; // If no files are provided, build all content. if (args.ResourceFiles == null) { contentFiles = []; CollectAssetFiles(args.ResourcePath, args.ResourcePath, ref contentFiles); } if (contentFiles.Count > 0) { ParallelOptions parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = contentFiles.Count }; Parallel.ForEach(contentFiles, parallelOptions, relativeFile => { try { string inFile = $"{args.ResourcePath}/{relativeFile}"; if (!File.Exists(inFile)) { Console.Error.WriteLine($"Asset file '{relativeFile}' not found"); return; } string outFile = $"{args.ResourceOutPath}/{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 CopyLibs(string projectPath) { string libDir = $"{AppDomain.CurrentDomain.BaseDirectory}/../../Native/"; if (OperatingSystem.IsWindows()) { libDir += "x64"; } else if (OperatingSystem.IsLinux()) { libDir += "lib64"; } else if (OperatingSystem.IsMacOS()) { libDir += "osx"; } libDir = Path.GetFullPath(libDir); foreach (string libFile in Directory.EnumerateFiles(libDir)) { FileInfo srcFileInfo = new FileInfo(libFile); FileInfo dstFileInfo = new FileInfo($"{projectPath}/{PathUtil.BuildFolderName}/{Path.GetFileName(libFile)}"); if (FileUtil.IsNewer(srcFileInfo, dstFileInfo)) { FileUtil.Copy(srcFileInfo, dstFileInfo); } } }*/ private void CollectAssetFiles(string assetDir, string dir, ref List files) { foreach (string file in Directory.EnumerateFiles(dir)) { 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() { } }