mirror of
https://github.com/All-Of-Us-Mods/MiraAPI.git
synced 2026-10-19 15:51:48 +00:00
field support
This commit is contained in:
3 files changed
+95
-11
No files matched your search
@@ -38,7 +38,7 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
|
||||
var flags = BindingFlags.Static | BindingFlags.Public;
|
||||
|
||||
type = holderType ?? groupType;
|
||||
MemberName ??= $"{property.Name}{defaultSuffix}";
|
||||
MemberName ??= property.Name + defaultSuffix;
|
||||
|
||||
if (type.IsAssignableTo(typeof(AbstractOptionGroup)))
|
||||
{
|
||||
@@ -59,13 +59,24 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
|
||||
|
||||
var member = type.GetMember(MemberName, flags).FirstOrDefault();
|
||||
|
||||
if (instanceGetter != null)
|
||||
if (instanceGetter == null)
|
||||
return member;
|
||||
|
||||
bool isStatic;
|
||||
|
||||
if (member is FieldInfo field)
|
||||
{
|
||||
isStatic = field.IsStatic;
|
||||
}
|
||||
else
|
||||
{
|
||||
var method = (member as PropertyInfo)?.GetGetMethod(true) ?? member as MethodInfo;
|
||||
if (method is { IsStatic: true })
|
||||
instanceGetter = null;
|
||||
isStatic = method is { IsStatic: true };
|
||||
}
|
||||
|
||||
if (isStatic)
|
||||
instanceGetter = null;
|
||||
|
||||
return member;
|
||||
}
|
||||
|
||||
@@ -186,8 +197,8 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
|
||||
baseParamTypes,
|
||||
delegateType,
|
||||
suffix,
|
||||
forwardParameters: baseParamTypes.Length > 0,
|
||||
postProcessCall: postProcessCall);
|
||||
baseParamTypes.Length > 0,
|
||||
postProcessCall);
|
||||
|
||||
return _ => sharedDelegate;
|
||||
}
|
||||
@@ -202,11 +213,16 @@ public abstract class ModdedOptionMemberAttribute(string? memberName, Type? hold
|
||||
|
||||
for (byte i = 0; i < baseParamTypes.Length; i++)
|
||||
{
|
||||
if (i == 0) il.Emit(OpCodes.Ldarg_0);
|
||||
else if (i == 1) il.Emit(OpCodes.Ldarg_1);
|
||||
else if (i == 2) il.Emit(OpCodes.Ldarg_2);
|
||||
else if (i == 3) il.Emit(OpCodes.Ldarg_3);
|
||||
else il.Emit(OpCodes.Ldarg_S, i);
|
||||
if (i == 0)
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
else if (i == 1)
|
||||
il.Emit(OpCodes.Ldarg_1);
|
||||
else if (i == 2)
|
||||
il.Emit(OpCodes.Ldarg_2);
|
||||
else if (i == 3)
|
||||
il.Emit(OpCodes.Ldarg_3);
|
||||
else
|
||||
il.Emit(OpCodes.Ldarg_S, i);
|
||||
}
|
||||
|
||||
if (hasIndexParameter)
|
||||
|
||||
@@ -71,6 +71,32 @@ public sealed class ModdedOptionVisibilityAttribute(string? memberName = null, T
|
||||
|
||||
targetMethod = vMethod;
|
||||
}
|
||||
else if (member is FieldInfo field)
|
||||
{
|
||||
if (field.FieldType != typeof(bool))
|
||||
{
|
||||
Error($"Field {MemberName} is not a bool.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var dynamicMethod = new DynamicMethod($"GetVisibility_{type.Name}_{field.Name}", typeof(bool), Type.EmptyTypes, type, true);
|
||||
|
||||
var il = dynamicMethod.GetILGenerator();
|
||||
|
||||
if (instanceGetter != null)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Call, instanceGetter);
|
||||
il.Emit(OpCodes.Ldfld, field);
|
||||
}
|
||||
else
|
||||
{
|
||||
il.Emit(OpCodes.Ldsfld, field);
|
||||
}
|
||||
|
||||
il.Emit(OpCodes.Ret);
|
||||
return dynamicMethod.CreateDelegate<Func<bool>>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Error($"Member {MemberName} of {type.FullName} is not valid for Visible function.");
|
||||
@@ -118,6 +144,7 @@ public sealed class ModdedOptionVisibilityAttribute(string? memberName = null, T
|
||||
}
|
||||
|
||||
var indexParams = vProperty.GetIndexParameters();
|
||||
|
||||
if (indexParams.Length > 1)
|
||||
{
|
||||
Error($"Indexer {MemberName} has too many parameters.");
|
||||
@@ -178,6 +205,43 @@ public sealed class ModdedOptionVisibilityAttribute(string? memberName = null, T
|
||||
|
||||
targetMethod = vMethod;
|
||||
}
|
||||
else if (member is FieldInfo field)
|
||||
{
|
||||
if (field.FieldType.IsAssignableTo(typeof(IList<bool>)))
|
||||
{
|
||||
postProcess = il =>
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Callvirt, ListBoolIndexerGetter);
|
||||
};
|
||||
}
|
||||
else if (field.FieldType != typeof(bool))
|
||||
{
|
||||
Error($"Field {MemberName} is not a bool or a list of bools.");
|
||||
return null;
|
||||
}
|
||||
|
||||
var dynamicMethod = new DynamicMethod($"GetListVisibility_{type.Name}_{field.Name}", typeof(bool), [typeof(int)], type, true);
|
||||
var il = dynamicMethod.GetILGenerator();
|
||||
|
||||
if (instanceGetter != null)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Call, instanceGetter);
|
||||
il.Emit(OpCodes.Ldfld, field);
|
||||
}
|
||||
else
|
||||
{
|
||||
il.Emit(OpCodes.Ldsfld, field);
|
||||
}
|
||||
|
||||
postProcess?.Invoke(il);
|
||||
|
||||
il.Emit(OpCodes.Ret);
|
||||
|
||||
var func = dynamicMethod.CreateDelegate<Func<int, bool>>();
|
||||
return index => () => func(index);
|
||||
}
|
||||
else
|
||||
{
|
||||
Error($"Member {MemberName} of {type.FullName} is not valid for Visibility function.");
|
||||
|
||||
@@ -52,6 +52,10 @@ public class ModdedEnumOption : ModdedOption<int>
|
||||
stringOption.SetUpFromData(Data, 20);
|
||||
stringOption.OnValueChanged = (Il2CppSystem.Action<OptionBehaviour>)ValueChanged;
|
||||
|
||||
// Changing the button text to make them more distinct from number options
|
||||
stringOption.MinusBtn.ChangeButtonText("<");
|
||||
stringOption.PlusBtn.ChangeButtonText(">");
|
||||
|
||||
// SetUpFromData method doesn't work correctly so we must set the values manually
|
||||
stringOption.Title = StringName;
|
||||
stringOption.Values = (Data as StringGameSetting)?.Values ?? new Il2CppStructArray<StringNames>(0);
|
||||
|
||||
Reference in new issue
Block a user