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);
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();
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<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;
@ -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<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;
}
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<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;
}

View File

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