From 2e61bcfbec911f0aa69f375dd00407e2fbf98d87 Mon Sep 17 00:00:00 2001 From: That_One_Nerd Date: Tue, 25 Apr 2023 17:27:14 -0400 Subject: [PATCH] Automated as much of the config system as possible. --- .../Shell/Extensions/ConversionExtension.cs | 13 +++ SrcMod/Shell/ObjectModels/Config.cs | 85 ++++++++++++++++--- SrcMod/Shell/Shell.csproj | 4 - 3 files changed, 88 insertions(+), 14 deletions(-) diff --git a/SrcMod/Shell/Extensions/ConversionExtension.cs b/SrcMod/Shell/Extensions/ConversionExtension.cs index 599c6ea..72a8e95 100644 --- a/SrcMod/Shell/Extensions/ConversionExtension.cs +++ b/SrcMod/Shell/Extensions/ConversionExtension.cs @@ -17,4 +17,17 @@ public static class ConversionExtension for (int i = 0; i < obj.Length; i++) result.SetValue(obj[i].Cast(), i); return (T[])result; } + + public static object CastArray(this Array obj, Type newElementType) + { + Array result = Array.CreateInstance(newElementType, obj.Length); + for (int i = 0; i < obj.Length; i++) result.SetValue(obj.GetValue(i)!.Cast(newElementType), i); + return result; + } + public static T[] CastArray(this Array obj) + { + Array result = Array.CreateInstance(typeof(T), obj.Length); + for (int i = 0; i < obj.Length; i++) result.SetValue(obj.GetValue(i)!.Cast(), i); + return (T[])result; + } } diff --git a/SrcMod/Shell/ObjectModels/Config.cs b/SrcMod/Shell/ObjectModels/Config.cs index 60d1e90..197b7e6 100644 --- a/SrcMod/Shell/ObjectModels/Config.cs +++ b/SrcMod/Shell/ObjectModels/Config.cs @@ -6,6 +6,9 @@ public class Config public static Config Defaults => new(); + private static readonly FieldInfo[] p_configSharedFields; + private static readonly FieldInfo[] p_changeSharedFields; + public static Config LoadedConfig { get => p_applied; @@ -22,6 +25,39 @@ public class Config static Config() { p_applied = Defaults; + + FieldInfo[] configFields = (from field in typeof(Config).GetFields() + let isPublic = field.IsPublic + let isStatic = field.IsStatic + where isPublic && !isStatic + select field).ToArray(), + changeFields = (from field in typeof(Changes).GetFields() + let isPublic = field.IsPublic + let isStatic = field.IsStatic + where isPublic && !isStatic + select field).ToArray(); + + List sharedConfigFields = new(), + sharedChangeFields = new(); + foreach (FieldInfo field in configFields) + { + FieldInfo? changeEquivalent = changeFields.FirstOrDefault( + x => x.Name == field.Name && + (x.FieldType == field.FieldType || Nullable.GetUnderlyingType(x.FieldType) == field.FieldType)); + + if (changeEquivalent is null) continue; + + sharedConfigFields.Add(field); + sharedChangeFields.Add(changeEquivalent); + } + + static int sortByName(FieldInfo a, FieldInfo b) => a.Name.CompareTo(b.Name); + + sharedConfigFields.Sort(sortByName); + sharedChangeFields.Sort(sortByName); + + p_configSharedFields = sharedConfigFields.ToArray(); + p_changeSharedFields = sharedChangeFields.ToArray(); } public string[] GameDirectories; @@ -35,22 +71,51 @@ public class Config public Config ApplyChanges(Changes changes) { - if (changes.GameDirectories is not null) - GameDirectories = GameDirectories.Union(changes.GameDirectories).ToArray(); + for (int i = 0; i < p_configSharedFields.Length; i++) + { + FieldInfo configField = p_configSharedFields[i], + changeField = p_changeSharedFields[i]; - if (changes.RunUnsafeCommands is not null) RunUnsafeCommands = changes.RunUnsafeCommands.Value; + object? toChange = changeField.GetValue(changes); + + if (toChange is null) continue; + + if (configField.FieldType.IsArray) + { + object[] currentArray = ((Array)configField.GetValue(this)!).CastArray(), + changeArray = ((Array)toChange).CastArray(); + + currentArray = currentArray.Union(changeArray).ToArray(); + configField.SetValue(this, currentArray.CastArray(configField.FieldType.GetElementType()!)); + } + else configField.SetValue(this, toChange); + } return this; } - public Changes GetChanges(Config? baseConfig = null) + public Changes GetChanges(Config? reference = null) { - Config reference = baseConfig ?? Defaults; - Changes changes = new() + reference ??= Defaults; + Changes changes = new(); + + for (int i = 0; i < p_configSharedFields.Length; i++) { - GameDirectories = reference.GameDirectories == GameDirectories ? null : - GameDirectories.Where(x => !reference.GameDirectories.Contains(x)).ToArray(), - RunUnsafeCommands = reference.RunUnsafeCommands == RunUnsafeCommands ? null : RunUnsafeCommands - }; + FieldInfo configField = p_configSharedFields[i], + changeField = p_changeSharedFields[i]; + + object? toSet = configField.GetValue(this); + + if (toSet is null) continue; + + if (configField.FieldType.IsArray) + { + object[] configArray = ((Array)toSet).CastArray(), + referenceArray = ((Array)configField.GetValue(Defaults)!).CastArray(), + changesArray = configArray.Where(x => !referenceArray.Contains(x)).ToArray(); + changeField.SetValue(changes, changesArray.CastArray(configField.FieldType.GetElementType()!)); + } + else changeField.SetValue(changes, toSet); + } return changes; } diff --git a/SrcMod/Shell/Shell.csproj b/SrcMod/Shell/Shell.csproj index 804ac4f..253835f 100644 --- a/SrcMod/Shell/Shell.csproj +++ b/SrcMod/Shell/Shell.csproj @@ -36,8 +36,4 @@ - - - -