解决 Dictionary<string, dynamic> 不支持的问题

This commit is contained in:
sin365 2025-01-02 18:23:32 +08:00
parent ef83021d9b
commit 11423c9bf2
7 changed files with 200 additions and 192 deletions

View File

@ -218,19 +218,20 @@ namespace Essgee.Emulation.Machines
psg?.Shutdown();
}
public void SetState(Dictionary<string, dynamic> state)
{
SaveStateHandler.PerformSetState(cartridge, state[nameof(cartridge)]);
wram = state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, state[nameof(psg)]);
//public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state)
{
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
portControls1 = state[nameof(portControls1)];
portControls2 = state[nameof(portControls2)];
controlsReadMode = state[nameof(controlsReadMode)];
isNmi = state[nameof(isNmi)];
isNmiPending = state[nameof(isNmiPending)];
portControls1 = (ushort)state[nameof(portControls1)];
portControls2 = (ushort)state[nameof(portControls2)];
controlsReadMode = (byte)state[nameof(controlsReadMode)];
isNmi = (bool)state[nameof(isNmi)];
isNmiPending = (bool)state[nameof(isNmiPending)];
ReconfigureSystem();
}

View File

@ -242,29 +242,30 @@ namespace Essgee.Emulation.Machines
psg?.Shutdown();
}
public void SetState(Dictionary<string, dynamic> state)
{
configuration.Region = state[nameof(configuration.Region)];
//public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state)
{
configuration.Region = (Region)state[nameof(configuration.Region)];
SaveStateHandler.PerformSetState(bootstrap, state[nameof(bootstrap)]);
SaveStateHandler.PerformSetState(cartridge, state[nameof(cartridge)]);
wram = state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, state[nameof(psg)]);
SaveStateHandler.PerformSetState(bootstrap, (Dictionary<string, object>)state[nameof(bootstrap)]);
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
portMemoryControl = state[nameof(portMemoryControl)];
portIoControl = state[nameof(portIoControl)];
hCounterLatched = state[nameof(hCounterLatched)];
portIoAB = state[nameof(portIoAB)];
portIoBMisc = state[nameof(portIoBMisc)];
portMemoryControl = (byte)state[nameof(portMemoryControl)];
portIoControl = (byte)state[nameof(portIoControl)];
hCounterLatched = (byte)state[nameof(hCounterLatched)];
portIoAB = (byte)state[nameof(portIoAB)];
portIoBMisc = (byte)state[nameof(portIoBMisc)];
portIoC = state[nameof(portIoC)];
portParallelData = state[nameof(portParallelData)];
portDataDirNMI = state[nameof(portDataDirNMI)];
portTxBuffer = state[nameof(portTxBuffer)];
portRxBuffer = state[nameof(portRxBuffer)];
portSerialControl = state[nameof(portSerialControl)];
portIoC = (byte)state[nameof(portIoC)];
portParallelData = (byte)state[nameof(portParallelData)];
portDataDirNMI = (byte)state[nameof(portDataDirNMI)];
portTxBuffer = (byte)state[nameof(portTxBuffer)];
portRxBuffer = (byte)state[nameof(portRxBuffer)];
portSerialControl = (byte)state[nameof(portSerialControl)];
ReconfigureSystem();
}

View File

@ -263,24 +263,25 @@ namespace Essgee.Emulation.Machines
psg?.Shutdown();
}
public void SetState(Dictionary<string, dynamic> state)
{
configuration.TVStandard = state[nameof(configuration.TVStandard)];
configuration.Region = state[nameof(configuration.Region)];
//public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state)
{
configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)];
configuration.Region = (Region)state[nameof(configuration.Region)];
SaveStateHandler.PerformSetState(bootstrap, state[nameof(bootstrap)]);
SaveStateHandler.PerformSetState(cartridge, state[nameof(cartridge)]);
wram = state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, state[nameof(psg)]);
SaveStateHandler.PerformSetState(bootstrap, (Dictionary<string, object>)state[nameof(bootstrap)]);
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
inputDevices = state[nameof(inputDevices)];
lightgunLatched = state[nameof(lightgunLatched)];
inputDevices = (InputDevice[])state[nameof(inputDevices)];
lightgunLatched = (bool)state[nameof(lightgunLatched)];
portMemoryControl = state[nameof(portMemoryControl)];
portIoControl = state[nameof(portIoControl)];
hCounterLatched = state[nameof(hCounterLatched)];
portMemoryControl = (byte)state[nameof(portMemoryControl)];
portIoControl = (byte)state[nameof(portIoControl)];
hCounterLatched = (byte)state[nameof(hCounterLatched)];
ReconfigureSystem();
}

View File

@ -246,18 +246,18 @@ namespace Essgee.Emulation.Machines
psg?.Shutdown();
}
public void SetState(Dictionary<string, dynamic> state)
{
configuration.TVStandard = state[nameof(configuration.TVStandard)];
SaveStateHandler.PerformSetState(cartridge, state[nameof(cartridge)]);
wram = state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, state[nameof(psg)]);
SaveStateHandler.PerformSetState(ppi, state[nameof(ppi)]);
keyboard = state[nameof(keyboard)];
//public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state)
{
configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)];
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
SaveStateHandler.PerformSetState(ppi, (Dictionary<string, object>)state[nameof(ppi)]);
keyboard = (bool[,])(state[nameof(keyboard)]);
ReconfigureSystem();
}

View File

@ -221,15 +221,16 @@ namespace Essgee.Emulation.Machines
psg?.Shutdown();
}
public void SetState(Dictionary<string, dynamic> state)
{
configuration.TVStandard = state[nameof(configuration.TVStandard)];
//public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state)
{
configuration.TVStandard = (TVStandard)state[nameof(configuration.TVStandard)];
SaveStateHandler.PerformSetState(cartridge, state[nameof(cartridge)]);
wram = state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, state[nameof(psg)]);
SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
wram = (byte[])state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
ReconfigureSystem();
}

View File

@ -102,8 +102,10 @@ namespace Essgee.Emulation
return machineId.Substring(0, Math.Min(machineId.Length, 16)).PadRight(16);
}
public static void PerformSetState(object obj, Dictionary<string, dynamic> state)
{
//public static void PerformSetState(object obj, Dictionary<string, dynamic> state)
public static void PerformSetState(object obj, Dictionary<string, object> state)
{
if (obj != null)
{
/* Restore property values from state */
@ -120,11 +122,13 @@ namespace Essgee.Emulation
}
}
public static Dictionary<string, dynamic> PerformGetState(object obj)
{
var state = new Dictionary<string, dynamic>();
//public static Dictionary<string, dynamic> PerformGetState(object obj)
public static Dictionary<string, object> PerformGetState(object obj)
{
//var state = new Dictionary<string, dynamic>();
var state = new Dictionary<string, object>();
if (obj != null)
if (obj != null)
{
/* Copy property values to state */
foreach (var prop in obj.GetType().GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance).Where(x => x.GetCustomAttributes(typeof(StateRequiredAttribute), false).Length != 0))

View File

@ -1,140 +1,140 @@
using System;
using System.Reflection;
using System.Reflection.Emit;
//using System;
//using System.Reflection;
//using System.Reflection.Emit;
namespace Essgee.Graphics
{
/* http://www.codeproject.com/Articles/14593/A-General-Fast-Method-Invoker */
//namespace Essgee.Graphics
//{
// /* http://www.codeproject.com/Articles/14593/A-General-Fast-Method-Invoker */
internal delegate object FastInvokeHandler(object target, object[] paramters);
// internal delegate object FastInvokeHandler(object target, object[] paramters);
internal class FastMethodInvoker
{
public static FastInvokeHandler GetMethodInvoker(MethodInfo methodInfo)
{
DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);
// internal class FastMethodInvoker
// {
// public static FastInvokeHandler GetMethodInvoker(MethodInfo methodInfo)
// {
// DynamicMethod dynamicMethod = new DynamicMethod(string.Empty, typeof(object), new Type[] { typeof(object), typeof(object[]) }, methodInfo.DeclaringType.Module);
ILGenerator il = dynamicMethod.GetILGenerator();
ParameterInfo[] ps = methodInfo.GetParameters();
// ILGenerator il = dynamicMethod.GetILGenerator();
// ParameterInfo[] ps = methodInfo.GetParameters();
Type[] paramTypes = new Type[ps.Length];
for (int i = 0; i < paramTypes.Length; i++)
{
if (ps[i].ParameterType.IsByRef)
paramTypes[i] = ps[i].ParameterType.GetElementType();
else
paramTypes[i] = ps[i].ParameterType;
}
// Type[] paramTypes = new Type[ps.Length];
// for (int i = 0; i < paramTypes.Length; i++)
// {
// if (ps[i].ParameterType.IsByRef)
// paramTypes[i] = ps[i].ParameterType.GetElementType();
// else
// paramTypes[i] = ps[i].ParameterType;
// }
LocalBuilder[] locals = new LocalBuilder[paramTypes.Length];
for (int i = 0; i < paramTypes.Length; i++)
locals[i] = il.DeclareLocal(paramTypes[i], true);
// LocalBuilder[] locals = new LocalBuilder[paramTypes.Length];
// for (int i = 0; i < paramTypes.Length; i++)
// locals[i] = il.DeclareLocal(paramTypes[i], true);
for (int i = 0; i < paramTypes.Length; i++)
{
il.Emit(OpCodes.Ldarg_1);
EmitFastInt(il, i);
il.Emit(OpCodes.Ldelem_Ref);
EmitCastToReference(il, paramTypes[i]);
il.Emit(OpCodes.Stloc, locals[i]);
}
// for (int i = 0; i < paramTypes.Length; i++)
// {
// il.Emit(OpCodes.Ldarg_1);
// EmitFastInt(il, i);
// il.Emit(OpCodes.Ldelem_Ref);
// EmitCastToReference(il, paramTypes[i]);
// il.Emit(OpCodes.Stloc, locals[i]);
// }
if (!methodInfo.IsStatic)
il.Emit(OpCodes.Ldarg_0);
// if (!methodInfo.IsStatic)
// il.Emit(OpCodes.Ldarg_0);
for (int i = 0; i < paramTypes.Length; i++)
{
if (ps[i].ParameterType.IsByRef)
il.Emit(OpCodes.Ldloca_S, locals[i]);
else
il.Emit(OpCodes.Ldloc, locals[i]);
}
// for (int i = 0; i < paramTypes.Length; i++)
// {
// if (ps[i].ParameterType.IsByRef)
// il.Emit(OpCodes.Ldloca_S, locals[i]);
// else
// il.Emit(OpCodes.Ldloc, locals[i]);
// }
if (methodInfo.IsStatic)
il.EmitCall(OpCodes.Call, methodInfo, null);
else
il.EmitCall(OpCodes.Callvirt, methodInfo, null);
// if (methodInfo.IsStatic)
// il.EmitCall(OpCodes.Call, methodInfo, null);
// else
// il.EmitCall(OpCodes.Callvirt, methodInfo, null);
if (methodInfo.ReturnType == typeof(void))
il.Emit(OpCodes.Ldnull);
else
EmitBoxIfNeeded(il, methodInfo.ReturnType);
// if (methodInfo.ReturnType == typeof(void))
// il.Emit(OpCodes.Ldnull);
// else
// EmitBoxIfNeeded(il, methodInfo.ReturnType);
for (int i = 0; i < paramTypes.Length; i++)
{
if (ps[i].ParameterType.IsByRef)
{
il.Emit(OpCodes.Ldarg_1);
EmitFastInt(il, i);
il.Emit(OpCodes.Ldloc, locals[i]);
// for (int i = 0; i < paramTypes.Length; i++)
// {
// if (ps[i].ParameterType.IsByRef)
// {
// il.Emit(OpCodes.Ldarg_1);
// EmitFastInt(il, i);
// il.Emit(OpCodes.Ldloc, locals[i]);
if (locals[i].LocalType.IsValueType)
il.Emit(OpCodes.Box, locals[i].LocalType);
// if (locals[i].LocalType.IsValueType)
// il.Emit(OpCodes.Box, locals[i].LocalType);
il.Emit(OpCodes.Stelem_Ref);
}
}
// il.Emit(OpCodes.Stelem_Ref);
// }
// }
il.Emit(OpCodes.Ret);
// il.Emit(OpCodes.Ret);
FastInvokeHandler invoder = (FastInvokeHandler)dynamicMethod.CreateDelegate(typeof(FastInvokeHandler));
return invoder;
}
// FastInvokeHandler invoder = (FastInvokeHandler)dynamicMethod.CreateDelegate(typeof(FastInvokeHandler));
// return invoder;
// }
private static void EmitCastToReference(ILGenerator il, Type type)
{
if (type.IsValueType)
il.Emit(OpCodes.Unbox_Any, type);
else
il.Emit(OpCodes.Castclass, type);
}
// private static void EmitCastToReference(ILGenerator il, Type type)
// {
// if (type.IsValueType)
// il.Emit(OpCodes.Unbox_Any, type);
// else
// il.Emit(OpCodes.Castclass, type);
// }
private static void EmitBoxIfNeeded(ILGenerator il, Type type)
{
if (type.IsValueType)
il.Emit(OpCodes.Box, type);
}
// private static void EmitBoxIfNeeded(ILGenerator il, Type type)
// {
// if (type.IsValueType)
// il.Emit(OpCodes.Box, type);
// }
private static void EmitFastInt(ILGenerator il, int value)
{
switch (value)
{
case -1:
il.Emit(OpCodes.Ldc_I4_M1);
return;
case 0:
il.Emit(OpCodes.Ldc_I4_0);
return;
case 1:
il.Emit(OpCodes.Ldc_I4_1);
return;
case 2:
il.Emit(OpCodes.Ldc_I4_2);
return;
case 3:
il.Emit(OpCodes.Ldc_I4_3);
return;
case 4:
il.Emit(OpCodes.Ldc_I4_4);
return;
case 5:
il.Emit(OpCodes.Ldc_I4_5);
return;
case 6:
il.Emit(OpCodes.Ldc_I4_6);
return;
case 7:
il.Emit(OpCodes.Ldc_I4_7);
return;
case 8:
il.Emit(OpCodes.Ldc_I4_8);
return;
}
// private static void EmitFastInt(ILGenerator il, int value)
// {
// switch (value)
// {
// case -1:
// il.Emit(OpCodes.Ldc_I4_M1);
// return;
// case 0:
// il.Emit(OpCodes.Ldc_I4_0);
// return;
// case 1:
// il.Emit(OpCodes.Ldc_I4_1);
// return;
// case 2:
// il.Emit(OpCodes.Ldc_I4_2);
// return;
// case 3:
// il.Emit(OpCodes.Ldc_I4_3);
// return;
// case 4:
// il.Emit(OpCodes.Ldc_I4_4);
// return;
// case 5:
// il.Emit(OpCodes.Ldc_I4_5);
// return;
// case 6:
// il.Emit(OpCodes.Ldc_I4_6);
// return;
// case 7:
// il.Emit(OpCodes.Ldc_I4_7);
// return;
// case 8:
// il.Emit(OpCodes.Ldc_I4_8);
// return;
// }
if (value > -129 && value < 128)
il.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
else
il.Emit(OpCodes.Ldc_I4, value);
}
}
}
// if (value > -129 && value < 128)
// il.Emit(OpCodes.Ldc_I4_S, (sbyte)value);
// else
// il.Emit(OpCodes.Ldc_I4, value);
// }
// }
//}