]> O.S.I.I.S - jp/crow.git/commitdiff
IMLInstantiator implementation
authorjpbruyere <jp.bruyere@hotmail.com>
Mon, 8 Aug 2016 17:22:52 +0000 (19:22 +0200)
committerjpbruyere <jp.bruyere@hotmail.com>
Mon, 8 Aug 2016 17:22:52 +0000 (19:22 +0200)
19 files changed:
Crow.csproj
Templates/CheckBox.goml
Tests/BasicTests.cs
Tests/Interfaces/basicTests/0.crow
src/CompilerServices/Bindings.cs
src/CompilerServices/CompilerServices.cs
src/GraphicObjects/Container.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Grid.cs
src/GraphicObjects/Group.cs
src/GraphicObjects/IBindable.cs [deleted file]
src/GraphicObjects/ListBox.cs
src/GraphicObjects/PrivateContainer.cs
src/GraphicObjects/Scroller.cs
src/GraphicObjects/TabView.cs
src/IMLInstantiatorBuilder.cs [new file with mode: 0644]
src/IMLStream.cs
src/Instantiator.cs [new file with mode: 0644]
src/Interface.cs

index 7dde305f39ac8c40491ac2f50c48c55c634d17a8..35a18de941e16f7febba929bfce52885615755ce 100644 (file)
     <Compile Include="src\rsvg\RsvgSharp.SizeFuncNative.cs" />
     <Compile Include="src\rsvg\SizeFunc.cs" />
     <Compile Include="src\MouseCursorChangedEventArgs.cs" />
-    <Compile Include="src\GraphicObjects\IBindable.cs" />
     <Compile Include="src\Input\KeyPressEventArgs.cs" />
     <Compile Include="src\Configuration.cs" />
     <Compile Include="src\Measure.cs" />
     <Compile Include="src\StyleReader.cs" />
     <Compile Include="src\IMLStream.cs" />
     <Compile Include="src\GraphicObjects\DirectoryView.cs" />
+    <Compile Include="src\IMLInstantiatorBuilder.cs" />
+    <Compile Include="src\Instantiator.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
index 818e10c1ef7ffef49dd950f4bc2ddc216802c3e8..a6f26555150902f761980c319d61814caa766b29 100755 (executable)
@@ -1,6 +1,3 @@
 <?xml version="1.0"?>
-<HorizontalStack Background="{./Background}" Margin="1" Spacing="1" Height="{./HeightPolicy}" Width="{./WidthPolicy}">
-       <Image Margin="2" Width="14"  Height="14" Path="#Crow.Images.Icons.checkbox.svg"
-               SvgSub="{./IsChecked}"/>
-       <Label Font="{./Font}" Text="{./Caption}" Height="{./HeightPolicy}" Width="{./WidthPolicy}"/>
-</HorizontalStack>
\ No newline at end of file
+
+       <Label/>
index 2a82bd238a31bc7b38defafaff3db37cc814bf87..249c9abb31f2d72783b2f3db7ff6a5207edb0752 100644 (file)
@@ -93,9 +93,9 @@ namespace Tests
                        this.KeyDown += KeyboardKeyDown1;
 
                        testFiles = new string [] { @"Interfaces/Divers/welcome.crow" };
-                       testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/GraphicObject", "*.crow")).ToArray ();
-                       //testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/basicTests", "*.crow")).ToArray ();
+                       testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/basicTests", "*.crow")).ToArray ();
                        testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Container", "*.crow")).ToArray ();
+                       testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/GraphicObject", "*.crow")).ToArray ();
                        testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Group", "*.crow")).ToArray ();
                        testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Stack", "*.crow")).ToArray ();
                        testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Splitter", "*.crow")).ToArray ();
index b5c153ef89a39839b04d6b3ada4460a0b4a03a7e..9d3948af6a922327f6206f3b392612c2241f584d 100755 (executable)
@@ -1,6 +1,2 @@
 <?xml version="1.0"?>
-<Label Margin="50" Width="50%" Height="50%" TextAlignment="BottomRight" Background="Mantis"/>
-<!--<Container Background="Green" Margin="10" Width="Fit" Height="Fit">
-       <GraphicObject Margin="10" Width="{../WidthPolicy}" Height="{../HeightPolicy}" Background="Red"
-               MinimumSize="50,50"/>
-</Container>-->
\ No newline at end of file
+<CheckBox/>
\ No newline at end of file
index 8ece856c51ddc2d86515cab093c28f184cc0c71a..0ce8da6ea0cd161ee0b821bd2d49ad2f4d41a7ab 100644 (file)
@@ -41,6 +41,11 @@ namespace Crow
                public string DynMethodId {
                        get { return dynMethodId; }
                }
+               public Type SourceType {
+                       get { return Source == null ? null 
+                                       : Source.Instance == null ? null 
+                                       : Source.Instance.GetType();}
+               }
 
                public bool Resolved {
                        get { return resolved; }
@@ -185,12 +190,8 @@ namespace Crow
                        }
 
                        if (Target.TryFindMember (memberName)) {
-                               if (TwoWayBinding) {
-                                       IBindable source = Target.Instance as IBindable;
-                                       if (source == null)
-                                               throw new Exception (Source.Instance + " does not implement IBindable for 2 way bindings");
-                                       source.Bindings.Add (new Binding (Target, Source));
-                               }
+                               if (TwoWayBinding)
+                                       Interface.RegisterBinding (new Binding (Target, Source));                               
                        }
                        #if DEBUG_BINDING
                        else
index 0b69f970779c73c1539702818994551f787e09e2..137ce626a259904053afb9faa2ea1adcf208b318 100644 (file)
@@ -5,12 +5,258 @@ using System.Diagnostics;
 using System.Linq;
 using System.Collections.Generic;
 using System.Runtime.CompilerServices;
+using System.Xml;
 
 
 namespace Crow
 {
        public static class CompilerServices
        {
+               public static void BuildInstanciator(IMLInstantiatorBuilder builder, Type crowType){
+                       string tmpXml = builder.ReadOuterXml ();
+
+                       builder.il.Emit (OpCodes.Ldloc_0);//save current go onto the stack if child has to be added
+
+                       if (typeof(TemplatedControl).IsAssignableFrom (crowType)) {
+                               //if its a template, first read template elements
+                               using (IMLInstantiatorBuilder reader = new IMLInstantiatorBuilder (builder.il, tmpXml)) {
+
+                                       string template = reader.GetAttribute ("Template");
+
+                                       bool inlineTemplate = false;
+                                       if (string.IsNullOrEmpty (template)) {
+                                               reader.Read ();
+
+                                               while (reader.Read ()) {
+                                                       if (!reader.IsStartElement ())
+                                                               continue;
+                                                       if (reader.Name == "Template") {
+                                                               inlineTemplate = true;
+                                                               reader.Read ();
+
+                                                               readChildren (reader, crowType);
+                                                               continue;
+                                                       }
+                                               }
+                                               if (!inlineTemplate) {
+                                                       DefaultTemplate dt = (DefaultTemplate)crowType.GetCustomAttributes (typeof(DefaultTemplate), true).FirstOrDefault();
+                                                       template = dt.Path;
+                                               }
+                                       } 
+                                       if (!inlineTemplate) {
+                                               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.Callvirt,//add child
+                                                       typeof(PrivateContainer).GetMethod ("SetChild", BindingFlags.Instance | BindingFlags.NonPublic));                                               
+                                       }
+                               }
+                       }
+
+                       using (IMLInstantiatorBuilder reader = new IMLInstantiatorBuilder(builder.il,tmpXml)){
+                               reader.Read ();
+
+                               if (reader.HasAttributes) {
+                                       string style = reader.GetAttribute ("Style");
+                                       if (!string.IsNullOrEmpty (style)) {
+                                               PropertyInfo pi = crowType.GetProperty ("Style");
+                                               CompilerServices.EmitSetValue (reader.il, pi, style);
+                                       }
+                               }
+                               if (reader.HasAttributes) {
+                                       reader.il.Emit (OpCodes.Ldloc_0);
+                                       reader.il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetMethod ("loadDefaultValues"));
+
+                                       while (reader.MoveToNextAttribute ()) {
+                                               if (reader.Name == "Style")
+                                                       continue;
+
+                                               PropertyInfo pi = crowType.GetProperty (reader.Name);
+
+                                               if (pi == null)
+                                                       throw new Exception ("Member '" + reader.Name + "' not found in " + crowType.Name);
+
+                                               CompilerServices.EmitSetValue (reader.il, pi, reader.Value);
+
+                                       }
+                                       reader.MoveToElement ();
+                               }
+
+                               if (reader.IsEmptyElement) {
+                                       reader.il.Emit (OpCodes.Pop);//pop saved ref to current object
+                                       return;
+                               }
+
+                               readChildren (reader, crowType);
+                       }
+                       builder.il.Emit (OpCodes.Pop);//pop saved ref to current object
+               }
+               static void readChildren(IMLInstantiatorBuilder reader, Type crowType){
+                       MethodInfo miAddChild = null;
+                       bool endTagReached = false;
+                       while (reader.Read()){
+                               switch (reader.NodeType) {
+                               case XmlNodeType.EndElement:
+                                       endTagReached = true;
+                                       break;
+                               case XmlNodeType.Element:
+                                       //Templates
+
+
+                                       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(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]);
+                                       reader.il.Emit (OpCodes.Stloc_0);//child is now loc_0
+
+                                       BuildInstanciator(reader, t);
+
+                                       reader.il.Emit (OpCodes.Ldloc_0);//load child on stack for parenting
+                                       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;
+                       }                       
+               }
+               public static void EmitSetValue(ILGenerator il, PropertyInfo pi, object val){
+                       il.Emit (OpCodes.Ldloc_0);
+
+                       if (val == null) {
+                               il.Emit (OpCodes.Ldnull);
+                               il.Emit (OpCodes.Callvirt, pi.GetSetMethod ());
+                               return;
+                       }
+                       Type dvType = val.GetType ();
+
+                       if (dvType.IsValueType) {
+                               if (pi.PropertyType.IsValueType) {
+                                       if (pi.PropertyType.IsEnum) {
+                                               if (pi.PropertyType != dvType)
+                                                       throw new Exception ("Enum mismatch in default values: " + pi.PropertyType.FullName);
+                                               il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (val));
+                                       } else {
+                                               switch (Type.GetTypeCode (dvType)) {
+                                               case TypeCode.Boolean:
+                                                       if ((bool)val == true)
+                                                               il.Emit (OpCodes.Ldc_I4_1);
+                                                       else
+                                                               il.Emit (OpCodes.Ldc_I4_0);
+                                                       break;
+                                                       //                                              case TypeCode.Empty:
+                                                       //                                                      break;
+                                                       //                                              case TypeCode.Object:
+                                                       //                                                      break;
+                                                       //                                              case TypeCode.DBNull:
+                                                       //                                                      break;
+                                                       //                                              case TypeCode.SByte:
+                                                       //                                                      break;
+                                                       //                                              case TypeCode.Decimal:
+                                                       //                                                      break;
+                                                       //                                              case TypeCode.DateTime:
+                                                       //                                                      break;
+                                               case TypeCode.Char:
+                                                       il.Emit (OpCodes.Ldc_I4, Convert.ToChar (val));
+                                                       break;
+                                               case TypeCode.Byte:
+                                               case TypeCode.Int16:
+                                               case TypeCode.Int32:
+                                                       il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (val));
+                                                       break;
+                                               case TypeCode.UInt16:
+                                               case TypeCode.UInt32:
+                                                       il.Emit (OpCodes.Ldc_I4, Convert.ToUInt32 (val));
+                                                       break;
+                                               case TypeCode.Int64:
+                                                       il.Emit (OpCodes.Ldc_I8, Convert.ToInt64 (val));
+                                                       break;
+                                               case TypeCode.UInt64:
+                                                       il.Emit (OpCodes.Ldc_I8, Convert.ToUInt64 (val));
+                                                       break;
+                                               case TypeCode.Single:
+                                                       il.Emit (OpCodes.Ldc_R4, Convert.ToSingle (val));
+                                                       break;
+                                               case TypeCode.Double:
+                                                       il.Emit (OpCodes.Ldc_R8, Convert.ToDouble (val));
+                                                       break;
+                                               case TypeCode.String:
+                                                       il.Emit (OpCodes.Ldstr, Convert.ToString (val));
+                                                       break;
+                                               default:
+                                                       il.Emit (OpCodes.Pop);
+                                                       return;
+                                               }
+                                       }
+                               } else
+                                       throw new Exception ("Expecting valuetype in default values for: " + pi.Name);
+                       }else{
+                               //surely a class or struct
+                               if (dvType != typeof(string))
+                                       throw new Exception ("Expecting String in default values for: " + pi.Name);
+                               if (pi.PropertyType == typeof(string))
+                                       il.Emit (OpCodes.Ldstr, Convert.ToString (val));
+                               else if (pi.PropertyType.IsEnum) {
+                                       MethodInfo miParse = typeof(Enum).GetMethod
+                                               ("Parse", BindingFlags.Static | BindingFlags.Public,
+                                                       Type.DefaultBinder, new Type [] {typeof (Type), typeof (string), typeof (bool)}, null);
+
+                                       if (miParse == null)
+                                               throw new Exception ("Enum Parse method not found");
+
+                                       //load type of enum
+                                       il.Emit(OpCodes.Ldtoken, pi.PropertyType);
+                                       il.Emit(OpCodes.Call, typeof(Type).GetMethod("GetTypeFromHandle", new
+                                               Type[1]{typeof(RuntimeTypeHandle)}));
+                                       //load enum value name
+                                       il.Emit (OpCodes.Ldstr, Convert.ToString (val));//TODO:is this convert required?
+                                       //load false
+                                       il.Emit (OpCodes.Ldc_I4_0);
+                                       il.Emit (OpCodes.Callvirt, miParse);
+
+                                       if (miParse.ReturnType != pi.PropertyType)
+                                               il.Emit (OpCodes.Unbox_Any, pi.PropertyType);                                   
+                               } else {
+                                       MethodInfo miParse = pi.PropertyType.GetMethod
+                                               ("Parse", BindingFlags.Static | BindingFlags.Public,
+                                                       Type.DefaultBinder, new Type [] {typeof (string)},null);
+                                       if (miParse == null)
+                                               throw new Exception ("no Parse method found for: " + pi.PropertyType.FullName);
+
+                                       il.Emit (OpCodes.Ldstr, Convert.ToString (val));//TODO:is this convert required?
+                                       il.Emit (OpCodes.Callvirt, miParse);
+
+                                       if (miParse.ReturnType != pi.PropertyType)
+                                               il.Emit (OpCodes.Unbox_Any, pi.PropertyType);
+                               }
+                       }
+                       il.Emit (OpCodes.Callvirt, pi.GetSetMethod ());                 
+               }
                public static void ResolveBindings (List<Binding> Bindings)
                {
                        if (Bindings == null)
index 69e3a3b4136a9e08ba1d6bb64b7b89c4f5b64c47..9acbf03a465d1559f52b6e878847cf6e09131377 100644 (file)
@@ -4,6 +4,7 @@ using System.Reflection;
 using System.ComponentModel;
 using System.Linq;
 using System.Threading;
+using System.Diagnostics;
 
 namespace Crow
 {
@@ -25,9 +26,10 @@ namespace Crow
                        get { return child; }
                        set { child = value; }
                }
-               public virtual T SetChild<T> (T _child)
+               public virtual void SetChild(GraphicObject _child)
                {
-                       return base.SetChild (_child);
+                       Debug.WriteLine ("container setChild");
+                       base.SetChild (_child);
                }
 
                #region IXmlSerializable
index 8966acf6fae61605d0c80493c77f7456e01f6154..fb9f592d1cb406283869c431988ce8f4014e4d2b 100644 (file)
@@ -12,16 +12,8 @@ using System.IO;
 
 namespace Crow
 {
-       public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange, ICloneable, IBindable
+       public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange, ICloneable
        {
-               #region IBindable implementation
-               List<Binding> bindings = new List<Binding> ();
-               public List<Binding> Bindings {
-                       get { return bindings; }
-               }
-
-               #endregion
-
                internal static ulong currentUid = 0;
                internal ulong uid = 0;
 
@@ -513,7 +505,7 @@ namespace Crow
                #endregion
 
                /// <summary> Loads the default values from XML attributes default </summary>
-               protected virtual void loadDefaultValues()
+               public void loadDefaultValues()
                {
                        #if DEBUG_LOAD
                        Debug.WriteLine ("LoadDefValues for " + this.ToString ());
@@ -581,151 +573,70 @@ namespace Crow
                                typeof(void),new Type[] {typeof(object)},thisType,true);
 
                        il = dm.GetILGenerator(256);
-
+                       il.DeclareLocal(typeof(GraphicObject));
                        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 (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
-                               string name = "";
-                               object defaultValue = null;
-
-                               #region retrieve custom attributes
+                       foreach (PropertyInfo pi in thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)) {                              
                                if (pi.GetSetMethod () == null)
                                        continue;
-
-                               XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute));
-                               if (xia != null)
+                               object defaultValue;
+                               if (!getDefaultValue (pi, styling, out defaultValue))
                                        continue;
-                               XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
-                               if (xaa != null) {
-                                       if (string.IsNullOrEmpty (xaa.AttributeName))
-                                               name = pi.Name;
-                                       else
-                                               name = xaa.AttributeName;
-                               }
 
-                               int styleIndex = -1;
-                               if (styling.Count > 0){
-                                       for (int i = 0; i < styling.Count; i++) {
-                                               if (styling[i].ContainsKey (name)){
-                                                       styleIndex = i;
-                                                       break;
-                                               }
-                                       }
-                               }
-                               if (styleIndex >= 0){
-                                       if (pi.PropertyType.IsEnum)//maybe should be in parser..
-                                               defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true);
-                                       else
-                                               defaultValue = styling[styleIndex] [name];
-                               }else {
-                                       DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute));
-                                       if (dv == null)
-                                               continue;
-                                       defaultValue = dv.Value;
-                               }
-                               #endregion
-
-                               il.Emit (OpCodes.Ldarg_0);
-
-                               if (defaultValue == null) {
-                                       il.Emit (OpCodes.Ldnull);
-                                       il.Emit (OpCodes.Callvirt, pi.GetSetMethod ());
-                                       continue;
-                               }
-                               Type dvType = defaultValue.GetType ();
-
-                               if (dvType.IsValueType) {
-                                       if (pi.PropertyType.IsValueType) {
-                                               if (pi.PropertyType.IsEnum) {
-                                                       if (pi.PropertyType != dvType)
-                                                               throw new Exception ("Enum mismatch in default values: " + pi.PropertyType.FullName);
-                                                       il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (defaultValue));
-                                               } else {
-                                                       switch (Type.GetTypeCode (dvType)) {
-                                                       case TypeCode.Boolean:
-                                                               if ((bool)defaultValue == true)
-                                                                       il.Emit (OpCodes.Ldc_I4_1);
-                                                               else
-                                                                       il.Emit (OpCodes.Ldc_I4_0);
-                                                               break;
-//                                             case TypeCode.Empty:
-//                                                     break;
-//                                             case TypeCode.Object:
-//                                                     break;
-//                                             case TypeCode.DBNull:
-//                                                     break;
-//                                             case TypeCode.SByte:
-//                                                     break;
-//                                             case TypeCode.Decimal:
-//                                                     break;
-//                                             case TypeCode.DateTime:
-//                                                     break;
-                                                       case TypeCode.Char:
-                                                               il.Emit (OpCodes.Ldc_I4, Convert.ToChar (defaultValue));
-                                                               break;
-                                                       case TypeCode.Byte:
-                                                       case TypeCode.Int16:
-                                                       case TypeCode.Int32:
-                                                               il.Emit (OpCodes.Ldc_I4, Convert.ToInt32 (defaultValue));
-                                                               break;
-                                                       case TypeCode.UInt16:
-                                                       case TypeCode.UInt32:
-                                                               il.Emit (OpCodes.Ldc_I4, Convert.ToUInt32 (defaultValue));
-                                                               break;
-                                                       case TypeCode.Int64:
-                                                               il.Emit (OpCodes.Ldc_I8, Convert.ToInt64 (defaultValue));
-                                                               break;
-                                                       case TypeCode.UInt64:
-                                                               il.Emit (OpCodes.Ldc_I8, Convert.ToUInt64 (defaultValue));
-                                                               break;
-                                                       case TypeCode.Single:
-                                                               il.Emit (OpCodes.Ldc_R4, Convert.ToSingle (defaultValue));
-                                                               break;
-                                                       case TypeCode.Double:
-                                                               il.Emit (OpCodes.Ldc_R8, Convert.ToDouble (defaultValue));
-                                                               break;
-                                                       case TypeCode.String:
-                                                               il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue));
-                                                               break;
-                                                       default:
-                                                               il.Emit (OpCodes.Pop);
-                                                               continue;
-                                                       }
-                                               }
-                                       } else
-                                               throw new Exception ("Expecting valuetype in default values for: " + pi.Name);
-                               }else{
-                                       //surely a class or struct
-                                       if (dvType != typeof(string))
-                                               throw new Exception ("Expecting String in default values for: " + pi.Name);
-                                       if (pi.PropertyType == typeof (string))
-                                               il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue));
-                                       else {
-                                               MethodInfo miParse = pi.PropertyType.GetMethod
-                                                                      ("Parse", BindingFlags.Static | BindingFlags.Public,
-                                                                       Type.DefaultBinder, new Type [] {typeof (string)},null);
-                                               if (miParse == null)
-                                                       throw new Exception ("no Parse method found for: " + pi.PropertyType.FullName);
-
-                                               il.Emit (OpCodes.Ldstr, Convert.ToString (defaultValue));
-                                               il.Emit (OpCodes.Callvirt, miParse);
-
-                                               if (miParse.ReturnType != pi.PropertyType)
-                                                       il.Emit (OpCodes.Unbox_Any, pi.PropertyType);
-                                       }
-                               }
-                               il.Emit (OpCodes.Callvirt, pi.GetSetMethod ());
+                               CompilerServices.EmitSetValue (il, pi, defaultValue);
                        }
                        il.Emit(OpCodes.Ret);
                        #endregion
 
                        try {
-                               Interface.DefaultValuesLoader[styleKey] = (Interface.loadDefaultInvoker)dm.CreateDelegate(typeof(Interface.loadDefaultInvoker));
+                               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);
                        }
                }
+               bool getDefaultValue(PropertyInfo pi, List<Dictionary<string, object>> styling,
+                       out object defaultValue){
+                       defaultValue = null;
+                       string name = "";
+
+                       XmlIgnoreAttribute xia = (XmlIgnoreAttribute)pi.GetCustomAttribute (typeof(XmlIgnoreAttribute));
+                       if (xia != null)
+                               return false;
+                       XmlAttributeAttribute xaa = (XmlAttributeAttribute)pi.GetCustomAttribute (typeof(XmlAttributeAttribute));
+                       if (xaa != null) {
+                               if (string.IsNullOrEmpty (xaa.AttributeName))
+                                       name = pi.Name;
+                               else
+                                       name = xaa.AttributeName;
+                       }
+
+                       int styleIndex = -1;
+                       if (styling.Count > 0){
+                               for (int i = 0; i < styling.Count; i++) {
+                                       if (styling[i].ContainsKey (name)){
+                                               styleIndex = i;
+                                               break;
+                                       }
+                               }
+                       }
+                       if (styleIndex >= 0){
+                               if (pi.PropertyType.IsEnum)//maybe should be in parser..
+                                       defaultValue = Enum.Parse(pi.PropertyType, (string)styling[styleIndex] [name], true);
+                               else
+                                       defaultValue = styling[styleIndex] [name];
+                       }else {
+                               DefaultValueAttribute dv = (DefaultValueAttribute)pi.GetCustomAttribute (typeof (DefaultValueAttribute));
+                               if (dv == null)
+                                       return false;
+                               defaultValue = dv.Value;
+                       }
+                       return true;
+               }
+
 
                public virtual GraphicObject FindByName(string nameToFind){
                        return string.Equals(nameToFind, _name, StringComparison.Ordinal) ? this : null;
@@ -747,7 +658,7 @@ namespace Crow
                        if (Width == Measure.Fit || Height == Measure.Fit)
                                RegisterForLayouting (LayoutingType.Sizing);
                        else if (RegisteredLayoutings == LayoutingType.None)
-                               Interface.CurrentInterface.EnqueueForRepaint (this);
+                               CurrentInterface.EnqueueForRepaint (this);
                }
                /// <summary> query an update of the content, a redraw </summary>
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -755,8 +666,20 @@ namespace Crow
                {
                        bmp = null;
                        if (RegisteredLayoutings == LayoutingType.None)
-                               Interface.CurrentInterface.EnqueueForRepaint (this);
+                               CurrentInterface.EnqueueForRepaint (this);
                }
+               public Interface CurrentInterface {
+                       get {
+                               ILayoutable tmp = this.Parent;
+                               while (tmp != null) {
+                                       if (tmp is Interface)
+                                               return tmp as Interface;
+                                       tmp = tmp.Parent;
+                               }
+                               return null;
+                       }
+               }
+
                #region Layouting
 
                #if DEBUG_LAYOUTING
@@ -1200,18 +1123,15 @@ namespace Crow
                }
 
                #region Binding
-               public void BindMember(string _member, string _expression){
-                       Bindings.Add(new Binding (this, _member, _expression));
-               }
                public virtual void ResolveBindings()
                {
-                       if (Bindings.Count == 0)
-                               return;
-                       #if DEBUG_BINDING
-                       Debug.WriteLine ("Resolve Bindings => " + this.ToString ());
-                       #endif
-
-                       CompilerServices.ResolveBindings (Bindings);
+//                     if (Bindings.Count == 0)
+//                             return;
+//                     #if DEBUG_BINDING
+//                     Debug.WriteLine ("Resolve Bindings => " + this.ToString ());
+//                     #endif
+//
+//                     CompilerServices.ResolveBindings (Bindings);
                }
 
                /// <summary>
@@ -1220,53 +1140,53 @@ namespace Crow
                /// </summary>
                public virtual void ClearBinding(){
                        //dont clear binding if dataSource is not null,
-                       foreach (Binding b in Bindings) {
-                               try {
-                                       if (!b.Resolved)
-                                               continue;
-                                       //cancel compiled events
-                                       if (b.Target == null){
-                                               continue;
-                                               #if DEBUG_BINDING
-                                               Debug.WriteLine("Clear binding canceled for => " + b.ToString());
-                                               #endif
-                                       }
-                                       if (b.Target.Instance != DataSource){
-                                               #if DEBUG_BINDING
-                                               Debug.WriteLine("Clear binding canceled for => " + b.ToString());
-                                               #endif
-                                               continue;
-                                       }
-                                       #if DEBUG_BINDING
-                                       Debug.WriteLine("ClearBinding => " + b.ToString());
-                                       #endif
-                                       if (string.IsNullOrEmpty (b.DynMethodId)) {
-                                               b.Resolved = false;
-                                               if (b.Source.Member.MemberType == MemberTypes.Event)
-                                                       removeEventHandler (b);
-                                               //TODO:check if full reset is necessary
-                                               continue;
-                                       }
-                                       MemberReference mr = null;
-                                       if (b.Target == null)
-                                               mr = b.Source;
-                                       else
-                                               mr = b.Target;
-                                       Type dataSourceType = mr.Instance.GetType();
-                                       EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged");
-                                       FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged");
-                                       MulticastDelegate multicastDelegate = evtFi.GetValue (mr.Instance) as MulticastDelegate;
-                                       if (multicastDelegate != null) {
-                                               foreach (Delegate d in multicastDelegate.GetInvocationList()) {
-                                                       if (d.Method.Name == b.DynMethodId)
-                                                               evtInfo.RemoveEventHandler (mr.Instance, d);
-                                               }
-                                       }
-                                       b.Reset ();
-                               } catch (Exception ex) {
-                                       Debug.WriteLine("\t Error: " + ex.ToString());
-                               }
-                       }
+//                     foreach (Binding b in Bindings) {
+//                             try {
+//                                     if (!b.Resolved)
+//                                             continue;
+//                                     //cancel compiled events
+//                                     if (b.Target == null){
+//                                             continue;
+//                                             #if DEBUG_BINDING
+//                                             Debug.WriteLine("Clear binding canceled for => " + b.ToString());
+//                                             #endif
+//                                     }
+//                                     if (b.Target.Instance != DataSource){
+//                                             #if DEBUG_BINDING
+//                                             Debug.WriteLine("Clear binding canceled for => " + b.ToString());
+//                                             #endif
+//                                             continue;
+//                                     }
+//                                     #if DEBUG_BINDING
+//                                     Debug.WriteLine("ClearBinding => " + b.ToString());
+//                                     #endif
+//                                     if (string.IsNullOrEmpty (b.DynMethodId)) {
+//                                             b.Resolved = false;
+//                                             if (b.Source.Member.MemberType == MemberTypes.Event)
+//                                                     removeEventHandler (b);
+//                                             //TODO:check if full reset is necessary
+//                                             continue;
+//                                     }
+//                                     MemberReference mr = null;
+//                                     if (b.Target == null)
+//                                             mr = b.Source;
+//                                     else
+//                                             mr = b.Target;
+//                                     Type dataSourceType = mr.Instance.GetType();
+//                                     EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged");
+//                                     FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged");
+//                                     MulticastDelegate multicastDelegate = evtFi.GetValue (mr.Instance) as MulticastDelegate;
+//                                     if (multicastDelegate != null) {
+//                                             foreach (Delegate d in multicastDelegate.GetInvocationList()) {
+//                                                     if (d.Method.Name == b.DynMethodId)
+//                                                             evtInfo.RemoveEventHandler (mr.Instance, d);
+//                                             }
+//                                     }
+//                                     b.Reset ();
+//                             } catch (Exception ex) {
+//                                     Debug.WriteLine("\t Error: " + ex.ToString());
+//                             }
+//                     }
                }
                void removeEventHandler(Binding b){
                        FieldInfo fiEvt = CompilerServices.GetEventHandlerField (b.Source.Instance.GetType(), b.Source.Member.Name);
@@ -1297,7 +1217,7 @@ namespace Crow
                                return;
                        }
                        if (mi.MemberType == MemberTypes.Event) {
-                               this.Bindings.Add (new Binding (new MemberReference(this, mi), value));
+                               Interface.RegisterBinding (new Binding (new MemberReference(this, mi), value));
                                return;
                        }
                        if (mi.MemberType == MemberTypes.Property) {
@@ -1318,7 +1238,7 @@ namespace Crow
                                        if (!value.EndsWith("}", StringComparison.Ordinal))
                                                throw new Exception (string.Format("XML:Malformed binding: {0}", value));
 
-                                       this.Bindings.Add (new Binding (new MemberReference(this, pi), value.Substring (1, value.Length - 2)));
+                                       Interface.RegisterBinding (new Binding (new MemberReference(this, pi), value.Substring (1, value.Length - 2)));
                                        return;
                                }
                                if (pi.GetCustomAttribute (typeof(XmlIgnoreAttribute)) != null)
@@ -1341,21 +1261,34 @@ namespace Crow
                }
                public virtual void ReadXml (System.Xml.XmlReader reader)
                {
-                       if (reader.HasAttributes) {                             
-
-                               style = reader.GetAttribute ("Style");
+                       IMLInstantiatorBuilder ir = reader as IMLInstantiatorBuilder;
+                       Type thisType = this.GetType ();
 
-                               loadDefaultValues ();
+                       if (ir.HasAttributes) {
+                               style = ir.GetAttribute ("Style");
+                               if (!string.IsNullOrEmpty (style)) {
+                                       PropertyInfo pi = thisType.GetProperty ("Style");
+                                       CompilerServices.EmitSetValue (ir.il, pi, style);
+                               }
+                       }
+                       if (ir.HasAttributes) {
+                               ir.il.Emit (OpCodes.Ldarg_0);
+                               ir.il.Emit (OpCodes.Callvirt, typeof(GraphicObject).GetMethod ("loadDefaultValues"));
 
-                               while (reader.MoveToNextAttribute ()) {
-                                       if (reader.Name == "Style")
+                               while (ir.MoveToNextAttribute ()) {
+                                       if (ir.Name == "Style")
                                                continue;
 
-                                       affectMember (reader.Name, reader.Value);
+                                       PropertyInfo pi = thisType.GetProperty (ir.Name);
+
+                                       if (pi == null)
+                                               throw new Exception ("Member '" + ir.Name + "' not found in " + thisType.Name);
+
+                                       CompilerServices.EmitSetValue (ir.il, pi, ir.Value);
+
                                }
-                               reader.MoveToElement ();
-                       }else
-                               loadDefaultValues ();
+                               ir.MoveToElement ();
+                       }
                }
                public virtual void WriteXml (System.Xml.XmlWriter writer)
                {
@@ -1445,6 +1378,8 @@ namespace Crow
                }
                #endregion
 
+
+
                #region ICloneable implementation
                public object Clone ()
                {
@@ -1470,8 +1405,8 @@ namespace Crow
                /// </summary>
                public virtual GraphicObject DeepClone(){
                        GraphicObject tmp = Clone () as GraphicObject;
-                       foreach (Binding b in this.bindings)
-                               tmp.Bindings.Add (new Binding (new MemberReference (tmp, b.Source.Member), b.Expression));
+//                     foreach (Binding b in this.bindings)
+//                             tmp.Bindings.Add (new Binding (new MemberReference (tmp, b.Source.Member), b.Expression));
                        return tmp;
                }
        }
index 525827e0f8b217e9325ff5d07aa22ad593f9be91..ed0cd98607cd86e97caf7b5174a41da751c1fa02 100644 (file)
@@ -29,11 +29,10 @@ namespace Crow
                int _rowCount;
                #endregion
 
-               public override T AddChild<T> (T child)
+               public override void AddChild (GraphicObject child)
                {
-                       T tmp = base.AddChild (child);
+                       base.AddChild (child);
                        this.RegisterForLayouting (LayoutingType.ArrangeChildren);
-                       return tmp;
                }
                public override void RemoveChild (GraphicObject child)
                {
index a6ca5758f613e1e223c3119d873e72187d31d9f4..4c8d0537899ddd5d2c2b3fc326caa8c851f0cc9d 100644 (file)
@@ -38,19 +38,14 @@ namespace Crow
             get { return _multiSelect; }
             set { _multiSelect = value; }
         }
-                       
-                       
-        public virtual T AddChild<T>(T child)
-        {
-                       GraphicObject g = child as GraphicObject;
+               public virtual void AddChild(GraphicObject g){
                        Children.Add(g);
-                       g.Parent = this as GraphicObject;
+                       g.Parent = this;
                        g.ResolveBindings ();
                        g.RegisteredLayoutings = LayoutingType.None;
                        g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
                        g.LayoutChanged += OnChildLayoutChanges;
-            return (T)child;
-        }
+               }
         public virtual void RemoveChild(GraphicObject child)        
                {
                        child.LayoutChanged -= OnChildLayoutChanges;
diff --git a/src/GraphicObjects/IBindable.cs b/src/GraphicObjects/IBindable.cs
deleted file mode 100644 (file)
index 45ff586..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-//  IValueChange.cs
-//
-//  Author:
-//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
-//
-//  Copyright (c) 2015 jp
-//
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-using System;
-using System.Collections.Generic;
-
-namespace Crow
-{
-       public interface IBindable
-       {
-               List<Binding> Bindings { get; }
-               object DataSource { get; set; }
-       }
-}
-
index 58d41e0ba177763b249ea159287a68501b900c96..397ef53d170707051a82df6cab0a431c1e22481a 100644 (file)
@@ -151,10 +151,10 @@ namespace Crow
                        //because _list total size is forced to approx size
                        if (_gsList.Orientation == Orientation.Horizontal) {
                                page.Width = Measure.Fit;
-                               page.BindMember ("Height", "../HeightPolicy");
+                               Interface.Bindings.Add(new Binding (this, "Height", "../HeightPolicy"));
                        } else {
                                page.Height = Measure.Fit;
-                               page.BindMember ("Width", "../WidthPolicy");
+                               Interface.Bindings.Add(new Binding (this, "Width", "../WidthPolicy"));
                        }
 
                        for (int i = (pageNum - 1) * itemPerPage; i < pageNum * itemPerPage; i++) {
index 8793ba4533e052b7c10542ef379106bdb881493e..51d766048a40cbf9b1e12fa0dde3463a6df9a44a 100644 (file)
@@ -22,6 +22,7 @@ using System;
 using System.Xml.Serialization;
 using System.ComponentModel;
 using Cairo;
+using System.Diagnostics;
 
 namespace Crow
 {
@@ -47,7 +48,7 @@ namespace Crow
 
                protected GraphicObject child;
 
-               protected virtual T SetChild<T>(T _child)
+               internal virtual void SetChild(GraphicObject _child)
                {
 
                        if (child != null) {
@@ -67,8 +68,8 @@ namespace Crow
                                child.RegisteredLayoutings = LayoutingType.None;
                                child.RegisterForLayouting (LayoutingType.Sizing);
                        }
+                       Debug.WriteLine ("privateContainer setChild");
 
-                       return (T)_child;
                }
 
                #region GraphicObject Overrides
index 3eaff5f4f324d2a3d1273cc12922eff55014983a..c248595d803971acd0397cc96d86fecdc5a3d7a1 100644 (file)
@@ -148,7 +148,7 @@ namespace Crow
                        ScrollY = 0;
                        ScrollX = 0;
                }
-               public override T SetChild<T> (T _child)
+               public override void SetChild (GraphicObject _child)
                {                       
                        GraphicObject c = child as GraphicObject;
                        Group g = child as Group;
@@ -164,7 +164,7 @@ namespace Crow
                                if (g != null)
                                        g.ChildrenCleared += onChildListCleared;                                
                        }
-                       return base.SetChild (_child);
+                       base.SetChild (_child);
                }
                #endregion
 
index d616ffc6a25256be8a7c1acf7b3592650de1c2b7..015f5f4f66ad0344d4f8adab101899c062aa22e3 100644 (file)
@@ -100,7 +100,7 @@ namespace Crow
                        set { }
                }
 
-               public override T AddChild<T> (T child)
+               public override void AddChild (GraphicObject child)
                {
                        TabItem ti = child as TabItem;
                        if (ti == null)
@@ -113,7 +113,7 @@ namespace Crow
                                SelectedTab = 0;
                        }
 
-                       return base.AddChild (child);
+                       base.AddChild (child);
                }
                public override void RemoveChild (GraphicObject child)
                {
diff --git a/src/IMLInstantiatorBuilder.cs b/src/IMLInstantiatorBuilder.cs
new file mode 100644 (file)
index 0000000..a9c078d
--- /dev/null
@@ -0,0 +1,100 @@
+//
+//  IMLReader.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2016 jp
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+using System;
+using System.Xml;
+using System.IO;
+using System.Reflection;
+using System.Reflection.Emit;
+
+namespace Crow
+{
+       public class IMLInstantiatorBuilder : XmlTextReader
+       {
+               public Stream ImlStream;
+               public Type RootType = null;
+
+               DynamicMethod dm = null;
+               public ILGenerator il = null;
+
+               public IMLInstantiatorBuilder (Stream stream) 
+                       : base(stream)
+               {
+                       ImlStream = stream;
+               }
+               public IMLInstantiatorBuilder (ILGenerator ilGen, string xmlFragment)
+                       : base(xmlFragment, XmlNodeType.Element,null){
+                       il = ilGen;
+               }
+               /// <summary>
+               /// Inits il generator, RootType must have been read first
+               /// </summary>
+               public void InitEmitter(){
+
+                       dm = new DynamicMethod("dyn_instantiator",
+                               MethodAttributes.Family | MethodAttributes.FamANDAssem | MethodAttributes.NewSlot,
+                               CallingConventions.Standard,
+                               typeof(void),new Type[] {typeof(object)}, RootType, true);
+
+                       il = dm.GetILGenerator(256);
+                       il.DeclareLocal(typeof(GraphicObject));
+                       il.Emit(OpCodes.Nop);
+                       //set local GraphicObject to root object passed as 1st argument
+                       il.Emit (OpCodes.Ldarg_0);
+                       il.Emit (OpCodes.Stloc_0);
+               }
+
+               /// <summary>
+               /// read first node to set GraphicObject class for loading
+               /// and let reader position on that node
+               /// </summary>
+               public Type ReadRootType ()
+               {
+                       string root = "Object";
+                       while (Read()) {
+                               if (NodeType == XmlNodeType.Element) {
+                                       root = this.Name;
+                                       break;
+                               }
+                       }
+
+                       Type t = Type.GetType ("Crow." + root);
+                       if (t == null) {
+                               Assembly a = Assembly.GetEntryAssembly ();
+                               foreach (Type expT in a.GetExportedTypes ()) {
+                                       if (expT.Name == root)
+                                               t = expT;
+                               }
+                       }
+                       RootType = t;
+                       return t;
+               }
+               /// <summary>
+               /// Finalize instatiator MSIL and return LoaderInvoker delegate
+               /// </summary>
+               public Instantiator GetInstanciator(){
+                       il.Emit(OpCodes.Ret);
+
+                       return new Instantiator (RootType,
+                               (Interface.LoaderInvoker)dm.CreateDelegate (typeof(Interface.LoaderInvoker)));
+               }
+       }
+}
+
index 542797a13ef978cdbcbd80dc9aa50885e765260d..290c5355513bac03dd6987d513a989c5abffab28 100644 (file)
@@ -23,6 +23,10 @@ using System.IO;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Threading;
+using System.Xml.Serialization;
+using System.Xml;
+using System.Collections.Generic;
+using System.Diagnostics;
 
 namespace Crow
 {
@@ -33,10 +37,10 @@ namespace Crow
                        Path = path;
                        using (Stream stream = Interface.GetStreamFromPath (path))
                                stream.CopyTo (this);
-                       RootType = Interface.GetTopContainerOfXMLStream (this);
+                       //RootType = Interface.GetTopContainerOfXMLStream (this);
                }
                public IMLStream(Byte[] b) : base (b){                  
-                       RootType = Interface.GetTopContainerOfXMLStream (this);
+                       //RootType = Interface.GetTopContainerOfXMLStream (this);
                }
                /// <summary>
                /// Create a graphicObject instance from the this XML stream.
@@ -47,7 +51,7 @@ namespace Crow
                                Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
 
                                Seek (0, SeekOrigin.Begin);
-                               GraphicObject tmp = Interface.Load (this, this.RootType);
+                               GraphicObject tmp = null;//Interface.Load (this, this.RootType);
 
                                Thread.CurrentThread.CurrentCulture = savedCulture;
                                return tmp;
diff --git a/src/Instantiator.cs b/src/Instantiator.cs
new file mode 100644 (file)
index 0000000..e54e744
--- /dev/null
@@ -0,0 +1,41 @@
+//
+//  Instantiator.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2016 jp
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+using System;
+
+namespace Crow
+{
+       public class Instantiator
+       {
+               Type RootType;
+               Interface.LoaderInvoker Loader;
+               public Instantiator (Type _root, Interface.LoaderInvoker loader)
+               {
+                       RootType = _root;
+                       Loader = loader;
+               }
+               public GraphicObject CreateInstance(){
+                       GraphicObject tmp = (GraphicObject)Activator.CreateInstance(RootType);
+                       Loader (tmp);
+                       return tmp;
+               }
+       }
+}
+
index 7b324de74070da3bb851b22adbc11c8c7fd769ec..4712a54c192a09948751f4bf7a251ebd07051aa1 100644 (file)
@@ -52,6 +52,10 @@ namespace Crow
                        FontRenderingOptions.HintMetrics = HintMetrics.On;
                        FontRenderingOptions.HintStyle = HintStyle.Medium;
                        FontRenderingOptions.SubpixelOrder = SubpixelOrder.Rgb;
+
+                       Thread tBindings = new Thread (BindingThread);
+                       tBindings.IsBackground = true;
+                       tBindings.Start ();
                }
                public Interface(){
                        Interface.CurrentInterface = this;
@@ -107,14 +111,16 @@ namespace Crow
                                g.IsQueueForRedraw = true;
                        }
                }
+               //fast compiled IML instantiators
+               public static Dictionary<String, Instantiator> Instantiators = new Dictionary<string, Instantiator>();
 
                #region Default values and Style loading
                /// Default values of properties from GraphicObjects are retrieve from XML Attributes.
                /// The reflexion process used to retrieve those values being very slow, it is compiled in MSIL
                /// and injected as a dynamic method referenced in the DefaultValuesLoader Dictionnary.
                /// The compilation is done on the first object instancing, and is also done for custom widgets
-               public delegate void loadDefaultInvoker(object instance);
-               public static Dictionary<String, loadDefaultInvoker> DefaultValuesLoader = new Dictionary<string, loadDefaultInvoker>();
+               public delegate void LoaderInvoker(object instance);
+               public static Dictionary<String, LoaderInvoker> DefaultValuesLoader = new Dictionary<string, LoaderInvoker>();
                public static Dictionary<string, Dictionary<string, object>> Styling;
                /// <summary> parse all styling data's and build global Styling Dictionary </summary>
                static void LoadStyling() {
@@ -176,36 +182,6 @@ namespace Crow
                        return stream;
                }
 
-               /// <summary>
-               /// Pre-read first node to set GraphicObject class for loading
-               /// and reset stream position to 0
-               /// </summary>
-               public static Type GetTopContainerOfXMLStream (Stream stream)
-               {
-                       string root = "Object";
-                       stream.Seek (0, SeekOrigin.Begin);
-                       using (XmlReader reader = XmlReader.Create (stream)) {
-                               while (reader.Read ()) {
-                                       // first element is the root element
-                                       if (reader.NodeType == XmlNodeType.Element) {
-                                               root = reader.Name;
-                                               break;
-                                       }
-                               }
-                       }
-
-                       Type t = Type.GetType ("Crow." + root);
-                       if (t == null) {
-                               Assembly a = Assembly.GetEntryAssembly ();
-                               foreach (Type expT in a.GetExportedTypes ()) {
-                                       if (expT.Name == root)
-                                               t = expT;
-                               }
-                       }
-
-                       stream.Seek (0, SeekOrigin.Begin);
-                       return t;
-               }
 
                public static void Save<T> (string file, T graphicObject)
                {
@@ -225,9 +201,10 @@ namespace Crow
 
                        GraphicObject tmp = null;
                        try {
-                               using (Stream stream = GetStreamFromPath (path)) {
-                                       tmp = Load(stream, GetTopContainerOfXMLStream(stream));
-                               }
+                               if (!Instantiators.ContainsKey(path))
+                                       BuildInstaciator(path);
+                               tmp = Instantiators [path].CreateInstance ();
+                               
                        } catch (Exception ex) {
                                throw new Exception ("Error loading <" + path + ">:", ex);
                        }
@@ -236,37 +213,37 @@ namespace Crow
 
                        return tmp;
                }
-               internal static GraphicObject Load (Stream stream, Type type)
+               public static void BuildInstaciator (string path)
                {
+                       System.Globalization.CultureInfo savedCulture = Thread.CurrentThread.CurrentCulture;
+                       Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
+
                        #if DEBUG_LOAD
                        Stopwatch loadingTime = new Stopwatch ();
                        loadingTime.Start ();
                        #endif
 
-                       GraphicObject result;
-
-                       CurrentInterface.XmlLoading = true;
-
-                       XmlSerializerNamespaces xn = new XmlSerializerNamespaces ();
-                       xn.Add ("", "");
-
-                       XmlSerializer xs = new XmlSerializer (type);
-
-                       result = (GraphicObject)xs.Deserialize (stream);
-                       CurrentInterface.XmlLoading = false;
+                       try {
+                               using (Stream stream = GetStreamFromPath (path)) {
+                                       using (IMLInstantiatorBuilder itr = new IMLInstantiatorBuilder (stream)){
+                                               itr.ReadRootType();
+                                               itr.InitEmitter();
+                                               CompilerServices.BuildInstanciator(itr, itr.RootType);
+                                               itr.Read();//close tag
+                                               Instantiators[path] = itr.GetInstanciator();
+                                       }
+                               }
+                       } catch (Exception ex) {
+                               throw new Exception ("Error loading <" + path + ">:", ex);
+                       }
 
                        #if DEBUG_LOAD
-                       FileStream fs = stream as FileStream;
-                       if (fs!=null)
-                               CurrentGOMLPath = fs.Name;
                        loadingTime.Stop ();
-                       Debug.WriteLine ("GOML Loading ({2}->{3}): {0} ticks, {1} ms",
-                               loadingTime.ElapsedTicks,
-                               loadingTime.ElapsedMilliseconds,
-                       CurrentGOMLPath, result.ToString());
+                       Debug.WriteLine ("IML Loading '{2}' : {0} ticks, {1} ms",
+                       loadingTime.ElapsedTicks, loadingTime.ElapsedMilliseconds, path);
                        #endif
 
-                       return result;
+                       Thread.CurrentThread.CurrentCulture = savedCulture;
                }
 
                public GraphicObject LoadInterface (string path)
@@ -289,6 +266,27 @@ namespace Crow
 
                public List<GraphicObject> GraphicTree = new List<GraphicObject>();
 
+               public static List<Binding> Bindings = new List<Binding>();
+               public static void RegisterBinding (Binding b){
+                       lock (Bindings)
+                               Bindings.Add (b);
+               }
+               public static void BindingThread(){
+                       while(true){
+                               Binding[] unresolved;
+                               lock (Bindings){
+                                       unresolved = Bindings.Where (b => !b.Resolved).ToArray ();
+                               }
+                               foreach (Binding ub in unresolved) {
+                                       if (ub.TryFindTarget ()) {
+                                               ub.Resolved = true;
+                                               Debug.WriteLine ("RESOLVED: " + ub);
+                                       }
+                               }
+                               Thread.Sleep (5);
+                       }
+               }
+
                public static Interface CurrentInterface;
 
                Rectangles _redrawClip = new Rectangles();