Automated as much of the config system as possible.

This commit is contained in:
That_One_Nerd 2023-04-25 17:27:14 -04:00
parent 6f65417fe7
commit 2e61bcfbec
3 changed files with 88 additions and 14 deletions

View File

@ -17,4 +17,17 @@ public static class ConversionExtension
for (int i = 0; i < obj.Length; i++) result.SetValue(obj[i].Cast<T>(), i); for (int i = 0; i < obj.Length; i++) result.SetValue(obj[i].Cast<T>(), i);
return (T[])result; 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<T>(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<T>(), i);
return (T[])result;
}
} }

View File

@ -6,6 +6,9 @@ public class Config
public static Config Defaults => new(); public static Config Defaults => new();
private static readonly FieldInfo[] p_configSharedFields;
private static readonly FieldInfo[] p_changeSharedFields;
public static Config LoadedConfig public static Config LoadedConfig
{ {
get => p_applied; get => p_applied;
@ -22,6 +25,39 @@ public class Config
static Config() static Config()
{ {
p_applied = Defaults; 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<FieldInfo> 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; public string[] GameDirectories;
@ -35,22 +71,51 @@ public class Config
public Config ApplyChanges(Changes changes) public Config ApplyChanges(Changes changes)
{ {
if (changes.GameDirectories is not null) for (int i = 0; i < p_configSharedFields.Length; i++)
GameDirectories = GameDirectories.Union(changes.GameDirectories).ToArray(); {
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<object>(),
changeArray = ((Array)toChange).CastArray<object>();
currentArray = currentArray.Union(changeArray).ToArray();
configField.SetValue(this, currentArray.CastArray(configField.FieldType.GetElementType()!));
}
else configField.SetValue(this, toChange);
}
return this; return this;
} }
public Changes GetChanges(Config? baseConfig = null) public Changes GetChanges(Config? reference = null)
{ {
Config reference = baseConfig ?? Defaults; reference ??= Defaults;
Changes changes = new() Changes changes = new();
for (int i = 0; i < p_configSharedFields.Length; i++)
{ {
GameDirectories = reference.GameDirectories == GameDirectories ? null : FieldInfo configField = p_configSharedFields[i],
GameDirectories.Where(x => !reference.GameDirectories.Contains(x)).ToArray(), changeField = p_changeSharedFields[i];
RunUnsafeCommands = reference.RunUnsafeCommands == RunUnsafeCommands ? null : RunUnsafeCommands
}; object? toSet = configField.GetValue(this);
if (toSet is null) continue;
if (configField.FieldType.IsArray)
{
object[] configArray = ((Array)toSet).CastArray<object>(),
referenceArray = ((Array)configField.GetValue(Defaults)!).CastArray<object>(),
changesArray = configArray.Where(x => !referenceArray.Contains(x)).ToArray();
changeField.SetValue(changes, changesArray.CastArray(configField.FieldType.GetElementType()!));
}
else changeField.SetValue(changes, toSet);
}
return changes; return changes;
} }

View File

@ -36,8 +36,4 @@
<PackageReference Include="SharpCompress" Version="0.33.0" /> <PackageReference Include="SharpCompress" Version="0.33.0" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<Folder Include="NewFolder\" />
</ItemGroup>
</Project> </Project>