解决 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(); psg?.Shutdown();
} }
public void SetState(Dictionary<string, dynamic> state) //public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state)
{ {
SaveStateHandler.PerformSetState(cartridge, state[nameof(cartridge)]); SaveStateHandler.PerformSetState(cartridge, (Dictionary<string, object>)state[nameof(cartridge)]);
wram = state[nameof(wram)]; wram = (byte[])state[nameof(wram)];
SaveStateHandler.PerformSetState(cpu, state[nameof(cpu)]); SaveStateHandler.PerformSetState(cpu, (Dictionary<string, object>)state[nameof(cpu)]);
SaveStateHandler.PerformSetState(vdp, state[nameof(vdp)]); SaveStateHandler.PerformSetState(vdp, (Dictionary<string, object>)state[nameof(vdp)]);
SaveStateHandler.PerformSetState(psg, state[nameof(psg)]); SaveStateHandler.PerformSetState(psg, (Dictionary<string, object>)state[nameof(psg)]);
portControls1 = state[nameof(portControls1)]; portControls1 = (ushort)state[nameof(portControls1)];
portControls2 = state[nameof(portControls2)]; portControls2 = (ushort)state[nameof(portControls2)];
controlsReadMode = state[nameof(controlsReadMode)]; controlsReadMode = (byte)state[nameof(controlsReadMode)];
isNmi = state[nameof(isNmi)]; isNmi = (bool)state[nameof(isNmi)];
isNmiPending = state[nameof(isNmiPending)]; isNmiPending = (bool)state[nameof(isNmiPending)];
ReconfigureSystem(); ReconfigureSystem();
} }

View File

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

View File

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

View File

@ -246,18 +246,18 @@ namespace Essgee.Emulation.Machines
psg?.Shutdown(); psg?.Shutdown();
} }
public void SetState(Dictionary<string, dynamic> state) //public void SetState(Dictionary<string, dynamic> state)
public void SetState(Dictionary<string, object> state)
{ {
configuration.TVStandard = state[nameof(configuration.TVStandard)]; 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(ppi, state[nameof(ppi)]);
keyboard = state[nameof(keyboard)];
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(); ReconfigureSystem();
} }

View File

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

View File

@ -102,7 +102,9 @@ namespace Essgee.Emulation
return machineId.Substring(0, Math.Min(machineId.Length, 16)).PadRight(16); 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) if (obj != null)
{ {
@ -120,9 +122,11 @@ namespace Essgee.Emulation
} }
} }
public static Dictionary<string, dynamic> PerformGetState(object obj) //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, dynamic>();
var state = new Dictionary<string, object>();
if (obj != null) if (obj != null)
{ {

View File

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