]> O.S.I.I.S - jp/crow.git/commitdiff
first tests with DataSourceType to prevent using reflexion too often in bindings
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 15 Dec 2018 06:13:54 +0000 (07:13 +0100)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sat, 15 Dec 2018 06:13:54 +0000 (07:13 +0100)
12 files changed:
Crow/src/CompilerServices/CompilerServices.cs
Crow/src/IML/IMLContext.cs
Crow/src/IML/Node.cs
Crow/src/Instantiator.cs
CrowIDE/ui/CrowIDE.crow
CrowIDE/ui/ItemTemplates/Enum.template
CrowIDE/ui/MembersItem.template
CrowIDE/ui/ProjectTree.template
CrowIDE/ui/editors/EditTabItem.template
CrowIDE/ui/editors/IMLEdit.itemp
Tests/BasicTests.cs
Tests/Interfaces/GraphicObject/0.crow

index ee6770a8001b378647db3a2398ad769bb487a3aa..80e47e9d77c8c3a4caf5479809ead156869c3ae8 100644 (file)
@@ -382,8 +382,6 @@ namespace Crow.IML
                                                tmp = gi.Invoke(instance, null);
                                        dstType = gi.ReturnType;
                                }
-
-
                                if (tmp != null)
                                        return tmp;
                                if (dstType == typeof(string) || dstType == typeof (object))//TODO:object should be allowed to return null and not ""
@@ -397,23 +395,6 @@ namespace Crow.IML
 
                        return null;
                }
-               
-               /// <summary>
-               /// search for extentions method in entry assembly then in assembly where the type is defined
-               /// </summary>
-               /// <returns>Extention MethodInfo</returns>
-               /// <param name="t">Extended type</param>
-               /// <param name="methodName">Extention method name</param>
-               //internal static MethodInfo SearchExtMethod(Type t, string methodName){
-               //      MethodInfo mi = null;
-               //      mi = GetExtensionMethods (Assembly.GetEntryAssembly(), t)
-               //              .Where (em => em.Name == methodName).FirstOrDefault ();
-               //      if (mi != null)
-               //              return mi;
-
-               //      return GetExtensionMethods (t.Module.Assembly, t)
-               //              .Where (em => em.Name == methodName).FirstOrDefault ();
-               //}
                internal static MethodInfo SearchExtMethod (Type t, string methodName)
                {
                        string key = t.Name + "." + methodName;
@@ -997,6 +978,77 @@ namespace Crow.IML
 
                        return fi.GetValue (data);
                }
+               internal static MemberInfo GetMemberInfo (Type dataType, string member, out Type returnType)
+               {
+                       MethodInfo miGetDatas = dataType.GetMethod (member, new Type [] { });
+                       if (miGetDatas != null) {
+                               returnType = miGetDatas.ReturnType;
+                               return miGetDatas;
+                       }
+
+                       MemberInfo mbi = dataType.GetMember (member).FirstOrDefault ();
+                       if (mbi == null)
+                               miGetDatas = CompilerServices.SearchExtMethod (dataType, member);
+                       else {
+                               if (mbi is FieldInfo) {
+                                       FieldInfo fi = mbi as FieldInfo;
+                                       returnType = fi.FieldType;
+                                       return mbi;
+                               }
+                               if (mbi.MemberType == MemberTypes.Property)
+                                       miGetDatas = (mbi as PropertyInfo).GetGetMethod ();
+                               else
+                                       miGetDatas = mbi as MethodInfo;
+                       }
+                       returnType = miGetDatas?.ReturnType;
+                       return miGetDatas;
+
+               }
+               internal static void emitGetMemberValue (ILGenerator il, Type dataType, MemberInfo mi)
+               {
+                       switch (mi.MemberType) {
+                       case MemberTypes.Method:
+                               MethodInfo mim = mi as MethodInfo;
+                               if (mim.IsStatic)
+                                       il.Emit (OpCodes.Call, mim);
+                               else
+                                       il.Emit (OpCodes.Callvirt, mim);
+                               break;
+                       case MemberTypes.Field:
+                               il.Emit (OpCodes.Ldfld, mi as FieldInfo);
+                               break;
+                       }
+               }
+               //object is already on the stack
+               internal static void emitGetMemberValue (ILGenerator il, Type dataType, string member)
+               {
+                       MethodInfo miGetDatas = dataType.GetMethod (member, new Type [] { });
+                       if (miGetDatas != null) {
+                               il.Emit (OpCodes.Callvirt, miGetDatas);
+                               return;
+                       }
+                       MemberInfo mbi = dataType.GetMember (member).FirstOrDefault ();
+                       if (mbi == null) {
+                               MethodInfo miExt = CompilerServices.SearchExtMethod (dataType, member);
+                               if (miExt == null)//and among fields
+                                       throw new Exception ($"member {member} not found in {dataType}");
+                               il.Emit (OpCodes.Call, miExt);
+                               return;
+                       }
+                       if (mbi.MemberType == MemberTypes.Property) {
+                               miGetDatas = (mbi as PropertyInfo)?.GetGetMethod ();
+                               if (miGetDatas == null)
+                                       throw new Exception ($"no getter found for property {member} in {dataType}");
+                               il.Emit (OpCodes.Callvirt, miGetDatas);
+                               return;
+                       }
+
+                       FieldInfo fi = mbi as FieldInfo;
+                       if (fi == null)
+                               throw new Exception ($"member {member} not found in {dataType}");
+
+                       il.Emit (OpCodes.Ldfld, fi);
+               }
        }
 }
 
index 8e12c41bfbdb45619c11c91b3e7a214ea9d152eb..a0e95bef11cf6cdb43c68daa35b73eb86f830027 100644 (file)
@@ -80,6 +80,39 @@ namespace Crow.IML
                        CompilerServices.emitSetCurInterface (il);
                }
 
+               Type curDataSourceType = null;
+               /// <summary>
+               /// Pushs  new node and set datasourcetype to current ds type
+               /// </summary>
+               /// <param name="crowType">Crow type.</param>
+               /// <param name="_index">Index.</param>
+               public void PushNode (Type crowType, int _index = 0) {
+                       nodesStack.Push (new Node (crowType, _index, curDataSourceType));
+               }
+               /// <summary>
+               /// Pops node and set curDS type to previous one in node on top of the stack
+               /// </summary>
+               /// <returns>The node.</returns>
+               public Node PopNode () {
+                       Node n = nodesStack.Pop ();
+                       if (nodesStack.Count > 0)
+                               curDataSourceType = nodesStack.Peek().DataSourceType;
+                       return n;
+               }
+               public bool CurrentNodeHasDataSourceType {
+                       get { return curDataSourceType != null; }
+               }
+               public Type CurrentDataSourceType {
+                       get { return curDataSourceType; }
+               }
+               public void SetDataSourceTypeForCurrentNode (Type dsType)
+               {
+                       Node n = nodesStack.Pop ();
+                       n.DataSourceType = dsType;
+                       nodesStack.Push (n);
+                       curDataSourceType = dsType;
+               }
+
                public NodeAddress CurrentNodeAddress {
                        get {
                                Node[] n = nodesStack.ToArray ();
@@ -185,7 +218,6 @@ namespace Crow.IML
                /// Emits the handler method addition, done at end of parsing, Loc_0 is root node instance
                /// </summary>
                /// <param name="bd">Bd.</param>
-               /// <param name="evt">passed as arg to prevent refetching it for the 3rd time</param>
                public void emitHandlerMethodAddition(EventBinding bd){
 
                        //fetch source instance with address for handler addition (as 1st arg of handler.add)
index 2ca90e8c098b515ddb32d59360b92ac1d0e26c4b..5ba93968f826c9e392872d309d10fe76208c3405 100644 (file)
@@ -37,17 +37,23 @@ namespace Crow.IML
        public struct Node
        {
                #region CTOR
-               public Node (Type crowType, int _index = 0)
+               public Node (Type crowType, int _index = 0, Type dsType = null)
                {
                        CrowType = crowType;
                        Index = _index;
+                       DataSourceType = dsType;
                }
                #endregion
 
                /// <summary> Current node type</summary>
-               public Type CrowType;
+               public readonly Type CrowType;
                /// <summary> Index in parent, -1 for template</summary>
-               public int Index;
+               public readonly int Index;
+               /// <summary>
+               /// DataSourceType attribute if set
+               /// </summary>
+               public Type DataSourceType;
+
 
                /// <summary>
                /// retrieve the child addition method depending on the type of this node
@@ -68,7 +74,7 @@ namespace Crow.IML
                        return null;
                }
 
-               #region Equality Compare
+#region Equality Compare
                public override bool Equals (object obj)
                {
                        if (obj == null) 
@@ -80,7 +86,7 @@ namespace Crow.IML
                {
                        return CrowType.GetHashCode () ^ Index.GetHashCode ();
                }
-               #endregion
+#endregion
 
                public bool HasTemplate {
                        get { return typeof (TemplatedControl).IsAssignableFrom (CrowType);}
@@ -88,6 +94,9 @@ namespace Crow.IML
                public bool IsTemplatedGroup {
                        get { return typeof (TemplatedGroup).IsAssignableFrom (CrowType);}
                }
+               public bool HasDataSourceType {
+                       get { return DataSourceType != null; }
+               }
 
                public static implicit operator string (Node sn)
                {
index 14218bfc6f85cee1cadfc60219e49ff07af93055..8c5a4d466e5d893d988e4a893144b85430773c48 100644 (file)
@@ -206,9 +206,9 @@ namespace Crow.IML
                void parseIML (XmlReader reader) {
                        IMLContext ctx = new IMLContext (findRootType (reader));
 
-                       ctx.nodesStack.Push (new Node (ctx.RootType));
+                       ctx.PushNode (ctx.RootType);
                        emitLoader (reader, ctx);
-                       ctx.nodesStack.Pop ();
+                       ctx.PopNode ();
 
                        foreach (int idx in templateCachedDelegateIndices)
                                ctx.emitCachedDelegateHandlerAddition(idx, CompilerServices.eiLogicalParentChanged);
@@ -429,7 +429,7 @@ namespace Crow.IML
                        using (XmlTextReader reader = new XmlTextReader (tmpXml, XmlNodeType.Element, null)) {
                                reader.Read ();
 
-                               #if DESIGN_MODE
+#if DESIGN_MODE
                                IXmlLineInfo li = (IXmlLineInfo)reader;
                                ctx.il.Emit (OpCodes.Ldloc_0);
                                ctx.il.Emit (OpCodes.Ldstr, this.NextDesignID);
@@ -450,23 +450,33 @@ namespace Crow.IML
                                //first check for Style attribute then trigger default value loading
                                if (reader.HasAttributes) {
                                        string style = reader.GetAttribute ("Style");
-                                       if (!string.IsNullOrEmpty (style)){
+                                       if (!string.IsNullOrEmpty (style)) {
                                                CompilerServices.EmitSetValue (ctx.il, CompilerServices.piStyle, style);
-                                               #if DESIGN_MODE
+#if DESIGN_MODE
                                                emitSetDesignAttribute (ctx, "Style", style);
-                                               #endif
+#endif
                                        }
+                                       //check for dataSourceType, if set, datasource bindings will use direct setter/getter
+                                       //instead of reflexion
+                                       string dataSourceType = reader.GetAttribute ("DataSourceType");
+                                       if (string.IsNullOrEmpty (dataSourceType)) {
+                                               //if not set but dataSource is not null, reset dsType to null
+                                               string ds = reader.GetAttribute ("DataSource");
+                                               if (!string.IsNullOrEmpty (ds)) 
+                                                       ctx.SetDataSourceTypeForCurrentNode (null);
+                                       } else
+                                               ctx.SetDataSourceTypeForCurrentNode(CompilerServices.getTypeFromName (dataSourceType));
                                }
-                ctx.il.Emit (OpCodes.Ldloc_0);
+                               ctx.il.Emit (OpCodes.Ldloc_0);
                 ctx.il.Emit (OpCodes.Callvirt, CompilerServices.miLoadDefaultVals);
-                #endregion
+#endregion
 
 
                                #region Attributes reading
                                if (reader.HasAttributes) {
 
                                        while (reader.MoveToNextAttribute ()) {
-                                               if (reader.Name == "Style")
+                                               if (reader.Name == "Style" || reader.Name == "DataSourceType")
                                                        continue;
 
                                                #if DESIGN_MODE
@@ -575,13 +585,16 @@ namespace Crow.IML
                        NodeAddress sourceNA = ctx.CurrentNodeAddress;
                        BindingDefinition bindingDef = sourceNA.GetBindingDef (sourceMember, expression);
 
-                       #if DEBUG_BINDING
+#if DEBUG_BINDING
                        Debug.WriteLine("Property Binding: " + bindingDef.ToString());
-                       #endif
+#endif
 
-                       if (bindingDef.IsDataSourceBinding)//bind on data source
-                               emitDataSourceBindings (ctx, bindingDef);
-                       else
+                       if (bindingDef.IsDataSourceBinding) {//bind on data source
+                               if (ctx.CurrentNodeHasDataSourceType)
+                                       emitDataSourceBindings (ctx, bindingDef, ctx.CurrentDataSourceType);
+                               else
+                                       emitDataSourceBindings (ctx, bindingDef);
+                       } else
                                ctx.StorePropertyBinding (bindingDef);
                }
 
@@ -591,7 +604,7 @@ namespace Crow.IML
                                (dataSource as IValueChange).ValueChanged +=
                                        (EventHandler<ValueChangeEventArgs>)dsValueChangedDynMeths [dynMethIdx].CreateDelegate (typeof(EventHandler<ValueChangeEventArgs>), dscSource);
                }
-               /// <summary> Emits remove old data source event handler./summary>
+               /// <summary> Emits remove old data source event handler.</summary>
                void emitRemoveOldDataSourceHandler(ILGenerator il, string eventName, string delegateName, bool DSSide = true){
                        System.Reflection.Emit.Label cancel = il.DefineLabel ();
 
@@ -968,6 +981,165 @@ namespace Crow.IML
                        ctx.emitCachedDelegateHandlerAddition(delDSIndex, CompilerServices.eiLogicalParentChanged);
                }
                /// <summary>
+               /// data source binding with known data type
+               /// </summary>
+               void emitDataSourceBindings (IMLContext ctx, BindingDefinition bindingDef, Type dsType)
+               {
+#if DEBUG_BINDING_FUNC_CALLS
+                       Console.WriteLine ($"emitDataSourceBindings with data type knows: {bindingDef}");
+#endif
+                       DynamicMethod dm = null;
+                       ILGenerator il = null;
+                       int dmVC = 0;
+                       PropertyInfo piSource = ctx.CurrentNodeType.GetProperty (bindingDef.SourceMember);
+                       //if no dataSource member name is provided, valuechange is not handle and datasource change
+                       //will be used as origine value
+                       string delName = "dyn_DSvalueChanged" + NewId;
+                       if (!string.IsNullOrEmpty (bindingDef.TargetMember)) {
+                               #region create valuechanged method
+                               dm = new DynamicMethod (delName,
+                                       typeof (void),
+                                       CompilerServices.argsBoundValueChange, true);
+
+                               il = dm.GetILGenerator (256);
+
+                               System.Reflection.Emit.Label endMethod = il.DefineLabel ();
+
+                               il.DeclareLocal (typeof (object));
+
+                               il.Emit (OpCodes.Nop);
+
+                               //load value changed member name onto the stack
+                               il.Emit (OpCodes.Ldarg_2);
+                               il.Emit (OpCodes.Ldfld, CompilerServices.fiVCMbName);
+
+                               //test if it's the expected one
+                               il.Emit (OpCodes.Ldstr, bindingDef.TargetMember);
+                               il.Emit (OpCodes.Ldc_I4_4);//StringComparison.Ordinal
+                               il.Emit (OpCodes.Call, CompilerServices.stringEquals);
+                               il.Emit (OpCodes.Brfalse, endMethod);
+                               //set destination member with valueChanged new value
+                               //load destination ref
+                               il.Emit (OpCodes.Ldarg_0);
+                               //load new value onto the stack
+                               il.Emit (OpCodes.Ldarg_2);
+                               il.Emit (OpCodes.Ldfld, CompilerServices.fiVCNewValue);
+
+                               //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
+                               CompilerServices.emitConvert (il, piSource.PropertyType);
+
+                               if (!piSource.CanWrite)
+                                       throw new Exception ("Source member of bindind is read only:" + piSource.ToString ());
+
+                               il.Emit (OpCodes.Callvirt, piSource.GetSetMethod ());
+
+                               il.MarkLabel (endMethod);
+                               il.Emit (OpCodes.Ret);
+
+                               //vc dyn meth is stored in a cached list, it will be bound to datasource only
+                               //when datasource of source graphic object changed
+                               dmVC = dsValueChangedDynMeths.Count;
+                               dsValueChangedDynMeths.Add (dm);
+                               #endregion
+                       }
+
+                       #region emit dataSourceChanged event handler
+                       //now we create the datasource changed method that will init the destination member with
+                       //the actual value of the origin member of the datasource and then will bind the value changed
+                       //dyn methode.
+                       //dm is bound to the instanciator instance to have access to cached dyn meth and delegates
+                       dm = new DynamicMethod ("dyn_dschanged" + NewId,
+                               typeof (void),
+                               CompilerServices.argsBoundDSChange, true);
+
+                       il = dm.GetILGenerator (256);
+
+                       il.DeclareLocal (typeof (object));//used for checking propery less bindings
+                       il.DeclareLocal (typeof (MemberInfo));//used for checking propery less bindings
+                       il.DeclareLocal (typeof (object));//new datasource store, save one field access
+                       System.Reflection.Emit.Label cancel = il.DefineLabel ();
+                       System.Reflection.Emit.Label newDSIsNull = il.DefineLabel ();
+                       System.Reflection.Emit.Label cancelInit = il.DefineLabel ();
+
+                       il.Emit (OpCodes.Nop);
+
+                       il.Emit (OpCodes.Ldarg_2);//load datasource change arg
+                       il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
+                       il.Emit (OpCodes.Stloc_2);//new ds is now loc 2
+
+                       emitRemoveOldDataSourceHandler (il, "ValueChanged", delName, true);
+
+                       if (!string.IsNullOrEmpty (bindingDef.TargetMember)) {
+                               if (bindingDef.TwoWay) //remove handler
+                                       emitRemoveOldDataSourceHandler (il, "ValueChanged", delName, false);
+                               //test if new ds is null
+                               il.Emit (OpCodes.Ldloc_2);
+                               il.Emit (OpCodes.Brfalse, newDSIsNull);//new ds is null
+                               //test if new ds is of expected type
+                               il.Emit (OpCodes.Ldloc_2);
+                               il.Emit (OpCodes.Isinst, dsType);
+                               //il.Emit (OpCodes.Call, CompilerServices.miGetMDToken);
+                               //il.Emit (OpCodes.Ldc_I4, dsType.MetadataToken);
+                               il.Emit (OpCodes.Brfalse, newDSIsNull);
+                       }
+
+                       #region fetch initial Value
+                       if (!string.IsNullOrEmpty (bindingDef.TargetMember)) {
+                               Type mbType;
+                               MemberInfo mi = CompilerServices.GetMemberInfo (dsType, bindingDef.TargetMember, out mbType);
+                               if (mi != null) {
+                                       il.Emit (OpCodes.Ldarg_1);//load source of dataSourceChanged which is the dest instance
+                                       il.Emit (OpCodes.Ldloc_2);//load new ds
+                                       CompilerServices.emitGetMemberValue (il, dsType, mi);
+                                       if (mbType != piSource.PropertyType)
+                                               CompilerServices.emitConvert (il, mbType, piSource.PropertyType);
+                                       il.Emit (OpCodes.Callvirt, piSource.GetSetMethod ());
+                               }
+                       }
+                       #endregion
+
+                       if (!string.IsNullOrEmpty (bindingDef.TargetMember)) {
+                               il.MarkLabel (cancelInit);
+                               //check if new dataSource implement IValueChange
+                               il.Emit (OpCodes.Ldloc_2);//load new datasource
+                               il.Emit (OpCodes.Isinst, typeof (IValueChange));
+                               il.Emit (OpCodes.Brfalse, cancel);
+
+                               il.Emit (OpCodes.Ldarg_0);//load ref to this instanciator onto the stack
+                               il.Emit (OpCodes.Ldarg_1);//load datasource change source
+                               il.Emit (OpCodes.Ldloc_2);//load new datasource
+                               il.Emit (OpCodes.Ldc_I4, dmVC);//load index of dynmathod
+                               il.Emit (OpCodes.Call, CompilerServices.miDSChangeEmitHelper);
+
+                               il.MarkLabel (cancel);
+
+                               if (bindingDef.TwoWay) {
+                                       il.Emit (OpCodes.Ldarg_1);//arg1: dataSourceChange source, the origine of the binding
+                                       il.Emit (OpCodes.Ldstr, bindingDef.SourceMember);//arg2: orig member
+                                       il.Emit (OpCodes.Ldloc_2);//arg3: new datasource
+                                       il.Emit (OpCodes.Ldstr, bindingDef.TargetMember);//arg4: dest member
+                                       il.Emit (OpCodes.Call, CompilerServices.miDSReverseBinding);
+                               }
+
+                       }
+                       il.MarkLabel (newDSIsNull);
+                       il.Emit (OpCodes.Ret);
+
+                       //store dschange delegate in instatiator instance for access while instancing graphic object
+                       int delDSIndex = cachedDelegates.Count;
+                       cachedDelegates.Add (dm.CreateDelegate (CompilerServices.ehTypeDSChange, this));
+                       #endregion
+
+                       ctx.emitCachedDelegateHandlerAddition (delDSIndex, CompilerServices.eiDSChange);
+
+#if DEBUG_BINDING
+                       Debug.WriteLine("\tDataSource ValueChanged: " + delName);
+                       Debug.WriteLine("\tDataSource Changed: " + dm.Name);
+#endif
+               }
+               /// <summary>
                /// create the valuechanged handler, the datasourcechanged handler and emit event handling
                /// </summary>
                void emitDataSourceBindings(IMLContext ctx, BindingDefinition bindingDef){
@@ -1044,13 +1216,18 @@ namespace Crow.IML
 
                        il.DeclareLocal (typeof(object));//used for checking propery less bindings
                        il.DeclareLocal (typeof(MemberInfo));//used for checking propery less bindings
+                       il.DeclareLocal (typeof (object));//new datasource store, save one field access
                        System.Reflection.Emit.Label cancel = il.DefineLabel ();
                        System.Reflection.Emit.Label newDSIsNull = il.DefineLabel ();
                        System.Reflection.Emit.Label cancelInit = il.DefineLabel ();
 
                        il.Emit (OpCodes.Nop);
 
-                       emitRemoveOldDataSourceHandler(il, "ValueChanged", delName, true);
+                       il.Emit (OpCodes.Ldarg_2);//load datasource change arg
+                       il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
+                       il.Emit (OpCodes.Stloc_2);//new ds is now loc 2
+
+                       emitRemoveOldDataSourceHandler (il, "ValueChanged", delName, true);
 
                        if (!string.IsNullOrEmpty(bindingDef.TargetMember)){
                                if (bindingDef.TwoWay){
@@ -1070,15 +1247,13 @@ namespace Crow.IML
 //                                     il.Emit (OpCodes.Call, CompilerServices.miRemEvtHdlByTarget);
 //                                     il.MarkLabel(cancelRemove);
                                }
-                               il.Emit (OpCodes.Ldarg_2);//load datasource change arg
-                               il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
+                               il.Emit (OpCodes.Ldloc_2);
                                il.Emit (OpCodes.Brfalse, newDSIsNull);//new ds is null
                        }
 
 #region fetch initial Value
                        if (!string.IsNullOrEmpty(bindingDef.TargetMember)){
-                               il.Emit (OpCodes.Ldarg_2);//load new datasource
-                               il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
+                               il.Emit (OpCodes.Ldloc_2); 
                                il.Emit (OpCodes.Ldstr, bindingDef.TargetMember);//load member name
                                il.Emit (OpCodes.Call, CompilerServices.miGetMembIinfoWithRefx);
                                il.Emit (OpCodes.Stloc_1);//save memberInfo
@@ -1087,8 +1262,7 @@ namespace Crow.IML
                        }
 
                        il.Emit (OpCodes.Ldarg_1);//load source of dataSourceChanged which is the dest instance
-                       il.Emit (OpCodes.Ldarg_2);//load new datasource
-                       il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
+                       il.Emit (OpCodes.Ldloc_2);//load new datasource
                        if (!string.IsNullOrEmpty(bindingDef.TargetMember)){
                                il.Emit (OpCodes.Ldloc_1);//push mi for value fetching
                                il.Emit (OpCodes.Call, CompilerServices.miGetValWithRefx);
@@ -1100,15 +1274,13 @@ namespace Crow.IML
                        if (!string.IsNullOrEmpty(bindingDef.TargetMember)){
                                il.MarkLabel(cancelInit);
                                //check if new dataSource implement IValueChange
-                               il.Emit (OpCodes.Ldarg_2);//load new datasource
-                               il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
+                               il.Emit (OpCodes.Ldloc_2);//load new datasource
                                il.Emit (OpCodes.Isinst, typeof(IValueChange));
                                il.Emit (OpCodes.Brfalse, cancel);
 
                                il.Emit(OpCodes.Ldarg_0);//load ref to this instanciator onto the stack
                                il.Emit (OpCodes.Ldarg_1);//load datasource change source
-                               il.Emit (OpCodes.Ldarg_2);//load new datasource
-                               il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
+                               il.Emit (OpCodes.Ldloc_2);//load new datasource
                                il.Emit(OpCodes.Ldc_I4, dmVC);//load index of dynmathod
                                il.Emit (OpCodes.Call, CompilerServices.miDSChangeEmitHelper);
 
@@ -1117,8 +1289,7 @@ namespace Crow.IML
                                if (bindingDef.TwoWay){
                                        il.Emit (OpCodes.Ldarg_1);//arg1: dataSourceChange source, the origine of the binding
                                        il.Emit (OpCodes.Ldstr, bindingDef.SourceMember);//arg2: orig member
-                                       il.Emit (OpCodes.Ldarg_2);//arg3: new datasource
-                                       il.Emit (OpCodes.Ldfld, CompilerServices.fiDSCNewDS);
+                                       il.Emit (OpCodes.Ldloc_2);//arg3: new datasource
                                        il.Emit (OpCodes.Ldstr, bindingDef.TargetMember);//arg4: dest member
                                        il.Emit (OpCodes.Call, CompilerServices.miDSReverseBinding);
                                }
index 94df6d676a7c20374e22a5b3ae7cdfb1e6d367c1..4295287d1abb311e1471149f83efc8cdd4b99cb0 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <!--<Window Height="Stretched" Width="Stretched" >-->
-       <VerticalStack>
+       <VerticalStack DataSourceType="CrowIDE">
                <Menu>
                        <MenuItem Caption="File" Width="Fit" PopWidth="120" DataSource="{CurrentSolution}">
                                <MenuItem Command="{CMDNew}" />
index 61b902ef0e72100a24be2bb1e4cf9bca1a099680..9ee2b60c34858a0ac337ea5ff0c571ec8663aa5f 100755 (executable)
@@ -1,5 +1,5 @@
 <?xml version="1.0"?>
-<HorizontalStack Style="MemberViewHStack" ContextCommands="{Commands}">
+<HorizontalStack Style="MemberViewHStack" ContextCommands="{Commands}" DataSourceType="PropertyContainer">
        <Label Style="MemberViewLabel" Text="{Name}" Foreground = "{LabForeground}"/>
        <ComboBox Margin="0"  Height="Stretched" Width="50%" Data="{Choices}"
                        SelectedItem="{²Value}">
index 845a117dddcd62de26f8ffd46bc94cba15acbeb2..b552e92032d5c410bd5cf92880e6033b70e92616 100755 (executable)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <ItemTemplate>
-       <HorizontalStack Style="MemberViewHStack" ContextCommands="{Commands}">
+       <HorizontalStack Style="MemberViewHStack" ContextCommands="{Commands}" DataSourceType="PropertyContainer">
                <Label Style="MemberViewLabel" Text="{Name}" Foreground = "{LabForeground}"/>
                <TextBox Margin="1" Text="{²Value}" Height="Fit" Foreground = "{LabForeground}"/>
        </HorizontalStack>
@@ -9,7 +9,7 @@
        Data="Properties" DataTest="Type"/>
 <ItemTemplate DataType="System.Boolean" >
        <HorizontalStack Style="MemberViewHStack" ContextCommands="{Commands}">
-               <Label Style="MemberViewLabel" Text="{Name}" Foreground = "{LabForeground}"/>
+               <Label Style="MemberViewLabel" Text="{Name}" Foreground = "{LabForeground}" />
                <CheckBox Background="White" Foreground = "{LabForeground}" Height="Stretched" Caption="" IsChecked="{²Value}"/>
        </HorizontalStack>
 </ItemTemplate>
index 0e31bb3ae72af08b61821a61ce859cb99a209f6a..06167f5ffe182384b115d815737cc83a4652674b 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <ItemTemplate>
-       <Border Style="TreeItemBorder" ContextCommands="{Commands}" Focusable="true" MouseDown="onClick" MouseDoubleClick="onDoubleClick">
+       <Border DataSourceType="ProjectItem" Style="TreeItemBorder" ContextCommands="{Commands}" Focusable="true" MouseDown="onClick" MouseDoubleClick="onDoubleClick">
                <Group>
                        <GraphicObject Height="Stretched" Background="RoyalBlue" Visible="{IsSelected}"/>
                        <HorizontalStack>
@@ -12,7 +12,7 @@
        </Border>
 </ItemTemplate>
 <ItemTemplate DataType="Crow.Coding.Project" Data="RootItems" DataTest="Type">
-       <Expandable Caption="{Name}" ContextCommands="{Commands}" IsExpanded="{²IsExpanded}" MouseDoubleClick="/onClickForExpand">
+       <Expandable DataSourceType="Project" Caption="{Name}" ContextCommands="{Commands}" IsExpanded="{²IsExpanded}" MouseDoubleClick="/onClickForExpand">
                <Template>
                        <VerticalStack>
                                <Border Style="TreeItemBorder" >
@@ -38,7 +38,7 @@
                </HorizontalStack>
        </Expandable>
 </ItemTemplate>
-<ItemTemplate DataType="ReferenceGroup" Data="ChildNodes" DataTest="Type" >
+<ItemTemplate DataSourceType="ProjectNode" DataType="ReferenceGroup" Data="ChildNodes" DataTest="Type" >
        <Expandable Caption="{DisplayName}" Template="#Crow.Coding.TreeExpandable.template" IsExpanded="{²IsExpanded}">
                <HorizontalStack Height="Fit">
                        <GraphicObject Width="8" Height="10"/>
@@ -47,7 +47,7 @@
        </Expandable>
 </ItemTemplate>
 <ItemTemplate DataType="VirtualGroup" Data="ChildNodes" DataTest="Type">
-       <Expandable Caption="{DisplayName}" Template="#Crow.Coding.TreeExpandable.template" IsExpanded="{²IsExpanded}">
+       <Expandable DataSourceType="ProjectNode" Caption="{DisplayName}" Template="#Crow.Coding.TreeExpandable.template" IsExpanded="{²IsExpanded}">
                <HorizontalStack Height="Fit">
                        <GraphicObject Width="8" Height="10"/>
                        <VerticalStack Height="Fit" Name="ItemsContainer"/>
@@ -55,7 +55,7 @@
        </Expandable>
 </ItemTemplate>
 <ItemTemplate DataType="Folder" DataTest="Type">
-       <Border Style="TreeItemBorder" ContextCommands="{Commands}">
+       <Border DataSourceType="ProjectNode" Style="TreeItemBorder" ContextCommands="{Commands}">
                <HorizontalStack>
                        <Image Style="ProjTreeIcon"
                                Path="#Crow.Icons.folder.svg"/>
index 81cc84d8df5fd80d92476ad00675881315b056f8..6280d83ff0e72088890ba00b8ca8fa6ee2aa7508 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<GenericStack Orientation="Vertical" Spacing="0"               
+<GenericStack Orientation="Vertical" Spacing="0" DataSourceType="ProjectFile"          
        MouseEnter="{caption.Font=hack bold, 10}"
        MouseLeave="{caption.Font=hack, 10}">
        <HorizontalStack Margin="2" Left="{./TabOffset}"
index b90594f0b211032fd474d1e98f9e231b1176ea74..77fe0449688f9e33f26481a37c78f745e044b602 100644 (file)
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<TabItem QueryClose="OnQueryClose" IsSelected="{²IsSelected}" Template="#Crow.Coding.EditTabItem.template">
+<TabItem DataSourceType="ImlProjectItem" QueryClose="OnQueryClose" IsSelected="{²IsSelected}" Template="#Crow.Coding.EditTabItem.template">
        <VerticalStack>
         <VerticalStack Height="60%">
                <Label DataSource="{../editor.HoverWidget}" Width="Stretched" Margin="2" Text="{Name}"/>
index 7db6fad5f0a2b483f0376a4031b8d2844951d699..b4d7840c6c168e31cd8504a826f2d6b460d288fa 100644 (file)
@@ -8,7 +8,7 @@ using System.Runtime.CompilerServices;
 
 namespace tests
 {
-       class MainClass : Interface
+       public class MainClass : Interface
        {
                [DllImport ("dl", CallingConvention=CallingConvention.Cdecl)]
                static extern IntPtr dlopen (string file, dlmode mode);
@@ -54,7 +54,7 @@ namespace tests
                /*[DllImport (cairoLibPath, EntryPoint="cairo_stroke")]
                [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
                public static extern void cairo_stroke_icall (IntPtr cr);*/
-
+               public string StringTest = "this is a string for testing";
 
                static MainClass app;
                public Command CMDTest;
@@ -115,9 +115,9 @@ namespace tests
                                //app.AddWidget (@"Interfaces/Divers/testFocus.crow").DataSource = app;
                                //app.AddWidget (@"Interfaces/Divers/testMenu.crow").DataSource = app;
                                //app.AddWidget (@"Interfaces/Divers/testVisibility.crow").DataSource = app;
-                               app.Load (@"Interfaces/Divers/0.crow").DataSource = app;
+                               //app.Load (@"Interfaces/Divers/0.crow").DataSource = app;
                                //app.AddWidget (@"Interfaces/Splitter/1.crow").DataSource = app;
-                               //app.AddWidget (@"Interfaces/GraphicObject/0.crow").DataSource = app;
+                               app.Load (@"Interfaces/GraphicObject/0.crow").DataSource = app;
                                //app.AddWidget (@"Interfaces/TemplatedContainer/test_Listbox.crow").DataSource = app;
 
                                /*app.instFileDlg = Crow.IML.Instantiator.CreateFromImlFragment
index 97cda8a0a4f85b133bdb89787d0e9032ca64b3b6..d608cf00a99de8595a1a62e5a5a81355c5725246 100755 (executable)
@@ -1,2 +1,4 @@
 <?xml version="1.0"?>
-<GraphicObject Background="SeaGreen"/>
\ No newline at end of file
+<VerticalStack >
+    <Label Text="{StringTest}" Background="SeaGreen" DataSourceType="MainClass"/>
+</VerticalStack>