Beispiel #1
0
        /// <summary>
        /// Parse child node an generate corresponding msil
        /// </summary>
        void readChildren(IMLReader reader, Type crowType, bool templateLoading = false)
        {
            MethodInfo miAddChild    = null;
            bool       endTagReached = false;

            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                case XmlNodeType.EndElement:
                    endTagReached = true;
                    break;

                case XmlNodeType.Element:
                    //Templates
                    if (reader.Name == "Template" ||
                        reader.Name == "ItemTemplate")
                    {
                        reader.Skip();
                        continue;
                    }

                    if (miAddChild == null)
                    {
                        if (typeof(Group).IsAssignableFrom(crowType))
                        {
                            miAddChild = typeof(Group).GetMethod("AddChild");
                        }
                        else if (typeof(Container).IsAssignableFrom(crowType))
                        {
                            miAddChild = typeof(Container).GetMethod("SetChild");
                        }
                        else if (typeof(TemplatedContainer).IsAssignableFrom(crowType) && !templateLoading)
                        {
                            miAddChild = typeof(TemplatedContainer).GetProperty("Content").GetSetMethod();
                        }
                        else if (typeof(TemplatedGroup).IsAssignableFrom(crowType) && !templateLoading)
                        {
                            miAddChild = typeof(TemplatedGroup).GetMethod("AddItem",
                                                                          BindingFlags.Instance | BindingFlags.Public);
                        }
                        else if (typeof(TemplatedControl).IsAssignableFrom(crowType))
                        {
                            miAddChild = typeof(TemplatedControl).GetMethod("loadTemplate",
                                                                            BindingFlags.Instance | BindingFlags.NonPublic);
                        }
                        else if (typeof(PrivateContainer).IsAssignableFrom(crowType))
                        {
                            miAddChild = typeof(PrivateContainer).GetMethod("SetChild",
                                                                            BindingFlags.Instance | BindingFlags.NonPublic);
                        }
                    }
                    //push current instance on stack for parenting
                    //loc_0 will be used for child
                    reader.il.Emit(OpCodes.Ldloc_0);

                    Type t = Type.GetType("Crow." + reader.Name);
                    if (t == null)
                    {
                        Assembly a = Assembly.GetEntryAssembly();
                        foreach (Type expT in a.GetExportedTypes())
                        {
                            if (expT.Name == reader.Name)
                            {
                                t = expT;
                            }
                        }
                    }
                    if (t == null)
                    {
                        throw new Exception(reader.Name + " type not found");
                    }

                    reader.il.Emit(OpCodes.Newobj, t.GetConstructors() [0]); //TODO:search parameterless ctor
                    reader.il.Emit(OpCodes.Stloc_0);                         //child is now loc_0
                    CompilerServices.emitSetCurInterface(il);

                    reader.emitLoader(t);

                    reader.il.Emit(OpCodes.Ldloc_0);                     //load child on stack for parenting
                    if (miAddChild == null)
                    {
                        System.Diagnostics.Debugger.Break();
                    }
                    reader.il.Emit(OpCodes.Callvirt, miAddChild);
                    reader.il.Emit(OpCodes.Stloc_0);                     //reset local to current go
                    reader.il.Emit(OpCodes.Ldloc_0);                     //save current go onto the stack if child has to be added
                    break;
                }
                if (endTagReached)
                {
                    break;
                }
            }
        }
Beispiel #2
0
        void emitLoader(Type crowType)
        {
            string tmpXml = ReadOuterXml();

            il.Emit(OpCodes.Ldloc_0);             //save current go onto the stack if child has to be added

            #region Template and ItemTemplates loading
            if (typeof(TemplatedControl).IsAssignableFrom(crowType))
            {
                //if its a template, first read template elements
                using (IMLReader reader = new IMLReader(il, tmpXml)) {
                    string templatePath = reader.GetAttribute("Template");
                    //string itemTemplatePath = reader.GetAttribute ("ItemTemplate");

                    List <string[]> itemTemplateIds = new List <string[]> ();
                    bool            inlineTemplate  = false;
                    reader.Read();
                    int depth = reader.Depth + 1;
                    while (reader.Read())
                    {
                        if (!reader.IsStartElement() || reader.Depth > depth)
                        {
                            continue;
                        }
                        if (reader.Name == "Template")
                        {
                            inlineTemplate = true;
                            reader.Read();

                            readChildren(reader, crowType, true);
                        }
                        else if (reader.Name == "ItemTemplate")
                        {
                            string dataType = "default", datas = "", path = "";
                            while (reader.MoveToNextAttribute())
                            {
                                if (reader.Name == "DataType")
                                {
                                    dataType = reader.Value;
                                }
                                else if (reader.Name == "Data")
                                {
                                    datas = reader.Value;
                                }
                                else if (reader.Name == "Path")
                                {
                                    path = reader.Value;
                                }
                            }
                            reader.MoveToElement();
                            using (IMLReader iTmp = new IMLReader(null, reader.ReadInnerXml())) {
                                string uid = Guid.NewGuid().ToString();
                                Interface.Instantiators [uid] =
                                    new ItemTemplate(iTmp.RootType, iTmp.GetLoader(), dataType, datas);

                                itemTemplateIds.Add(new string[] { dataType, uid, datas });
                            }
                        }
                    }

                    if (!inlineTemplate)
                    {
                        reader.il.Emit(OpCodes.Ldloc_0);                         //Load  this templateControl ref
                        if (string.IsNullOrEmpty(templatePath))
                        {
                            reader.il.Emit(OpCodes.Ldnull);                             //default template loading
                        }
                        else
                        {
                            reader.il.Emit(OpCodes.Ldarg_1);                             //load currentInterface
                            reader.il.Emit(OpCodes.Ldstr, templatePath);                 //Load template path string
                            reader.il.Emit(OpCodes.Callvirt,                             //call Interface.Load(path)
                                           typeof(Interface).GetMethod("Load", BindingFlags.Instance | BindingFlags.Public));
                        }
                        reader.il.Emit(OpCodes.Callvirt,                         //load template
                                       crowType.GetMethod("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic));
                    }
                    foreach (string[] iTempId in itemTemplateIds)
                    {
                        reader.il.Emit(OpCodes.Ldloc_0);                      //load TempControl ref
                        reader.il.Emit(OpCodes.Ldfld,                         //load ItemTemplates dic field
                                       typeof(TemplatedGroup).GetField("ItemTemplates"));
                        reader.il.Emit(OpCodes.Ldstr, iTempId[0]);            //load key
                        reader.il.Emit(OpCodes.Ldstr, iTempId[1]);            //load value
                        reader.il.Emit(OpCodes.Callvirt,
                                       typeof(Interface).GetMethod("GetItemTemplate"));
                        reader.il.Emit(OpCodes.Callvirt,
                                       typeof(Dictionary <string, ItemTemplate>).GetMethod("set_Item",
                                                                                           new Type[] { typeof(string), typeof(ItemTemplate) }));

                        if (!string.IsNullOrEmpty(iTempId [2]))
                        {
                            //expand delegate creation
                            reader.il.Emit(OpCodes.Ldloc_0);                          //load TempControl ref
                            reader.il.Emit(OpCodes.Ldfld,                             //load ItemTemplates dic field
                                           typeof(TemplatedGroup).GetField("ItemTemplates"));
                            reader.il.Emit(OpCodes.Ldstr, iTempId [0]);               //load key
                            reader.il.Emit(OpCodes.Callvirt,
                                           typeof(Dictionary <string, ItemTemplate>).GetMethod("get_Item",
                                                                                               new Type[] { typeof(string) }));
                            reader.il.Emit(OpCodes.Ldloc_0);                             //load root of treeView
                            reader.il.Emit(OpCodes.Callvirt,
                                           typeof(ItemTemplate).GetMethod("CreateExpandDelegate"));
                        }
                    }
                }
            }
            #endregion

            using (IMLReader reader = new IMLReader(il, tmpXml)){
                reader.Read();

                #region Styling and default values loading
                if (reader.HasAttributes)
                {
                    string style = reader.GetAttribute("Style");
                    if (!string.IsNullOrEmpty(style))
                    {
                        PropertyInfo pi = crowType.GetProperty("Style");
                        CompilerServices.EmitSetValue(reader.il, pi, style);
                    }
                }
                reader.il.Emit(OpCodes.Ldloc_0);
                reader.il.Emit(OpCodes.Callvirt, typeof(GraphicObject).GetMethod("loadDefaultValues"));
                #endregion

                #region Attributes reading
                if (reader.HasAttributes)
                {
                    MethodInfo miAddBinding = typeof(GraphicObject).GetMethod("BindMember");

                    while (reader.MoveToNextAttribute())
                    {
                        if (reader.Name == "Style")
                        {
                            continue;
                        }

                        MemberInfo mi = crowType.GetMember(reader.Name).FirstOrDefault();
                        if (mi == null)
                        {
                            throw new Exception("Member '" + reader.Name + "' not found in " + crowType.Name);
                        }
                        if (mi.MemberType == MemberTypes.Event)
                        {
                            CompilerServices.emitBindingCreation(reader.il, reader.Name, reader.Value);
                            continue;
                        }
                        PropertyInfo pi = mi as PropertyInfo;
                        if (pi == null)
                        {
                            throw new Exception("Member '" + reader.Name + "' not found in " + crowType.Name);
                        }

                        if (reader.Value.StartsWith("{"))
                        {
                            CompilerServices.emitBindingCreation(reader.il, reader.Name, reader.Value.Substring(1, reader.Value.Length - 2));
                        }
                        else
                        {
                            CompilerServices.EmitSetValue(reader.il, pi, reader.Value);
                        }
                    }
                    reader.MoveToElement();
                }
                #endregion

                if (reader.IsEmptyElement)
                {
                    reader.il.Emit(OpCodes.Pop);                     //pop saved ref to current object
                    return;
                }

                readChildren(reader, crowType);
            }
            il.Emit(OpCodes.Pop);             //pop saved ref to current object
        }