Exemple #1
0
		/// <summary> Loads the default values from XML attributes default </summary>
		public void loadDefaultValues()
		{
			#if DEBUG_LOAD
			Debug.WriteLine ("LoadDefValues for " + this.ToString ());
			#endif

			Type thisType = this.GetType ();

			if (!string.IsNullOrEmpty (Style)) {
				if (Interface.DefaultValuesLoader.ContainsKey (Style)) {
					Interface.DefaultValuesLoader [Style] (this);
					return;
				}
			} else {
				if (Interface.DefaultValuesLoader.ContainsKey (thisType.FullName)) {
					Interface.DefaultValuesLoader [thisType.FullName] (this);
					return;
				} else if (!Interface.Styling.ContainsKey (thisType.FullName)) {
					if (Interface.DefaultValuesLoader.ContainsKey (thisType.Name)) {
						Interface.DefaultValuesLoader [thisType.Name] (this);
						return;
					}
				}
			}

			List<Style> styling = new List<Style>();

			//Search for a style matching :
			//1: Full class name, with full namespace
			//2: class name
			//3: style may have been registered with their ressource ID minus .style extention
			//   those files being placed in a Styles folder
			string styleKey = Style;
			if (!string.IsNullOrEmpty (Style)) {
				if (Interface.Styling.ContainsKey (Style)) {
					styling.Add (Interface.Styling [Style]);
				}
			}
			if (Interface.Styling.ContainsKey (thisType.FullName)) {
				styling.Add (Interface.Styling [thisType.FullName]);
				if (string.IsNullOrEmpty (styleKey))
					styleKey = thisType.FullName;
			}
			if (Interface.Styling.ContainsKey (thisType.Name)) {
				styling.Add (Interface.Styling [thisType.Name]);
				if (string.IsNullOrEmpty (styleKey))
					styleKey = thisType.Name;
			}

			if (string.IsNullOrEmpty (styleKey))
				styleKey = thisType.FullName;


			//Reflexion being very slow compared to dyn method or delegates,
			//I compile the initial values coded in the CustomAttribs of the class,
			//all other instance of this type would not longer use reflexion to init properly
			//but will fetch the  dynamic initialisation method compiled for this precise type
			//TODO:measure speed gain.
			#region Delfault values Loading dynamic compilation
			DynamicMethod dm = null;
			ILGenerator il = null;

			dm = new DynamicMethod("dyn_loadDefValues",
				MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
				CallingConventions.Standard,
				typeof(void),new Type[] {CompilerServices.TObject},thisType,true);

			il = dm.GetILGenerator(256);
			il.DeclareLocal(CompilerServices.TObject);
			il.Emit(OpCodes.Nop);
			//set local GraphicObject to root object passed as 1st argument
			il.Emit (OpCodes.Ldarg_0);
			il.Emit (OpCodes.Stloc_0);

			foreach (EventInfo ei in thisType.GetEvents(BindingFlags.Public | BindingFlags.Instance)) {
				string expression;
				if (!getDefaultEvent(ei, styling, out expression))
					continue;
				//TODO:dynEventHandler could be cached somewhere, maybe a style instanciator class holding the styling delegate and bound to it.
				foreach (string exp in CompilerServices.splitOnSemiColumnOutsideAccolades(expression)) {
					string trimed = exp.Trim();
					if (trimed.StartsWith ("{", StringComparison.OrdinalIgnoreCase)){
						il.Emit (OpCodes.Ldloc_0);//load this as 1st arg of event Add

						//push eventInfo as 1st arg of compile
						il.Emit (OpCodes.Ldloc_0);
						il.Emit (OpCodes.Call, CompilerServices.miGetType);
						il.Emit (OpCodes.Ldstr, ei.Name);//push event name
						il.Emit (OpCodes.Call, CompilerServices.miGetEvent);
						//push expression as 2nd arg of compile
						il.Emit (OpCodes.Ldstr, trimed.Substring (1, trimed.Length - 2));
						//push null as 3rd arg, currentNode, not known when instanciing
						il.Emit (OpCodes.Ldnull);
						il.Emit (OpCodes.Callvirt, CompilerServices.miCompileDynEventHandler);
						il.Emit (OpCodes.Castclass, ei.EventHandlerType);
						il.Emit (OpCodes.Callvirt, ei.AddMethod);
					}else
						Debug.WriteLine("error in styling, event not handled : " + trimed);
				}
			}

			foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
				if (pi.GetSetMethod () == null)
					continue;
				object defaultValue;
				if (!getDefaultValue (pi, styling, out defaultValue))
					continue;

				CompilerServices.EmitSetValue (il, pi, defaultValue);
			}
			il.Emit(OpCodes.Ret);
			#endregion

			try {
				Interface.DefaultValuesLoader[styleKey] = (Interface.LoaderInvoker)dm.CreateDelegate(typeof(Interface.LoaderInvoker));
				Interface.DefaultValuesLoader[styleKey] (this);
			} catch (Exception ex) {
				throw new Exception ("Error applying style <" + styleKey + ">:", ex);
			}
		}
Exemple #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
        }