From 2142f63a2d9105d204024d5b84a9c23a605cce4d Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Tue, 19 Nov 2019 14:11:52 +0100 Subject: [PATCH] allow override processors to be specified as well --- Contentless/Config.cs | 3 +- Contentless/OverrideInfo.cs | 17 ++++++++ Contentless/Program.cs | 74 +++++++++++++++++++++++++++-------- README.md | 5 ++- Test/Content/Content.mgcb | 35 ++++------------- Test/Content/Contentless.json | 3 +- 6 files changed, 90 insertions(+), 47 deletions(-) create mode 100644 Contentless/OverrideInfo.cs diff --git a/Contentless/Config.cs b/Contentless/Config.cs index 1acd7ed..82a1c45 100644 --- a/Contentless/Config.cs +++ b/Contentless/Config.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Contentless { public class Config { @@ -11,7 +12,7 @@ namespace Contentless { public bool LogSkipped = true; [JsonProperty(PropertyName = "overrides")] - public Dictionary Overrides = new Dictionary(); + public Dictionary Overrides = new Dictionary(); } } \ No newline at end of file diff --git a/Contentless/OverrideInfo.cs b/Contentless/OverrideInfo.cs new file mode 100644 index 0000000..eb7463e --- /dev/null +++ b/Contentless/OverrideInfo.cs @@ -0,0 +1,17 @@ +using System.Text.RegularExpressions; + +namespace Contentless { + public class OverrideInfo { + + public readonly Regex Regex; + public readonly string Importer; + public readonly string Processor; + + public OverrideInfo(Regex regex, string importer, string processor) { + this.Regex = regex; + this.Importer = importer; + this.Processor = processor; + } + + } +} \ No newline at end of file diff --git a/Contentless/Program.cs b/Contentless/Program.cs index 47d76be..dba3f9f 100644 --- a/Contentless/Program.cs +++ b/Contentless/Program.cs @@ -6,6 +6,7 @@ using System.Reflection; using System.Text.RegularExpressions; using Microsoft.Xna.Framework.Content.Pipeline; using Newtonsoft.Json; +using Newtonsoft.Json.Linq; namespace Contentless { public static class Program { @@ -41,7 +42,7 @@ namespace Contentless { Console.WriteLine("Using default config"); } var excluded = config.ExcludedFiles.Select(MakeFileRegex).ToArray(); - var overrides = config.Overrides.Select((e, i) => (MakeFileRegex(e.Key), e.Value)).ToArray(); + var overrides = GetOverrides(config.Overrides).ToArray(); // load any references to be able to include custom content types as well foreach (var line in content) { @@ -60,6 +61,8 @@ namespace Contentless { // load content importers var importers = GetContentImporters().ToArray(); Console.WriteLine($"Found possible importer types {string.Join(", ", importers.AsEnumerable())}"); + var processors = GetContentProcessors().ToArray(); + Console.WriteLine($"Found possible processor types {string.Join(", ", processors.AsEnumerable())}"); var changed = false; foreach (var file in contentFile.Directory.EnumerateFiles("*", SearchOption.AllDirectories)) { @@ -83,35 +86,46 @@ namespace Contentless { } ImporterInfo importer = null; + string processor = null; // override importers - var over = GetOverrideImporterFor(relative, overrides); + var over = GetOverrideFor(relative, overrides); if (over != null) { // copy special case - if (over == "Copy") { + if (over.Importer == "Copy") { CopyFile(content, relative); changed = true; continue; } - importer = Array.Find(importers, i => i.Type.Name == over); + importer = Array.Find(importers, i => i.Type.Name == over.Importer); if (importer == null) { - Console.WriteLine($"Override importer {over} not found for file {relative}"); + Console.WriteLine($"Override importer {over.Importer} not found for file {relative}"); continue; } + + if (over.Processor != null) { + processor = Array.Find(processors, p => p == over.Processor); + if (processor == null) { + Console.WriteLine($"Override processor {over.Processor} not found for file {relative}"); + continue; + } + } } // normal importers if (importer == null) importer = GetImporterFor(relative, importers); + if (processor == null) + processor = Array.Find(processors, p => p == importer.Importer.DefaultProcessor); // no importer found :( - if (importer == null) { - Console.WriteLine($"No importer found for file {relative}"); + if (importer == null || processor == null) { + Console.WriteLine($"No importer or processor found for file {relative}"); continue; } - AddFile(content, relative, importer); + AddFile(content, relative, importer, processor); changed = true; } @@ -136,10 +150,38 @@ namespace Contentless { } } - private static string GetOverrideImporterFor(string file, IEnumerable<(Regex, string)> overrides) { - foreach (var (regex, value) in overrides) { - if (regex.IsMatch(file)) - return value; + private static IEnumerable GetContentProcessors() { + foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { + foreach (var type in assembly.GetTypes()) { + var processor = type.GetCustomAttribute(typeof(ContentProcessorAttribute), true); + if (processor != null) + yield return type.Name; + } + } + } + + private static IEnumerable GetOverrides(Dictionary config) { + foreach (var entry in config) { + var regex = MakeFileRegex(entry.Key); + if (entry.Value.Type == JTokenType.Array) { + var arr = (JArray) entry.Value; + if (arr.Count != 2) { + Console.WriteLine("The override config " + entry.Key + " is invalid: The array needs to contain exactly two entries"); + } else { + yield return new OverrideInfo(regex, arr[0].ToString(), arr[1].ToString()); + } + } else if (entry.Value.Type == JTokenType.String) { + yield return new OverrideInfo(regex, entry.Value.ToString(), null); + } else { + Console.WriteLine("The override config " + entry.Key + " is invalid: Should be an array or a string"); + } + } + } + + private static OverrideInfo GetOverrideFor(string file, IEnumerable overrides) { + foreach (var over in overrides) { + if (over.Regex.IsMatch(file)) + return over; } return null; } @@ -172,13 +214,13 @@ namespace Contentless { return content; } - private static void AddFile(List content, string relative, ImporterInfo importer) { + private static void AddFile(List content, string relative, ImporterInfo importer, string processor) { content.Add($"#begin {relative}"); - content.Add($"/importer:{importer.Type.Name}"); - content.Add($"/processor:{importer.Importer.DefaultProcessor}"); + content.Add($"/importer:{importer}"); + content.Add($"/processor:{processor}"); content.Add($"/build:{relative}"); content.Add(""); - Console.WriteLine($"Adding file {relative} with importer {importer.Type.Name} and processor {importer.Importer.DefaultProcessor}"); + Console.WriteLine($"Adding file {relative} with importer {importer} and processor {processor}"); } private static void CopyFile(List content, string relative) { diff --git a/README.md b/README.md index ff1ab14..19bb0a3 100644 --- a/README.md +++ b/README.md @@ -31,12 +31,15 @@ To add a configuration file to Contentless, simply create a file named `Contentl // Default: true "logSkipped": true, // The list of files that should use a different importer than the one that Contentless automatically determined. Can use regex + // Specifying a string as the value represents an override importer, specifying an array with two entries represents the override importer and override processor // Default: {} "overrides": { // Example: Make all files matching the regex ".json" use the importer "JsonImporter" ".json": "JsonImporter", // Example: Specifying "Copy" as the importer sets the file's Build Mode to "Copy" instead of "Build" - ".txt": "Copy" + ".txt": "Copy", + // Example: Specifying both an importer and a processor + ".ogg": ["OggImporter", "SongProcessor"] } } ``` diff --git a/Test/Content/Content.mgcb b/Test/Content/Content.mgcb index 84e8263..6a74ba6 100644 --- a/Test/Content/Content.mgcb +++ b/Test/Content/Content.mgcb @@ -13,6 +13,13 @@ /reference:..\bin\Debug\netcoreapp2.2\MonoGame.Extended.Content.Pipeline.dll #---------------------------------- Content ---------------------------------# +#begin Json/Copy.json +/copy:Json/Copy.json + +#begin Json/Test.json +/importer:JsonContentImporter +/processor:FontTextureProcessor +/build:Json/Test.json #begin Locale/Interface.xml /importer:XmlImporter @@ -22,25 +29,11 @@ #begin Textures/Icons.png /importer:TextureImporter /processor:TextureProcessor -/processorParam:ColorKeyColor=255,0,255,255 -/processorParam:ColorKeyEnabled=True -/processorParam:GenerateMipmaps=False -/processorParam:PremultiplyAlpha=True -/processorParam:ResizeToPowerOfTwo=False -/processorParam:MakeSquare=False -/processorParam:TextureFormat=Color /build:Textures/Icons.png #begin Textures/Inside.png /importer:TextureImporter /processor:TextureProcessor -/processorParam:ColorKeyColor=255,0,255,255 -/processorParam:ColorKeyEnabled=True -/processorParam:GenerateMipmaps=False -/processorParam:PremultiplyAlpha=True -/processorParam:ResizeToPowerOfTwo=False -/processorParam:MakeSquare=False -/processorParam:TextureFormat=Color /build:Textures/Inside.png #begin Tiled/Map.tmx @@ -51,24 +44,10 @@ #begin Tiled/Tiles.png /importer:TextureImporter /processor:TextureProcessor -/processorParam:ColorKeyColor=255,0,255,255 -/processorParam:ColorKeyEnabled=True -/processorParam:GenerateMipmaps=False -/processorParam:PremultiplyAlpha=True -/processorParam:ResizeToPowerOfTwo=False -/processorParam:MakeSquare=False -/processorParam:TextureFormat=Color /build:Tiled/Tiles.png #begin Tiled/Tileset.tsx /importer:TiledMapTilesetImporter /processor:TiledMapTilesetProcessor /build:Tiled/Tileset.tsx -#begin Json/Copy.json -/copy:Json/Copy.json - -#begin Json/Test.json -/importer:JsonContentImporter -/processor:JsonContentProcessor -/build:Json/Test.json diff --git a/Test/Content/Contentless.json b/Test/Content/Contentless.json index b47fdf8..4288dad 100644 --- a/Test/Content/Contentless.json +++ b/Test/Content/Contentless.json @@ -7,6 +7,7 @@ "logSkipped": false, "overrides": { "Copy.*": "Copy", - ".json": "JsonContentImporter" + ".json": ["JsonContentImporter", "FontTextureProcessor"], + ".ogg": ["OggImporter", "SongProcessor"] } } \ No newline at end of file