Automated as much of the config system as possible.
This commit is contained in:
parent
6f65417fe7
commit
2e61bcfbec
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user