aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/IMLReader.cs
diff options
context:
space:
mode:
authorjpbruyere <jp.bruyere@hotmail.com>2016-08-10 07:13:14 +0200
committerjpbruyere <jp.bruyere@hotmail.com>2016-08-10 07:13:40 +0200
commit1b2e2794fc8c4c8c20ff50fd7fbe842908912d23 (patch)
treee84e01c98b958e9d93214757543639110b07ae4f /src/IMLReader.cs
parent5a03df5faeda15e2d99c4c656eb62ed21817fdf6 (diff)
parent69c470239bfbab11192f3699f29b5352d74d3630 (diff)
ItemTemplate instantiator, basic listbox ok
Diffstat (limited to 'src/IMLReader.cs')
-rw-r--r--src/IMLReader.cs141
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);