11using System ;
22using System . Collections . Generic ;
33using System . Linq ;
4+ using System . Reflection ;
45using HarmonyLib ;
56using Mono . Cecil . Cil ;
67using MonoMod . Utils ;
@@ -9,22 +10,10 @@ namespace APIPlugin
910{
1011 [ AttributeUsage ( AttributeTargets . Field ) ]
1112 public class IgnoreMappingAttribute : Attribute { }
12- public static unsafe class TypeMapper < S , D > where S : class where D : class , new ( )
13+ public static class TypeMapper < S , D > where S : class where D : class
1314 {
14- private struct GetFieldDelegate
15- {
16- public delegate * < S , object > Del ;
17- public Type FieldType ;
18- }
19-
20- private struct SetFieldDelegate
21- {
22- public delegate * < D , object , void > Del ;
23- public Type FieldType ;
24- }
25-
26- private static Dictionary < string , GetFieldDelegate > _accessors = null ;
27- private static Dictionary < string , GetFieldDelegate > FieldAccessors
15+ private static Dictionary < string , MethodInfo > _accessors = null ;
16+ private static Dictionary < string , MethodInfo > FieldAccessors
2817 {
2918 get
3019 {
@@ -39,21 +28,17 @@ private static Dictionary<string, GetFieldDelegate> FieldAccessors
3928 il . Emit ( OpCodes . Ldarg_0 ) ;
4029 il . Emit ( OpCodes . Ldfld , accessor . Module . ImportReference ( field ) ) ;
4130 if ( field . FieldType . IsValueType )
42- il . Emit ( OpCodes . Box ) ;
31+ il . Emit ( OpCodes . Box , field . FieldType ) ;
4332 il . Emit ( OpCodes . Ret ) ;
44- _accessors . Add ( field . Name , new GetFieldDelegate
45- {
46- Del = ( delegate * < S , object > ) accessor . Generate ( ) . MethodHandle . GetFunctionPointer ( ) ,
47- FieldType = field . FieldType
48- } ) ;
33+ _accessors . Add ( field . Name , accessor . Generate ( ) ) ;
4934 }
5035 }
5136 return _accessors ;
5237 }
5338 }
5439
55- private static Dictionary < string , SetFieldDelegate > _setters = null ;
56- private static Dictionary < string , SetFieldDelegate > FieldSetters
40+ private static Dictionary < string , MethodInfo > _setters = null ;
41+ private static Dictionary < string , MethodInfo > FieldSetters
5742 {
5843 get
5944 {
@@ -63,43 +48,28 @@ private static Dictionary<string, SetFieldDelegate> FieldSetters
6348
6449 foreach ( var field in AccessTools . GetDeclaredFields ( typeof ( D ) ) )
6550 {
66- var fieldType = field . FieldType ;
6751 var setter = new DynamicMethodDefinition ( "set_" + field . Name , typeof ( void ) , new Type [ ] { typeof ( D ) , typeof ( object ) } ) ;
6852 var il = setter . GetILProcessor ( ) ;
6953 il . Emit ( OpCodes . Ldarg_0 ) ;
7054 il . Emit ( OpCodes . Ldarg_1 ) ;
71- if ( FieldAccessors . TryGetValue ( field . Name , out var getter ) && getter . FieldType . GetGenericTypeDefinition ( ) == typeof ( Nullable < > ) && getter . FieldType . GetGenericArguments ( ) [ 0 ] == field . FieldType )
72- {
73- il . Emit ( OpCodes . Call , AccessTools . DeclaredPropertyGetter ( fieldType , "Value" ) ) ;
74- fieldType = getter . FieldType . GetGenericArguments ( ) [ 0 ] ;
75- }
76- else if ( fieldType . IsValueType )
77- il . Emit ( OpCodes . Unbox , setter . Module . ImportReference ( field . FieldType ) ) ;
78- else
79- il . Emit ( OpCodes . Castclass , setter . Module . ImportReference ( field . FieldType ) ) ;
55+ il . Emit ( OpCodes . Unbox_Any , setter . Module . ImportReference ( field . FieldType ) ) ;
8056 il . Emit ( OpCodes . Stfld , setter . Module . ImportReference ( field ) ) ;
8157 il . Emit ( OpCodes . Ret ) ;
82- _setters . Add ( field . Name , new SetFieldDelegate
83- {
84- Del = ( delegate * < D , object , void > ) setter . Generate ( ) . MethodHandle . GetFunctionPointer ( ) ,
85- FieldType = field . FieldType
86- } ) ;
58+ _setters . Add ( field . Name , setter . Generate ( ) ) ;
8759 }
8860 }
8961 return _setters ;
9062 }
9163 }
9264
93- public static D Convert ( S source , D destination = null )
65+ public static D Convert ( S source , D destination )
9466 {
95- destination ??= new ( ) ;
96-
9767 foreach ( var field in FieldAccessors )
9868 {
99- object val = field . Value . Del ( source ) ;
100- if ( val is not null )
69+ object val = field . Value . Invoke ( null , new object [ ] { source } ) ;
70+ if ( val is not null && FieldSetters . ContainsKey ( field . Key ) )
10171 {
102- FieldSetters [ field . Key ] . Del ( destination , val ) ;
72+ FieldSetters [ field . Key ] . Invoke ( null , new object [ ] { destination , val } ) ;
10373 }
10474 }
10575
0 commit comments