1
1
using System . Reflection ;
2
+ using System . Reflection . Emit ;
2
3
using UnityEngine ;
3
4
4
5
namespace UnityMapper ;
@@ -82,4 +83,78 @@ public string GetName()
82
83
{
83
84
return info . DeclaringType . Name + "/" + info . Name ;
84
85
}
86
+ }
87
+
88
+ /// <summary>
89
+ /// Implementation of IMappedProperty that uses runtime code generation to improve performance.
90
+ /// </summary>
91
+ public class RCGClassField : IMappedProperty
92
+ {
93
+
94
+ private delegate void SetObjectDelegate ( object target , object value ) ;
95
+ private delegate object GetValueDelegate ( object target ) ;
96
+
97
+ private object _target ;
98
+ private FieldInfo _info ;
99
+ private SetObjectDelegate _setter ;
100
+ private GetValueDelegate _getter ;
101
+
102
+ public RCGClassField ( FieldInfo info , Component target )
103
+ {
104
+ _target = target ;
105
+ _info = info ;
106
+ _setter = CreateSetter ( ) ;
107
+ _getter = CreateGetter ( ) ;
108
+ }
109
+
110
+ public Type GetMappedType ( )
111
+ {
112
+ return _info . FieldType ;
113
+ }
114
+
115
+ public void SetObject ( object value )
116
+ {
117
+ _setter ( _target , value ) ;
118
+ }
119
+
120
+ public object GetValue ( )
121
+ {
122
+ return _getter ( _target ) ;
123
+ }
124
+
125
+ public string GetName ( )
126
+ {
127
+ return _info . DeclaringType . Name + "/" + _info . Name ;
128
+ }
129
+
130
+ private GetValueDelegate CreateGetter ( )
131
+ {
132
+ var d = new DynamicMethod ( $ "Get{ _info . Name } _Generated", typeof ( object ) , new [ ] { typeof ( object ) } , _info . DeclaringType ) ;
133
+ var il = d . GetILGenerator ( ) ;
134
+ il . Emit ( OpCodes . Ldarg_0 ) ; // "this"
135
+ il . Emit ( OpCodes . Castclass , _info . DeclaringType ) ; // cast to the declaring type
136
+ il . Emit ( OpCodes . Ldfld , _info ) ; // "this".{_info}
137
+ if ( _info . FieldType . IsValueType ) // box it if it's a value type
138
+ {
139
+ il . Emit ( OpCodes . Box , _info . FieldType ) ;
140
+ }
141
+ il . Emit ( OpCodes . Ret ) ; // return the value
142
+ return ( GetValueDelegate ) d . CreateDelegate ( typeof ( GetValueDelegate ) ) ;
143
+ }
144
+
145
+ private SetObjectDelegate CreateSetter ( )
146
+ {
147
+ var d = new DynamicMethod ( $ "Set{ _info . Name } _Generated", typeof ( void ) , new [ ] { typeof ( object ) , typeof ( object ) } , _info . DeclaringType ) ;
148
+ var il = d . GetILGenerator ( ) ;
149
+ il . Emit ( OpCodes . Ldarg_0 ) ; // "this"
150
+ il . Emit ( OpCodes . Castclass , _info . DeclaringType ) ; // cast to the declaring type
151
+ il . Emit ( OpCodes . Ldarg_1 ) ; // value
152
+ if ( _info . FieldType . IsValueType ) // unbox it if it's a value type
153
+ {
154
+ il . Emit ( OpCodes . Unbox_Any , _info . FieldType ) ;
155
+ }
156
+ il . Emit ( OpCodes . Stfld , _info ) ; // "this".{_info} = value
157
+ il . Emit ( OpCodes . Ret ) ; // return
158
+ return ( SetObjectDelegate ) d . CreateDelegate ( typeof ( SetObjectDelegate ) ) ;
159
+ }
85
160
}
0 commit comments