Changeset 4788
- Timestamp:
- 11/13/10 10:26:04 (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/ParameterBinding/HeuristicLab.Core/3.3/ItemBinding.cs
r4787 r4788 23 23 private bool bound; 24 24 25 private Dictionary<Type, Delegate> eventHandlerCache = new Dictionary<Type, Delegate>(); 25 private static object evhCacheLock = new object(); 26 private static Dictionary<Type, DynamicMethod> eventHandlerCache = new Dictionary<Type, DynamicMethod>(); 26 27 27 28 [StorableConstructor] … … 94 95 string[] sourceProperties = sourcePath.Split('.'); 95 96 object cSource = source; 96 PropertyInfo bindingProperty = null;97 #region Navigate to source property 97 98 bool reregister = false; 98 99 for (int i = 0; i < sourceProperties.Length; i++) { … … 101 102 if (reregister) TryHookToChangedEvent(cSource, property + "Changed"); 102 103 if (cSource == sender) reregister = true; 103 bindingProperty = cSource.GetType().GetProperty(property, Flags); 104 object next = bindingProperty.GetGetMethod(true).Invoke(cSource, null); 104 object next = cSource.GetType().GetProperty(property, Flags).GetGetMethod(true).Invoke(cSource, null); 105 105 cSource = next; 106 106 } 107 #endregion 107 108 108 109 string[] targetProperties = targetPath.Split('.'); 109 110 object cTarget = target; 111 MethodInfo targetSetter = null; 112 #region Navigate to target property 110 113 for (int i = 0; i < targetProperties.Length - 1; i++) { 111 114 cTarget = cTarget.GetType().GetProperty(targetProperties[i], Flags).GetGetMethod(true).Invoke(cTarget, null); 112 115 if (cTarget == null) return; 113 116 } 114 MethodInfo setter = cTarget.GetType().GetProperty(targetProperties.Last(), Flags).GetSetMethod(true); 115 if (cSource.GetType().IsValueType) 116 setter.Invoke(cTarget, new object[] { cSource }); 117 targetSetter = cTarget.GetType().GetProperty(targetProperties.Last(), Flags).GetSetMethod(true); 118 if (targetSetter == null) return; 119 #endregion 120 121 if (cSource == null && !targetSetter.GetParameters().First().ParameterType.IsValueType 122 || cSource != null && cSource.GetType().IsValueType) 123 targetSetter.Invoke(cTarget, new object[] { cSource }); 117 124 else if (cSource is ICloneable) 118 setter.Invoke(cTarget, new object[] { ((ICloneable)cSource).Clone() });125 targetSetter.Invoke(cTarget, new object[] { ((ICloneable)cSource).Clone() }); 119 126 else throw new InvalidOperationException("Can only bind to targets which are either a ValueType or an ICloneable."); 120 127 } … … 126 133 if (!eventHandlerCache.ContainsKey(methodParams[1])) 127 134 CreateAndAddDynamicEventHandler(eInfo, methodParams); 128 eInfo.AddEventHandler(obj, eventHandlerCache[methodParams[1]] );135 eInfo.AddEventHandler(obj, eventHandlerCache[methodParams[1]].CreateDelegate(eInfo.EventHandlerType, this)); 129 136 } 130 137 return eInfo != null; … … 136 143 Type[] methodParams = eInfo.EventHandlerType.GetMethod("Invoke").GetParameters().Select(x => x.ParameterType).ToArray(); 137 144 if (eventHandlerCache.ContainsKey(methodParams[1])) 138 eInfo.RemoveEventHandler(obj, eventHandlerCache[methodParams[1]] );145 eInfo.RemoveEventHandler(obj, eventHandlerCache[methodParams[1]].CreateDelegate(eInfo.EventHandlerType, this)); 139 146 } 140 147 return eInfo != null; … … 142 149 143 150 private void CreateAndAddDynamicEventHandler(EventInfo eInfo, Type[] methodParams) { 144 Type[] instanceMethodParams = new Type[] { GetType() }.Concat(methodParams).ToArray(); 145 DynamicMethod dynamicEventHandler = new DynamicMethod("sourceChanged", null, instanceMethodParams, GetType()); 146 MethodInfo executeBindingMethodInfo = GetType().GetMethod("ExecuteBinding", Flags); 147 ILGenerator iLG = dynamicEventHandler.GetILGenerator(); 148 iLG.Emit(OpCodes.Ldarg_0); // load 'this' pointer 149 iLG.Emit(OpCodes.Ldarg_1); // load sender parameter 150 iLG.Emit(OpCodes.Call, executeBindingMethodInfo); // call method to execute the binding 151 iLG.Emit(OpCodes.Ret); 152 eventHandlerCache.Add(methodParams[1], dynamicEventHandler.CreateDelegate(eInfo.EventHandlerType, this)); 151 lock (evhCacheLock) { 152 if (!eventHandlerCache.ContainsKey(methodParams[1])) { 153 Type[] instanceMethodParams = new Type[] { GetType() }.Concat(methodParams).ToArray(); 154 DynamicMethod dynamicEventHandler = new DynamicMethod("sourceChanged", null, instanceMethodParams, GetType()); 155 MethodInfo executeBindingMethodInfo = GetType().GetMethod("ExecuteBinding", Flags); 156 ILGenerator iLG = dynamicEventHandler.GetILGenerator(); 157 iLG.Emit(OpCodes.Ldarg_0); // load 'this' pointer 158 iLG.Emit(OpCodes.Ldarg_1); // load sender parameter 159 iLG.Emit(OpCodes.Call, executeBindingMethodInfo); // call method to execute the binding 160 iLG.Emit(OpCodes.Ret); 161 eventHandlerCache.Add(methodParams[1], dynamicEventHandler); 162 } 163 } 153 164 } 154 165 }
Note: See TracChangeset
for help on using the changeset viewer.