public void CreateExpandDelegate(TemplatedGroup host) { Type dataType = Type.GetType(strDataType); Type tmpGrpType = typeof(TemplatedGroup); Type hostType = tmpGrpType; //not sure is the best place to put the dyn method Type evtType = typeof(EventHandler); MethodInfo evtInvoke = evtType.GetMethod("Invoke"); ParameterInfo [] evtParams = evtInvoke.GetParameters(); Type handlerArgsType = evtParams [1].ParameterType; Type [] args = { typeof(object), typeof(object), handlerArgsType }; DynamicMethod dm = new DynamicMethod("dyn_expand_" + fetchMethodName, typeof(void), args, hostType); #region IL generation ILGenerator il = dm.GetILGenerator(256); il.DeclareLocal(typeof(GraphicObject)); il.Emit(OpCodes.Ldarg_1); MethodInfo miFindByName = typeof(GraphicObject).GetMethod("FindByName"); il.Emit(OpCodes.Ldstr, "List"); il.Emit(OpCodes.Callvirt, miFindByName); il.Emit(OpCodes.Stloc_0); FieldInfo fiTemplates = typeof(TemplatedGroup).GetField("ItemTemplates"); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fiTemplates); il.Emit(OpCodes.Stfld, fiTemplates); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Callvirt, typeof(GraphicObject).GetProperty("DataSource").GetGetMethod()); MethodInfo miGetDatas = dataType.GetMethod(fetchMethodName, new Type[] {}); il.Emit(OpCodes.Callvirt, miGetDatas); il.Emit(OpCodes.Callvirt, tmpGrpType.GetProperty("Data").GetSetMethod()); il.Emit(OpCodes.Ret); #endregion Expand = (EventHandler)dm.CreateDelegate(evtType, host); }
/// <summary> /// Creates the expand delegate. /// </summary> /// <param name="host">Host.</param> public void CreateExpandDelegate(TemplatedGroup host) { Type dataType = null; //if (host.DataTest == "TypeOf"){ dataType = CompilerServices.tryGetType(strDataType); // if (dataType == null) { // Debug.WriteLine ("ItemTemplate error: DataType not found: {0}.", strDataType); // return; // } // } Type tmpGrpType = typeof(TemplatedGroup); Type evtType = typeof(EventHandler); //PropertyInfo piData = tmpGrpType.GetProperty ("Data"); MethodInfo evtInvoke = evtType.GetMethod("Invoke"); ParameterInfo [] evtParams = evtInvoke.GetParameters(); Type handlerArgsType = evtParams [1].ParameterType; Type [] args = { CompilerServices.TObject, CompilerServices.TObject, handlerArgsType }; #region Expand dyn meth //DM is bound to templatedGroup root (arg0) //arg1 is the sender of the expand event DynamicMethod dm = new DynamicMethod("dyn_expand_" + fetchMethodName, typeof(void), args, typeof(TemplatedGroup), true); System.Reflection.Emit.Label gotoEnd; System.Reflection.Emit.Label ifDataIsNull; System.Reflection.Emit.Label gotoItemsContainerNotFound; ILGenerator il = dm.GetILGenerator(256); il.DeclareLocal(typeof(GraphicObject)); gotoEnd = il.DefineLabel(); ifDataIsNull = il.DefineLabel(); gotoItemsContainerNotFound = il.DefineLabel(); il.Emit(OpCodes.Ldarg_1); //load sender of expand event il.Emit(OpCodes.Ldstr, "ItemsContainer"); //load name to find il.Emit(OpCodes.Callvirt, CompilerServices.miFindByName); il.Emit(OpCodes.Stloc_0); //save items container as loc0 //ensure ItemsContainer is not null il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Brfalse, gotoItemsContainerNotFound); //check that node is not already expanded il.Emit(OpCodes.Ldarg_0); //push root TemplatedGroup into the stack il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Call, CompilerServices.miIsAlreadyExpanded); il.Emit(OpCodes.Brtrue, gotoEnd); // il.Emit (OpCodes.Ldloc_0); // il.Emit (OpCodes.Callvirt, piData.GetGetMethod ()); // il.Emit (OpCodes.Brfalse, ifDataIsNull); // il.Emit (OpCodes.Br, gotoEnd); // il.MarkLabel(ifDataIsNull); //copy the ref of ItemTemplates list TODO: maybe find another way to share it among the nodes? // FieldInfo fiTemplates = tmpGrpType.GetField("ItemTemplates"); // il.Emit (OpCodes.Ldloc_0); // il.Emit (OpCodes.Ldarg_0); // il.Emit (OpCodes.Ldfld, fiTemplates); // il.Emit (OpCodes.Stfld, fiTemplates); //call 'fetchMethodName' from the dataSource to build the sub nodes list //il.Emit (OpCodes.Ldarg_0);//load root templatedGroop il.Emit(OpCodes.Ldarg_0); //push root TemplatedGroup into the stack il.Emit(OpCodes.Ldarg_1); //load sender node of expand il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataSource); //get the dataSource of the sender if (fetchMethodName != "self") //special keyword self allows the use of recurent list<<< { if (dataType == null) { //dataTest was not = TypeOF, so we have to get the type of data //dynamically and fetch il.Emit(OpCodes.Ldstr, fetchMethodName); il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataTypeAndFetch); } else { emitGetSubData(il, dataType); } } //set 'return' from the fetch method as 'data' of the list //il.Emit (OpCodes.Callvirt, piData.GetSetMethod ()); il.Emit(OpCodes.Ldloc_0); //load second arg of loadPage, the sender node il.Emit(OpCodes.Ldstr, dataTest); //load 3rd arg, dataTest kind on subitems il.Emit(OpCodes.Callvirt, CompilerServices.miLoadPage); il.Emit(OpCodes.Br, gotoEnd); il.MarkLabel(gotoItemsContainerNotFound); il.EmitWriteLine("ItemsContainer not found in ItemTemplate for " + host.ToString()); il.MarkLabel(gotoEnd); il.Emit(OpCodes.Ret); Expand = (EventHandler)dm.CreateDelegate(evtType, host); #endregion #region Items counting dyn method //dm is unbound, arg0 is instance of Item container to expand dm = new DynamicMethod("dyn_count_" + fetchMethodName, typeof(bool), new Type[] { CompilerServices.TObject }, true); il = dm.GetILGenerator(256); //get the dataSource of the arg0 il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataSource); if (fetchMethodName != "self") //special keyword self allows the use of recurent list<<< { if (dataType == null) { //dataTest was not = TypeOF, so we have to get the type of data //dynamically and fetch il.Emit(OpCodes.Ldstr, fetchMethodName); il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataTypeAndFetch); } else { emitGetSubData(il, dataType); } } il.Emit(OpCodes.Callvirt, CompilerServices.miGetColCount); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Cgt); il.Emit(OpCodes.Ret); HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate(typeof(BooleanTestOnInstance)); #endregion }
public void CreateExpandDelegate(TemplatedGroup host) { Type dataType = Type.GetType(strDataType); if (dataType == null) { Assembly a = Assembly.GetEntryAssembly(); foreach (Type expT in a.GetExportedTypes()) { if (expT.Name == strDataType) { dataType = expT; break; } } } if (dataType == null) { Debug.WriteLine("ItemTemplate error: DataType not found: {0}.", strDataType); return; } Type tmpGrpType = typeof(TemplatedGroup); Type evtType = typeof(EventHandler); PropertyInfo piData = tmpGrpType.GetProperty("Data"); MethodInfo evtInvoke = evtType.GetMethod("Invoke"); ParameterInfo [] evtParams = evtInvoke.GetParameters(); Type handlerArgsType = evtParams [1].ParameterType; Type [] args = { CompilerServices.TObject, CompilerServices.TObject, handlerArgsType }; #region Expand dyn meth //DM is bound to templatedGroup root (arg0) //arg1 is the sender of the expand event DynamicMethod dm = new DynamicMethod("dyn_expand_" + fetchMethodName, typeof(void), args, true); System.Reflection.Emit.Label gotoEnd; System.Reflection.Emit.Label ifDataIsNull; ILGenerator il = dm.GetILGenerator(256); il.DeclareLocal(typeof(GraphicObject)); gotoEnd = il.DefineLabel(); ifDataIsNull = il.DefineLabel(); il.Emit(OpCodes.Ldarg_1); //load sender of expand event il.Emit(OpCodes.Ldstr, "List"); il.Emit(OpCodes.Callvirt, CompilerServices.miFindByName); il.Emit(OpCodes.Stloc_0); //check that 'Data' of list is not already set il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Callvirt, piData.GetGetMethod()); il.Emit(OpCodes.Brfalse, ifDataIsNull); il.Emit(OpCodes.Br, gotoEnd); il.MarkLabel(ifDataIsNull); //copy the ref of ItemTemplates list TODO: maybe find another way to share it among the nodes? FieldInfo fiTemplates = tmpGrpType.GetField("ItemTemplates"); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, fiTemplates); il.Emit(OpCodes.Stfld, fiTemplates); //call 'fetchMethodName' from the dataSource to build the sub nodes list il.Emit(OpCodes.Ldloc_0); //push 'List' (of sub nodes) into the stack il.Emit(OpCodes.Ldarg_1); //get the dataSource of the sender il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataSource); if (fetchMethodName != "self") //special keyword self allows the use of recurent list<<< { emitGetSubData(il, dataType); } //set 'return' from the fetch method as 'data' of the list il.Emit(OpCodes.Callvirt, piData.GetSetMethod()); il.MarkLabel(gotoEnd); il.Emit(OpCodes.Ret); Expand = (EventHandler)dm.CreateDelegate(evtType, host); #endregion #region Items counting dyn method //dm is unbound, arg0 is instance of Item container to expand dm = new DynamicMethod("dyn_count_" + fetchMethodName, typeof(bool), new Type[] { CompilerServices.TObject }, true); il = dm.GetILGenerator(256); //get the dataSource of the arg0 il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Callvirt, CompilerServices.miGetDataSource); if (fetchMethodName != "self") { emitGetSubData(il, dataType); } il.Emit(OpCodes.Callvirt, CompilerServices.miGetColCount); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Cgt); il.Emit(OpCodes.Ret); HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate(typeof(BooleanTestOnInstance)); #endregion }
public void CreateExpandDelegate(TemplatedGroup host) { Type dataType = Type.GetType(strDataType); Type tmpGrpType = typeof(TemplatedGroup); Type evtType = typeof(EventHandler); PropertyInfo piData = tmpGrpType.GetProperty ("Data"); MethodInfo evtInvoke = evtType.GetMethod ("Invoke"); ParameterInfo [] evtParams = evtInvoke.GetParameters (); Type handlerArgsType = evtParams [1].ParameterType; Type [] args = { CompilerServices.TObject, CompilerServices.TObject, handlerArgsType }; #region Expand dyn meth //DM is bound to templatedGroup root (arg0) //arg1 is the sender of the expand event DynamicMethod dm = new DynamicMethod ("dyn_expand_" + fetchMethodName, typeof (void), args, true); System.Reflection.Emit.Label gotoEnd; System.Reflection.Emit.Label ifDataIsNull; ILGenerator il = dm.GetILGenerator (256); il.DeclareLocal(typeof(GraphicObject)); gotoEnd = il.DefineLabel (); ifDataIsNull = il.DefineLabel (); il.Emit (OpCodes.Ldarg_1);//load sender of expand event il.Emit(OpCodes.Ldstr, "List"); il.Emit (OpCodes.Callvirt, CompilerServices.miFindByName); il.Emit (OpCodes.Stloc_0); //check that 'Data' of list is not already set il.Emit (OpCodes.Ldloc_0); il.Emit (OpCodes.Callvirt, piData.GetGetMethod ()); il.Emit (OpCodes.Brfalse, ifDataIsNull); il.Emit (OpCodes.Br, gotoEnd); il.MarkLabel(ifDataIsNull); //copy the ref of ItemTemplates list TODO: maybe find another way to share it among the nodes? FieldInfo fiTemplates = tmpGrpType.GetField("ItemTemplates"); il.Emit (OpCodes.Ldloc_0); il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Ldfld, fiTemplates); il.Emit (OpCodes.Stfld, fiTemplates); //call 'fetchMethodName' from the dataSource to build the sub nodes list il.Emit (OpCodes.Ldloc_0);//push 'List' (of sub nodes) into the stack il.Emit (OpCodes.Ldarg_1);//get the dataSource of the sender il.Emit (OpCodes.Callvirt, CompilerServices.miGetDataSource); if (fetchMethodName != "self")//special keyword self allows the use of recurent list<<< emitGetSubData(il, dataType); //set 'return' from the fetch method as 'data' of the list il.Emit (OpCodes.Callvirt, piData.GetSetMethod ()); il.MarkLabel(gotoEnd); il.Emit (OpCodes.Ret); Expand = (EventHandler)dm.CreateDelegate (evtType, host); #endregion #region Items counting dyn method //dm is unbound, arg0 is instance of Item container to expand dm = new DynamicMethod ("dyn_count_" + fetchMethodName, typeof (bool), new Type[] {CompilerServices.TObject}, true); il = dm.GetILGenerator (256); //get the dataSource of the arg0 il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Callvirt, CompilerServices.miGetDataSource); if (fetchMethodName != "self") emitGetSubData(il, dataType); il.Emit (OpCodes.Callvirt, CompilerServices.miGetColCount); il.Emit (OpCodes.Ldc_I4_0); il.Emit (OpCodes.Cgt); il.Emit (OpCodes.Ret); HasSubItems = (BooleanTestOnInstance)dm.CreateDelegate (typeof(BooleanTestOnInstance)); #endregion }