diff options
| author | jpbruyere <jp.bruyere@hotmail.com> | 2016-11-22 17:49:16 +0100 |
|---|---|---|
| committer | jpbruyere <jp.bruyere@hotmail.com> | 2016-11-22 17:49:16 +0100 |
| commit | f416267010e2d44badae89ceb76df3b27dd69a67 (patch) | |
| tree | 59fd7e8e44af4a6674bbbe50ebaedefbf089992a /src/Instantiator.cs | |
| parent | f7512fd4b75d815f4b78fcc844523d2bfc5f2bd1 (diff) | |
debug
Diffstat (limited to 'src/Instantiator.cs')
| -rw-r--r-- | src/Instantiator.cs | 90 |
1 files changed, 55 insertions, 35 deletions
diff --git a/src/Instantiator.cs b/src/Instantiator.cs index 0af50a85..b5ffbe83 100644 --- a/src/Instantiator.cs +++ b/src/Instantiator.cs @@ -95,8 +95,7 @@ namespace Crow void parseIML (XmlTextReader reader) { Context ctx = new Context (findRootType (reader)); - ctx.CurrentNode = new Node (ctx.RootType); - emitLoader (reader, ctx); + emitLoader (reader, ctx, ctx.RootType); emitBindingDelegates (ctx); @@ -130,17 +129,21 @@ namespace Crow } return t; } - void emitLoader (XmlTextReader reader, Context ctx) + void emitLoader (XmlTextReader reader, Context ctx, Type newType) { + ctx.nodesStack.Push(new Node (newType, ctx.CurrentIndex)); string tmpXml = reader.ReadOuterXml (); - if (ctx.CurrentNode.HasTemplate) + if (ctx.nodesStack.Peek().HasTemplate) emitTemplateLoad (ctx, tmpXml); emitGOLoad (ctx, tmpXml); + + emitCheckAndBindValueChanged (ctx); + + ctx.nodesStack.Pop (); } - void emitTemplateLoad (Context ctx, string tmpXml) { - ctx.CurrentNode.Index--;//template indexing use -1 + void emitTemplateLoad (Context ctx, string tmpXml) { //if its a template, first read template elements using (XmlTextReader reader = new XmlTextReader (tmpXml, XmlNodeType.Element, null)) { List<string []> itemTemplateIds = new List<string []> (); @@ -156,9 +159,8 @@ namespace Crow if (reader.Name == "Template") { inlineTemplate = true; reader.Read (); - ctx.nodesStack.Push (ctx.CurrentNode); + ctx.CurrentIndex = -1; readChildren (reader, ctx); - ctx.nodesStack.Pop (); } else if (reader.Name == "ItemTemplate") { string dataType = "default", datas = "", path = ""; while (reader.MoveToNextAttribute ()) { @@ -221,7 +223,7 @@ namespace Crow } } } - ctx.CurrentNode.Index++; + ctx.nodesStack.IncrementCurrentNodeIndex (); } void emitGOLoad (Context ctx, string tmpXml) { @@ -245,16 +247,16 @@ namespace Crow if (reader.Name == "Style") continue; - MemberInfo mi = ctx.CurrentNode.CrowType.GetMember (reader.Name).FirstOrDefault (); + MemberInfo mi = ctx.CurrentNodeType.GetMember (reader.Name).FirstOrDefault (); if (mi == null) - throw new Exception ("Member '" + reader.Name + "' not found in " + ctx.CurrentNode.CrowType.Name); + throw new Exception ("Member '" + reader.Name + "' not found in " + ctx.CurrentNodeType.Name); if (mi.MemberType == MemberTypes.Event) { //CompilerServices.emitBindingCreation (ctx.il, reader.Name, reader.Value); continue; } PropertyInfo pi = mi as PropertyInfo; if (pi == null) - throw new Exception ("Member '" + reader.Name + "' not found in " + ctx.CurrentNode.CrowType.Name); + throw new Exception ("Member '" + reader.Name + "' not found in " + ctx.CurrentNodeType.Name); if (pi.Name == "Name"){ if (!ctx.Names.ContainsKey(reader.Value)) @@ -273,12 +275,9 @@ namespace Crow #endregion if (!reader.IsEmptyElement) { - ctx.nodesStack.Push (ctx.CurrentNode); + ctx.CurrentIndex = 0; readChildren (reader, ctx); - ctx.nodesStack.Pop (); } - - emitCheckAndBindValueChanged (ctx); } } /// <summary> @@ -295,7 +294,7 @@ namespace Crow case XmlNodeType.Element: //skip Templates if (reader.Name == "Template" || - reader.Name == "ItemTemplate") { + reader.Name == "ItemTemplate") { reader.Skip (); continue; } @@ -320,14 +319,13 @@ namespace Crow ctx.il.Emit (OpCodes.Stloc_0);//child is now loc_0 CompilerServices.emitSetCurInterface (ctx.il); - ctx.CurrentNode = new Node (t); - emitLoader (reader, ctx); + emitLoader (reader, ctx, t); ctx.il.Emit (OpCodes.Ldloc_0);//load child on stack for parenting - ctx.il.Emit (OpCodes.Callvirt, ctx.nodesStack.Peek ().AddMethod); + ctx.il.Emit (OpCodes.Callvirt, ctx.CurrentAddMethod); ctx.il.Emit (OpCodes.Stloc_0); //reset local to current go - ctx.nodesStack.Peek ().Index++; + ctx.CurrentIndex++; break; } @@ -421,7 +419,7 @@ namespace Crow Array.Copy (currentNode.ToArray (), targetNode, ptr + 1); NodeAddress targetNA = new NodeAddress (targetNode); - string [] bindTrg = bindingExp [currentNode.Count - 1 - ptr].Split ('.'); + string [] bindTrg = bindingExp.Last().Split ('.'); if (bindTrg.Length == 1) memberName = bindTrg [0]; @@ -504,7 +502,7 @@ namespace Crow //by default, source value type is deducted from target member type to allow //memberless binding, if targetMember exists, it will be used to determine target //value type for conversion - PropertyInfo piSource = ctx.CurrentNode.CrowType.GetProperty(sourceMember); + PropertyInfo piSource = ctx.CurrentNodeType.GetProperty(sourceMember); Type sourceValueType = piSource.PropertyType; //il.Emit (OpCodes.Call, typeof(object).GetMethod("GetType")); @@ -642,17 +640,9 @@ namespace Crow NodeAddress origine = bindings.Key; NodeAddress destination = ma.Address; - if (origine.Count < destination.Count){ - for (int j = origine.Count-1; j < destination.Count-1; j++){ - destination[j].EmitGetInstance(ilInit); - destination[j].EmitGetInstance(il); - } - }else{ - for (int j = destination.Count; j < origine.Count; j++){ - ilInit.Emit(OpCodes.Callvirt, typeof(ILayoutable).GetProperty("Parent").GetGetMethod()); - il.Emit(OpCodes.Callvirt, typeof(ILayoutable).GetProperty("Parent").GetGetMethod()); - } - } + emitGetInstance(il,origine,destination); + emitGetInstance(ilInit,origine,destination); + //init dynmeth: load actual value ilInit.Emit (OpCodes.Ldarg_0); ilInit.Emit (OpCodes.Callvirt, origineNodeType.GetProperty (bindingCase.Key).GetGetMethod()); @@ -681,8 +671,38 @@ namespace Crow il.Emit (OpCodes.Ret); bindingDelegates [bindings.Key.ToString()] = dm.CreateDelegate (typeof(EventHandler<ValueChangeEventArgs>)); - bindingDelegates [bindings.Key.ToString()] = dmInit.CreateDelegate (typeof(Action<object>)); + bindingInitializer [bindings.Key.ToString()] = dmInit.CreateDelegate (typeof(Action<object>)); + } + } + void emitGetInstance (ILGenerator il, NodeAddress orig, NodeAddress dest){ + if (orig.Count < dest.Count){ + for (int i = orig.Count-1; i < dest.Count-1; i++){ + if (typeof (Group).IsAssignableFrom (dest[i].CrowType)) { + il.Emit (OpCodes.Ldfld, typeof(Group).GetField ("children", BindingFlags.Instance | BindingFlags.NonPublic)); + il.Emit(OpCodes.Ldc_I4, dest[i+1].Index); + il.Emit (OpCodes.Callvirt, typeof(List<GraphicObject>).GetMethod("get_Item", new Type[] { typeof(Int32) })); + continue; + } + if (typeof(Container).IsAssignableFrom (dest[i].CrowType) || dest[i+1].Index < 0) { + il.Emit (OpCodes.Ldfld, typeof(PrivateContainer).GetField ("child", BindingFlags.Instance | BindingFlags.NonPublic)); + continue; + } + if (typeof(TemplatedContainer).IsAssignableFrom (dest[i].CrowType)) { + il.Emit (OpCodes.Callvirt, typeof(TemplatedContainer).GetProperty ("Content").GetGetMethod ()); + continue; + } + if (typeof(TemplatedGroup).IsAssignableFrom (dest[i].CrowType)) { + il.Emit (OpCodes.Callvirt, typeof(TemplatedGroup).GetProperty ("Items").GetGetMethod ()); + il.Emit(OpCodes.Ldc_I4, dest[i+1].Index); + il.Emit (OpCodes.Callvirt, typeof(List<GraphicObject>).GetMethod("get_Item", new Type[] { typeof(Int32) })); + continue; + } + } + return; } + + for (int j = dest.Count; j < orig.Count; j++) + il.Emit(OpCodes.Callvirt, typeof(ILayoutable).GetProperty("Parent").GetGetMethod()); } void emitConvert(ILGenerator il, Type origType, Type destType){ if (destType == typeof (string)) |