コード例 #1
0
        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);
        }
コード例 #2
0
ファイル: ItemTemplate.cs プロジェクト: masums/Crow
        /// <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
        }
コード例 #3
0
        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
        }
コード例 #4
0
ファイル: ItemTemplate.cs プロジェクト: jpbruyere/Crow
        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
        }