diff options
| author | jpbruyere <jp.bruyere@hotmail.com> | 2016-08-10 07:13:14 +0200 |
|---|---|---|
| committer | jpbruyere <jp.bruyere@hotmail.com> | 2016-08-10 07:13:40 +0200 |
| commit | 1b2e2794fc8c4c8c20ff50fd7fbe842908912d23 (patch) | |
| tree | e84e01c98b958e9d93214757543639110b07ae4f /src/IMLReader.cs | |
| parent | 5a03df5faeda15e2d99c4c656eb62ed21817fdf6 (diff) | |
| parent | 69c470239bfbab11192f3699f29b5352d74d3630 (diff) | |
ItemTemplate instantiator, basic listbox ok
Diffstat (limited to 'src/IMLReader.cs')
| -rw-r--r-- | src/IMLReader.cs | 141 |
1 files changed, 87 insertions, 54 deletions
diff --git a/src/IMLReader.cs b/src/IMLReader.cs index c1238081..7792de4d 100644 --- a/src/IMLReader.cs +++ b/src/IMLReader.cs @@ -24,11 +24,14 @@ using System.IO; using System.Reflection; using System.Reflection.Emit; using System.Linq; +using System.Collections.Generic; namespace Crow { public class IMLReader : XmlTextReader { + Interface.LoaderInvoker loader = null; + public string ImlPath; public Stream ImlStream; public Type RootType = null; @@ -45,27 +48,40 @@ namespace Crow : base(stream) { ImlStream = stream; - readRootType(); - InitEmitter(); - BuildInstanciator(RootType); - Read();//close tag + createInstantiator (); } + /// <summary> + /// Used to parse xmlFrament with same code generator linked + /// If ilGen=null, a new Code Generator will be created. + /// </summary> public IMLReader (ILGenerator ilGen, string xmlFragment) : base(xmlFragment, XmlNodeType.Element,null){ il = ilGen; + + if (il != null) + return; + + createInstantiator(); } #endregion + void createInstantiator(){ + readRootType(); + InitEmitter(); + emitLoader(RootType); + Read();//close tag + } /// <summary> /// Finalize instatiator MSIL and return LoaderInvoker delegate /// </summary> - public Instantiator GetInstanciator(){ - il.Emit(OpCodes.Ret); + public Interface.LoaderInvoker GetLoader(){ + if (loader != null) + return loader; - return new Instantiator (RootType, - (Interface.LoaderInvoker)dm.CreateDelegate (typeof(Interface.LoaderInvoker))); + il.Emit(OpCodes.Ret); + loader = (Interface.LoaderInvoker)dm.CreateDelegate (typeof(Interface.LoaderInvoker)); + return loader; } - /// <summary> /// Inits il generator, RootType must have been read first /// </summary> @@ -83,7 +99,7 @@ namespace Crow il.Emit (OpCodes.Ldarg_0); il.Emit (OpCodes.Stloc_0); } - void BuildInstanciator(Type crowType){ + void emitLoader(Type crowType){ string tmpXml = ReadOuterXml (); il.Emit (OpCodes.Ldloc_0);//save current go onto the stack if child has to be added @@ -92,58 +108,71 @@ namespace Crow //if its a template, first read template elements using (IMLReader reader = new IMLReader (il, tmpXml)) { - string template = reader.GetAttribute ("Template"); + string templatePath = reader.GetAttribute ("Template"); + //string itemTemplatePath = reader.GetAttribute ("ItemTemplate"); bool inlineTemplate = false; - if (string.IsNullOrEmpty (template)) { - reader.Read (); + reader.Read (); - while (reader.Read ()) { - if (!reader.IsStartElement ()) - continue; - if (reader.Name == "Template") { - inlineTemplate = true; - reader.Read (); + while (reader.Read ()) { + if (!reader.IsStartElement ()) + continue; + if (reader.Name == "Template") { + inlineTemplate = true; + reader.Read (); - readChildren (reader, crowType); - continue; - }else if (reader.Name == "ItemTemplate") { - reader.Skip (); - // string dataType = "default", datas = "", itemTmp; - // while (reader.MoveToNextAttribute ()) { - // if (reader.Name == "DataType") - // dataType = reader.Value; - // else if (reader.Name == "Data") - // datas = reader.Value; - // } - // - // reader.Read(); - // itemTmp = .ReadInnerXml (); - // - // if (ItemTemplates == null) - // ItemTemplates = new Dictionary<string, ItemTemplate> (); - // //TODO:check encoding - // ItemTemplates[dataType] = new ItemTemplate (Encoding.UTF8.GetBytes(itemTmp)); - // if (!string.IsNullOrEmpty (datas)) - // ItemTemplates [dataType].CreateExpandDelegate(this, dataType, datas); + readChildren (reader, crowType); + continue; + } 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; + } - continue; + using (IMLReader iTmp = new IMLReader (null, reader.ReadInnerXml ())) { + string uid = Guid.NewGuid ().ToString (); + Interface.Instantiators [uid] = + new ItemTemplate (iTmp.RootType, iTmp.GetLoader ()); + reader.il.Emit (OpCodes.Ldloc_0);//load TempControl ref + reader.il.Emit (OpCodes.Ldfld,//load ItemTemplates dic field + typeof(TemplatedControl).GetField("ItemTemplates")); + reader.il.Emit (OpCodes.Ldstr, dataType);//load key + reader.il.Emit (OpCodes.Ldstr, uid);//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 (!inlineTemplate) { - DefaultTemplate dt = (DefaultTemplate)crowType.GetCustomAttributes (typeof(DefaultTemplate), true).FirstOrDefault(); - template = dt.Path; +// if (!string.IsNullOrEmpty (datas)) +// ItemTemplates [dataType].CreateExpandDelegate(this, dataType, datas); + + continue; } } + if (!inlineTemplate) { - reader.il.Emit (OpCodes.Ldloc_0);//Load this templateControl ref + if (string.IsNullOrEmpty (templatePath)) { + DefaultTemplate dt = (DefaultTemplate)crowType.GetCustomAttributes (typeof(DefaultTemplate), true).FirstOrDefault (); + if (dt!=null) + templatePath = dt.Path; + } + + if (!string.IsNullOrEmpty (templatePath)) { + reader.il.Emit (OpCodes.Ldloc_0);//Load this templateControl ref - reader.il.Emit (OpCodes.Ldstr, template); //Load template path string - reader.il.Emit (OpCodes.Callvirt,//call Interface.Load(path) - typeof(Interface).GetMethod ("Load", BindingFlags.Static | BindingFlags.Public)); + reader.il.Emit (OpCodes.Ldstr, templatePath); //Load template path string + reader.il.Emit (OpCodes.Callvirt,//call Interface.Load(path) + typeof(Interface).GetMethod ("Load", BindingFlags.Static | BindingFlags.Public)); + reader.il.Emit (OpCodes.Callvirt,//add child + crowType.GetMethod ("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic)); + } } - reader.il.Emit (OpCodes.Callvirt,//add child - crowType.GetMethod ("loadTemplate", BindingFlags.Instance | BindingFlags.NonPublic)); } } @@ -157,9 +186,10 @@ namespace Crow CompilerServices.EmitSetValue (reader.il, pi, style); } } + reader.il.Emit (OpCodes.Ldloc_0); + reader.il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetMethod ("loadDefaultValues")); + if (reader.HasAttributes) { - reader.il.Emit (OpCodes.Ldloc_0); - reader.il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetMethod ("loadDefaultValues")); MethodInfo miAddBinding = typeof(GraphicObject).GetMethod ("BindMember"); @@ -222,6 +252,9 @@ namespace Crow miAddChild = typeof(Container).GetMethod ("SetChild"); else if (typeof(TemplatedContainer).IsAssignableFrom (crowType)) miAddChild = typeof(TemplatedContainer).GetProperty("Content").GetSetMethod(); + 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); @@ -245,7 +278,7 @@ namespace Crow reader.il.Emit(OpCodes.Newobj, t.GetConstructors () [0]); reader.il.Emit (OpCodes.Stloc_0);//child is now loc_0 - reader.BuildInstanciator(t); + reader.emitLoader(t); reader.il.Emit (OpCodes.Ldloc_0);//load child on stack for parenting reader.il.Emit (OpCodes.Callvirt, miAddChild); |