]> O.S.I.I.S - jp/crow.git/commitdiff
Bindings clearance,
authorjpbruyere <jp.bruyere@hotmail.com>
Mon, 12 Oct 2015 11:53:37 +0000 (13:53 +0200)
committerjpbruyere <jp.bruyere@hotmail.com>
Mon, 12 Oct 2015 11:53:37 +0000 (13:53 +0200)
code clean

Tests/GOLIBTests.cs
src/CompilerServices/CompilerServices.cs
src/GraphicObjects/GraphicObject.cs
src/Interface.cs

index 13576b241f07bdecfef0e74883afc863dc74e0a7..508acc2d13406f82664cdf79417176d8b8dd972c 100644 (file)
@@ -44,8 +44,8 @@ namespace test
                        "testSpinner.goml",\r
                        "testPopper.goml",\r
                        "testGroupBox.goml",\r
-                       "testWindow.goml",\r
-                       "testMsgBox.goml",\r
+//                     "testWindow.goml",\r
+//                     "testMsgBox.goml",\r
                        "testGrid.goml",\r
                        "testMeter.goml",\r
 //                     "testCombobox.goml",\r
index 0d13d7bf1d613ddc41bc70c3196b010da4549484..07afdaea7bede5127943c2c0dd5388aebe467718 100644 (file)
@@ -10,65 +10,91 @@ using System.Runtime.CompilerServices;
 
 namespace go
 {
-       public enum BindingType
+       public class MemberReference
        {
-               Handler,
-               DynamicHandler,
-               PropertyBinding
-       }
-       public class Binding{
-               public MemberInfo SourceMember;
-               public string Expression;
+               public object Instance;
+               public MemberInfo Member;
 
-               public PropertyInfo Property { get { return SourceMember as PropertyInfo; } }
-               public EventInfo Event { get { return SourceMember as EventInfo; } }
+               public PropertyInfo Property { get { return Member as PropertyInfo; } }
+               public FieldInfo Field { get { return Member as FieldInfo; } }
+               public EventInfo Event { get { return Member as EventInfo; } }
+               public MethodInfo Method { get { return Member as MethodInfo; } }
 
-               public Binding(){
+               public MemberReference(){
                }
-               public Binding(MemberInfo _sourceMember, string _expression)
+               public MemberReference(object _instance, MemberInfo _member = null)
                {
-                       SourceMember = _sourceMember;
-                       Expression = _expression;
+                       Instance = _instance;
+                       Member = _member;
+               }
+               public bool FindMember(string _memberName)
+               {
+                       Type t = Instance.GetType ();
+                       Member = t.GetMember (_memberName).FirstOrDefault ();
+
+                       #region search for extensions methods if member not found in type
+                       if (Member == null && !string.IsNullOrEmpty(_memberName))
+                       {
+                               Assembly a = Assembly.GetExecutingAssembly();
+                               Member =  CompilerServices.GetExtensionMethods(a, t).Where(em=>em.Name == _memberName).FirstOrDefault();
+                       }                       
+                       #endregion
+               
+                       return string.IsNullOrEmpty(_memberName) ? false : true;
                }
        }
+       public class Binding{
+               static int bindingCpt = 0;
+               string dynMethodId = "";
+               public string NewDynMethodId {
+                       get {
+                               if (!string.IsNullOrEmpty (dynMethodId))
+                                       return dynMethodId;
+                               dynMethodId = "dynHandle_" + bindingCpt;
+                               bindingCpt++;
+                               return dynMethodId;
+                       }
+               }
+               public string DynMethodId {
+                       get { return dynMethodId; }
+               }
+                               
 
-       public class ResolvedBinding
-       {
-               public object Target;
-               public MemberInfo Member;
+               public MemberReference Source;
+               public MemberReference Target;
 
-               public Binding Binding;
+               public string Expression;
 
-               public ResolvedBinding(){
-               }
-               public ResolvedBinding(Binding _binding){
-                       Binding = _binding;
+               #region CTOR
+               public Binding(){}
+               public Binding(MemberReference _source, string _expression)
+               {
+                       Source = _source;
+                       Expression = _expression;
                }
+               #endregion
 
-               public bool FindTarget(GraphicObject source){
+               public bool FindTarget(){
                        string member = null;
 
                        //if binding exp = '{}' => binding is done on datasource
-                       if (string.IsNullOrEmpty (Binding.Expression)) {
-                               Target = source;
-                               Member = null;
+                       if (string.IsNullOrEmpty (Expression)) {
+                               Target = new MemberReference (Source.Instance);
                                return true;
                        }
 
-                       //if (Binding.SourceMember.MemberType == MemberTypes.Event)
-
-                       string[] bindingExp = Binding.Expression.Split ('/');
+                       string[] bindingExp = Expression.Split ('/');
 
                        if (bindingExp.Length == 1) {
                                //datasource binding
-                               Target = source.DataSource;
+                               Target = new MemberReference((Source.Instance as GraphicObject).DataSource);
                                member = bindingExp [0];
                        } else {
                                int ptr = 0;
-                               ILayoutable tmp = source;
+                               ILayoutable tmp = Source.Instance as ILayoutable;
                                if (string.IsNullOrEmpty (bindingExp [0])) {
                                        //if exp start with '/' => Graphic tree parsing start at top container
-                                       tmp = source.TopContainer as ILayoutable;
+                                       tmp = tmp.TopContainer as ILayoutable;
                                        ptr++;
                                }
                                while (ptr < bindingExp.Length - 1) {
@@ -79,7 +105,7 @@ namespace go
                                        else if (bindingExp [ptr] == ".") {
                                                if (ptr > 0)
                                                        throw new Exception ("Syntax error in binding, './' may only appear in first position");                                                
-                                               tmp = source;
+                                               tmp = Source.Instance as ILayoutable;
                                        }else
                                                tmp = (tmp as GraphicObject).FindByName (bindingExp [ptr]);
                                        ptr++;
@@ -94,486 +120,33 @@ namespace go
                                        member = bindTrg [1];
                                } else
                                        throw new Exception ("Syntax error in binding, expected 'go dot member'");
-                               
-                               Target = tmp;
-                       }
-                       if (Target == null) {
-                               Debug.WriteLine ("Binding Source is null: " + Binding.Expression);
-                               return false;
-                       }
-                       Type targetType = Target.GetType ();
-                       Member = targetType.GetMember (member).FirstOrDefault ();
 
-                       #region search for extensions methods if member not found in type
-                       if (Member == null && !string.IsNullOrEmpty(member))
-                       {
-                               Assembly a = Assembly.GetExecutingAssembly();
-                               Member =  CompilerServices.GetExtensionMethods(a, targetType).FirstOrDefault();                                 
+                               Target = new MemberReference(tmp);
                        }
-                       #endregion
-
-                       if (member == null) {
-                               Debug.WriteLine ("Binding member not found: " + member);
+                       if (Target == null) {
+                               Debug.WriteLine ("Binding Source is null: " + Expression);
                                return false;
                        }
 
-                       return true;
+                       if (Target.FindMember (member))
+                               return true;
+                       
+                       Debug.WriteLine ("Binding member not found: " + member);
+                       return false;
                }
-       }
-
-       public static class CompilerServices2
-       {
-               static int dynHandleCpt = 0;
-               /// <summary>
-               /// Compile events expression in GOML attributes
-               /// </summary>
-               /// <param name="es">Event binding details</param>
-               public static void ResolveBinding(DynAttribute es)
+               public void Reset()
                {
-                       Type srcType = es.Source.GetType ();
-
-                       #region Retrieve EventHandler parameter type
-                       EventInfo ei = srcType.GetEvent (es.MemberName);
-                       MethodInfo invoke = ei.EventHandlerType.GetMethod ("Invoke");
-                       ParameterInfo[] pars = invoke.GetParameters ();
-
-                       Type handlerArgsType = pars [1].ParameterType;
-                       #endregion
-
-                       Type[] args = {typeof(object), handlerArgsType};
-                       DynamicMethod dm = new DynamicMethod("dynHandle_" + dynHandleCpt,
-                               typeof(void), 
-                               args, 
-                               srcType.Module);
-
-                       es.Source.DynamicMethodIds.Add (dynHandleCpt);
-
-                       dynHandleCpt++;
-
-                       #region IL generation
-                       ILGenerator il = dm.GetILGenerator(256);
-
-                       string src = es.Value.Trim();
-
-                       if (! (src.StartsWith("{") || src.EndsWith ("}"))) 
-                               throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", es.MemberName, es.Value));
-
-                       src = src.Substring (1, src.Length - 2);
-                       string[] srcLines = src.Split (new char[] { ';' });
-
-                       foreach (string srcLine in srcLines) {
-                               string statement = srcLine.Trim ();
-
-                               string[] operandes = statement.Split (new char[] { '=' });
-                               if (operandes.Length < 2) //not an affectation
-                               {
-                                       continue;
-                               }
-                               string lop = operandes [0].Trim ();
-                               string rop = operandes [operandes.Length-1].Trim ();
-
-                               #region LEFT OPERANDES
-                               GraphicObject lopObj = es.Source;       //default left operand base object is 
-                               //the first arg (object sender) of the event handler
-
-                               string[] lopParts = lop.Split (new char[] { '.' });
-                               if (lopParts.Length == 2) {//should search also for member of es.Source
-                                       lopObj = es.Source.FindByName (lopParts [0]);
-                                       if (lopObj==null)
-                                               throw new Exception (string.Format("GOML:Unknown name: {0}", lopParts[0]));
-                                       //TODO: should create private member holding ref of lopObj, and emit
-                                       //a call to FindByName(lopObjName) during #ctor or in a onLoad func or evt handler
-                                       throw new Exception (string.Format("GOML:obj tree ref not yet implemented", lopParts[0]));
-                               }else
-                                       il.Emit(OpCodes.Ldarg_0);       //load sender ref onto the stack
-
-                               int i = lopParts.Length -1;
-
-                               MemberInfo lopMbi = lopObj.GetType().GetMember (lopParts[i])[0];
-                               OpCode lopSetOC;
-                               dynamic lopSetMbi;
-                               Type lopT = null;
-                               switch (lopMbi.MemberType) {
-                               case MemberTypes.Property:
-                                       PropertyInfo lopPi = srcType.GetProperty (lopParts[i]);
-                                       MethodInfo dstMi = lopPi.GetSetMethod ();
-                                       lopT = lopPi.PropertyType;
-                                       lopSetMbi = dstMi;
-                                       lopSetOC = OpCodes.Callvirt;
-                                       break;
-                               case MemberTypes.Field:
-                                       FieldInfo dstFi = srcType.GetField(lopParts[i]);
-                                       lopT = dstFi.FieldType;
-                                       lopSetMbi = dstFi;
-                                       lopSetOC = OpCodes.Stfld;
-                                       break;
-                               default:
-                                       throw new Exception (string.Format("GOML:member type not handle: {0}", lopParts[i]));
-                               }  
-                               #endregion
-
-                               #region RIGHT OPERANDES
-                               if (rop.StartsWith("\'")){
-                                       if (!rop.EndsWith("\'"))
-                                               throw new Exception (string.Format
-                                                       ("GOML:malformed string constant in handler: {0}", rop));       
-                                       string strcst = rop.Substring (1, rop.Length - 2);
-
-                                       il.Emit(OpCodes.Ldstr,strcst);
-
-                               }else{
-                                       //search for a static field in left operand type named 'rop name'
-                                       FieldInfo ropFi = lopT.GetField (rop, BindingFlags.Static|BindingFlags.Public);
-                                       if (ropFi != null)
-                                       {
-                                               il.Emit (OpCodes.Ldsfld, ropFi);
-                                       }else{
-                                               //search if parsing methods are present
-                                               MethodInfo lopTryParseMi = lopT.GetMethod("TryParse");
-
-                                       }
-                               }
-
-                               #endregion
-
-                               //emit left operand assignment
-                               il.Emit(lopSetOC, lopSetMbi);
-                       }
+                       Target = null;
+                       dynMethodId = "";
+               }
+       }
 
-                       il.Emit(OpCodes.Ret);
 
-                       #endregion
 
-                       Delegate del = dm.CreateDelegate(ei.EventHandlerType);
-                       MethodInfo addHandler = ei.GetAddMethod ();
-                       addHandler.Invoke(es.Source, new object[] {del});
-               }
-
-       }
        public static class CompilerServices
        {
-               public static void CreateBindingHandler()
-               {
-               }
-
                static int dynHandleCpt = 0;
 
-               /// <summary>
-               /// Compile events expression in GOML attributes
-               /// </summary>
-               /// <param name="es">Event binding details</param>
-               public static void CompileEventSource(DynAttribute es)
-               {
-                       Type srcType = es.Source.GetType ();
-
-                       #region Retrieve EventHandler parameter type
-                       EventInfo ei = srcType.GetEvent (es.MemberName);
-                       MethodInfo invoke = ei.EventHandlerType.GetMethod ("Invoke");
-                       ParameterInfo[] pars = invoke.GetParameters ();
-
-                       Type handlerArgsType = pars [1].ParameterType;
-                       #endregion
-
-                       Type[] args = {typeof(object), handlerArgsType};
-                       DynamicMethod dm = new DynamicMethod("dynHandle",
-                               typeof(void), 
-                               args, 
-                               srcType.Module);
-
-                       #region IL generation
-                       ILGenerator il = dm.GetILGenerator(256);
-
-                       string src = es.Value.Trim();
-
-                       if (! (src.StartsWith("{") || src.EndsWith ("}"))) 
-                               throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", es.MemberName, es.Value));
-
-                       src = src.Substring (1, src.Length - 2);
-                       string[] srcLines = src.Split (new char[] { ';' });
-
-                       foreach (string srcLine in srcLines) {
-                               string statement = srcLine.Trim ();
-
-                               string[] operandes = statement.Split (new char[] { '=' });
-                               if (operandes.Length < 2) //not an affectation
-                               {
-                                       continue;
-                               }
-                               string lop = operandes [0].Trim ();
-                               string rop = operandes [operandes.Length-1].Trim ();
-
-                               #region LEFT OPERANDES
-                               GraphicObject lopObj = es.Source;       //default left operand base object is 
-                                                                                                       //the first arg (object sender) of the event handler
-
-                               string[] lopParts = lop.Split (new char[] { '.' });
-                               if (lopParts.Length == 2) {//should search also for member of es.Source
-                                       lopObj = es.Source.FindByName (lopParts [0]);
-                                       if (lopObj==null)
-                                               throw new Exception (string.Format("GOML:Unknown name: {0}", lopParts[0]));
-                                       //TODO: should create private member holding ref of lopObj, and emit
-                                       //a call to FindByName(lopObjName) during #ctor or in a onLoad func or evt handler
-                                       throw new Exception (string.Format("GOML:obj tree ref not yet implemented", lopParts[0]));
-                               }else
-                                       il.Emit(OpCodes.Ldarg_0);       //load sender ref onto the stack
-
-                               int i = lopParts.Length -1;
-
-                               MemberInfo lopMbi = lopObj.GetType().GetMember (lopParts[i])[0];
-                               OpCode lopSetOC;
-                               dynamic lopSetMbi;
-                               Type lopT = null;
-                               switch (lopMbi.MemberType) {
-                               case MemberTypes.Property:
-                                       PropertyInfo lopPi = srcType.GetProperty (lopParts[i]);
-                                       MethodInfo dstMi = lopPi.GetSetMethod ();
-                                       lopT = lopPi.PropertyType;
-                                       lopSetMbi = dstMi;
-                                       lopSetOC = OpCodes.Callvirt;
-                                       break;
-                               case MemberTypes.Field:
-                                       FieldInfo dstFi = srcType.GetField(lopParts[i]);
-                                       lopT = dstFi.FieldType;
-                                       lopSetMbi = dstFi;
-                                       lopSetOC = OpCodes.Stfld;
-                                       break;
-                               default:
-                                       throw new Exception (string.Format("GOML:member type not handle: {0}", lopParts[i]));
-                               }  
-                               #endregion
-
-                               #region RIGHT OPERANDES
-                               if (rop.StartsWith("\'")){
-                                       if (!rop.EndsWith("\'"))
-                                               throw new Exception (string.Format
-                                               ("GOML:malformed string constant in handler: {0}", rop));       
-                                       string strcst = rop.Substring (1, rop.Length - 2);
-
-                                       il.Emit(OpCodes.Ldstr,strcst);
-
-                               }else{
-                                       //search for a static field in left operand type named 'rop name'
-                                       FieldInfo ropFi = lopT.GetField (rop, BindingFlags.Static|BindingFlags.Public);
-                                       if (ropFi != null)
-                                       {
-                                               il.Emit (OpCodes.Ldsfld, ropFi);
-                                       }else{
-                                               //search if parsing methods are present
-                                               MethodInfo lopTryParseMi = lopT.GetMethod("TryParse");
-                                               //TODO
-                                       }
-                               }
-
-                               #endregion
-
-                               //emit left operand assignment
-                               il.Emit(lopSetOC, lopSetMbi);
-                       }
-                               
-                       il.Emit(OpCodes.Ret);
-
-                       #endregion
-
-                       Delegate del = dm.CreateDelegate(ei.EventHandlerType);
-                       MethodInfo addHandler = ei.GetAddMethod ();
-                       addHandler.Invoke(es.Source, new object[] {del});
-               }
-
-               /// <summary>
-               /// Resolves GOML property bindings afler loading
-               /// </summary>
-               /// <param name="binding">Binding details</param>
-               /// <param name="_source">Data source for binding</param>
-               public static void ResolveBinding(DynAttribute binding, object _source)
-               {                       
-                       object srcGO = null;
-                       string statement = binding.Value;
-
-                       if (statement.StartsWith ("/"))//binding is done in graphic object tree, _source param is ignore
-                               srcGO = binding.Source;
-                       else
-                               srcGO = _source;
-
-                       string[] bindingExp = binding.Value.Split ('/');
-
-                       if (bindingExp.Length > 1){
-                               int i = 0;
-                               srcGO = binding.Source; //starts parsing from current GO
-                               while (i < bindingExp.Length - 1) {
-                                       if (bindingExp [i] == "..")
-                                               srcGO = (srcGO as ILayoutable).Parent as GraphicObject;
-                                       else
-                                               srcGO = (srcGO as GraphicObject).FindByName (bindingExp [i]);
-                                       i++;
-                               }
-                               string[] bindTrg = bindingExp [i].Split ('.');
-
-                               if (bindTrg.Length == 2) {
-                                       srcGO = (srcGO as GraphicObject).FindByName (bindTrg [0]);
-                                       statement = bindTrg [1];
-                               } else
-                                       throw new Exception ("Syntax error in binding, expected 'go dot member'");
-                       }
-
-                       if (srcGO == null) {
-                               Debug.WriteLine ("Invalid Binding Source: " + binding.Value);
-                               return;
-                       }
-                       Type srcType = srcGO.GetType ();
-                       Type dstType = binding.Source.GetType ();
-
-                       MemberInfo miSrc = srcType.GetMember (statement).FirstOrDefault ();
-                       MemberInfo miDst = dstType.GetMember (binding.MemberName).FirstOrDefault ();
-
-                       object srcVal = null; //value in source member
-
-                       #region search for extensions methods if member not found in type
-                       if (miSrc == null && !string.IsNullOrEmpty(statement))
-                       {
-                               Assembly a = Assembly.GetExecutingAssembly();
-                               miSrc =  CompilerServices.GetExtensionMethods(a, srcType).FirstOrDefault();                                     
-                       }
-                       #endregion
-
-                       #region initialize target with actual value
-
-                       if (string.IsNullOrEmpty(binding.Value))
-                               srcVal = srcGO;//if no member is provided for binding, source raw value is taken
-                       else if (miSrc != null){
-                               if (miSrc.MemberType == MemberTypes.Property)
-                                       srcVal = (miSrc as PropertyInfo).GetGetMethod ().Invoke (srcGO, null);
-                               else if (miSrc.MemberType == MemberTypes.Field)
-                                       srcVal = (miSrc as FieldInfo).GetValue (srcGO);
-                               else if (miSrc.MemberType == MemberTypes.Method){
-                                       MethodInfo mthSrc = miSrc as MethodInfo;
-                                       if (mthSrc.IsDefined(typeof(ExtensionAttribute), false))
-                                               srcVal = mthSrc.Invoke(null, new object[] {srcGO});
-                                       else
-                                               srcVal = mthSrc.Invoke(srcGO, null);
-                               }else
-                                       throw new Exception ("unandled source member type for binding");
-                       }
-//                     if (miSrc != null){
-                               if (miDst.MemberType == MemberTypes.Property) {
-                                       PropertyInfo piDst = miDst as PropertyInfo;
-                                       //TODO: handle other dest type conversions
-                                       if (piDst.PropertyType == typeof(string)){
-                                               if (srcVal != null)
-                                                       srcVal = srcVal.ToString ();
-                                       }
-                                       piDst.GetSetMethod ().Invoke (binding.Source, new object[] { srcVal });
-                               } else if (miDst.MemberType == MemberTypes.Field) {
-                                       FieldInfo fiDst = miDst as FieldInfo;
-                                       if (fiDst.FieldType == typeof(string))
-                                               srcVal = srcVal.ToString ();
-                                       fiDst.SetValue (binding.Source, srcVal );
-                               }else
-                                       throw new Exception("unandled destination member type for binding");
-//                     }
-                       #endregion
-
-                       #region Retrieve EventHandler parameter type
-                       EventInfo ei = srcType.GetEvent ("ValueChanged");
-                       if (ei == null)
-                               return; //no dynamic update if ValueChanged interface is not implemented
-
-                       MethodInfo evtInvoke = ei.EventHandlerType.GetMethod ("Invoke");
-                       ParameterInfo[] evtParams = evtInvoke.GetParameters ();
-                       Type handlerArgsType = evtParams [1].ParameterType;
-
-                       #endregion
-
-
-                       Type[] args = {typeof(object), handlerArgsType};
-                       DynamicMethod dm = new DynamicMethod("dynHandle_" + dynHandleCpt,
-                               typeof(void), 
-                               args, 
-                               srcType.Module, true);
-
-                       (binding.Source as GraphicObject).DynamicMethodIds.Add (dynHandleCpt);
-
-                       dynHandleCpt++;
-
-                       //register target object reference
-                       int dstIdx = Interface.Reference(binding.Source);
-
-                       #region IL generation
-                       ILGenerator il = dm.GetILGenerator(256);
-
-                       System.Reflection.Emit.Label labFailed = il.DefineLabel();
-                       System.Reflection.Emit.Label labContinue = il.DefineLabel();
-
-                       #region test if valueChange event is the correct one
-                       il.Emit (OpCodes.Ldstr, statement);
-                       //push name from arg
-                       il.Emit(OpCodes.Ldarg_1);
-                       FieldInfo fiMbName = typeof(ValueChangeEventArgs).GetField("MemberName");
-                       il.Emit(OpCodes.Ldfld, fiMbName);
-                       MethodInfo miStrEqu = typeof(string).GetMethod("op_Inequality", new Type[] {typeof(string),typeof(string)});
-                       il.Emit(OpCodes.Call, miStrEqu);
-                       il.Emit(OpCodes.Brfalse_S, labContinue);
-                       il.Emit(OpCodes.Br_S, labFailed);
-                       il.MarkLabel(labContinue);
-                       #endregion
-
-//                     string[] srcLines = binding.Value.Trim().Split (new char[] { ';' });
-//                     foreach (string srcLine in srcLines) {
-                               //MethodInfo infoWriteLine = typeof(System.Diagnostics.Debug).GetMethod("WriteLine", new Type[] { typeof(string) });
-                                                       
-
-                       //load target ref onto the stack
-                       FieldInfo fiRefs = typeof(Interface).GetField("References");
-                       il.Emit(OpCodes.Ldsfld, fiRefs);
-                       il.Emit(OpCodes.Ldc_I4, dstIdx);
-                       MethodInfo miGetRef = Interface.References.GetType().GetMethod("get_Item");
-                       il.Emit(OpCodes.Callvirt, miGetRef);
-                       il.Emit(OpCodes.Isinst, dstType);
-
-                       //push new value
-                       il.Emit(OpCodes.Ldarg_1);
-                       FieldInfo fiNewValue = typeof(ValueChangeEventArgs).GetField("NewValue");
-                       il.Emit(OpCodes.Ldfld, fiNewValue);
-
-                       //Target is expected always to be a Property
-                       PropertyInfo piTarget = dstType.GetProperty(binding.MemberName);
-
-                       //type of the source value
-                       Type srcValueType = null;
-
-                       //member info of the source value
-                       MemberInfo miSrcVal = miSrc;
-
-                       //this allow memberless binding with only a name passed as MemberName
-                       //the type of the source value is determined by the destination member
-                       if (miSrcVal == null)
-                               miSrcVal = miDst;
-
-                       if (miSrcVal.MemberType == MemberTypes.Property)
-                               srcValueType = (miSrcVal as PropertyInfo).PropertyType;
-                       else if (miSrcVal.MemberType == MemberTypes.Field) 
-                               srcValueType = (miSrcVal as FieldInfo).FieldType;
-                       else
-                               throw new Exception("unandled source member type for binding");
-                       
-                       if (!srcValueType.IsValueType)
-                               il.Emit(OpCodes.Castclass, srcValueType);
-                       else if (piTarget.PropertyType != srcValueType)
-                               il.Emit(OpCodes.Callvirt, GetConvertMethod( piTarget.PropertyType ));
-                       else
-                               il.Emit(OpCodes.Unbox_Any, piTarget.PropertyType);
-                               
-                       il.Emit(OpCodes.Callvirt, piTarget.GetSetMethod());
-
-                       il.MarkLabel(labFailed);
-                       il.Emit(OpCodes.Ret);
-
-                       #endregion
-
-                       Delegate del = dm.CreateDelegate(ei.EventHandlerType);
-                       MethodInfo addHandler = ei.GetAddMethod ();
-                       addHandler.Invoke(srcGO, new object[] {del});
-               }
-
                #region conversions
 
                internal static MethodInfo GetConvertMethod( Type targetType )
index 7ebcaf61c6d860e7b99c6cd12a72db49fc219f60..505e85a9a6115bafc01545704d0476bca7061e3c 100644 (file)
@@ -23,7 +23,13 @@ namespace go
 {              \r
        public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange\r
        {\r
-               internal List<int> DynamicMethodIds = new List<int> ();\r
+               internal List<string> DynamicMethodIds\r
+               {\r
+                       get { return Bindings.\r
+                               Where(bi=>!string.IsNullOrEmpty(bi.DynMethodId)).\r
+                               Select (b => b.DynMethodId).ToList ();\r
+                       }\r
+               }\r
                internal List<Binding> Bindings = new List<Binding> ();\r
 \r
                #region IValueChange implementation\r
@@ -790,38 +796,36 @@ namespace go
 \r
                public virtual void ResolveBindings()\r
                {\r
-                       List<ResolvedBinding> resolved = new List<ResolvedBinding> ();\r
+                       List<Binding> resolved = new List<Binding> ();\r
                        foreach (Binding b in Bindings) {\r
-                               if (b.SourceMember.MemberType == MemberTypes.Event) {\r
+                               if (b.Source.Member.MemberType == MemberTypes.Event) {\r
                                        if (b.Expression.StartsWith("{")){\r
                                                CompileEventSource(b);\r
                                                continue;\r
                                        }\r
                                }\r
-                               ResolvedBinding rb = new ResolvedBinding (b);\r
-                               if (!rb.FindTarget (this))\r
+                               if (!b.FindTarget ())\r
                                        continue;\r
-                               if (rb.Binding.SourceMember.MemberType == MemberTypes.Event) {\r
+                               if (b.Source.Member.MemberType == MemberTypes.Event) {\r
                                        //register handler for event\r
-                                       MethodInfo mi = rb.Member as MethodInfo;\r
-                                       if (mi == null) {\r
-                                               Debug.WriteLine ("Handler Method not found: " + rb.Binding.Expression);\r
+                                       if (b.Target.Method == null) {\r
+                                               Debug.WriteLine ("Handler Method not found: " + b.Expression);\r
                                                continue;\r
                                        }\r
 \r
-                                       MethodInfo addHandler = rb.Binding.Event.GetAddMethod ();\r
-                                       Delegate del = Delegate.CreateDelegate (rb.Binding.Event.EventHandlerType, rb.Target, mi);\r
+                                       MethodInfo addHandler = b.Source.Event.GetAddMethod ();\r
+                                       Delegate del = Delegate.CreateDelegate (b.Source.Event.EventHandlerType, b.Target.Instance, b.Target.Method);\r
                                        addHandler.Invoke (this, new object[] { del });\r
                                        continue;\r
                                }\r
-                               resolved.Add (rb);                              \r
+                               resolved.Add (b);                               \r
                        }\r
                        //group;only one dynMethods by target (valuechanged event source)\r
                        //changed value name tested in switch\r
-                       IEnumerable<ResolvedBinding[]> groupedByTarget = resolved.GroupBy (g => g.Target, g => g, (k, g) => g.ToArray ());\r
-                       foreach (ResolvedBinding[] grouped in groupedByTarget) {\r
+                       IEnumerable<Binding[]> groupedByTarget = resolved.GroupBy (g => g.Target.Instance, g => g, (k, g) => g.ToArray ());\r
+                       foreach (Binding[] grouped in groupedByTarget) {\r
                                int i = 0;\r
-                               Type targetType = grouped[0].Target.GetType();\r
+                               Type targetType = grouped[0].Target.Instance.GetType();\r
                                Type sourceType = this.GetType();\r
 \r
                                DynamicMethod dm = null;\r
@@ -837,6 +841,8 @@ namespace go
                                LocalBuilder lbMemberName = null;\r
                                LocalBuilder lbValue = null;\r
 \r
+\r
+\r
                                #region Retrieve EventHandler parameter type\r
                                EventInfo ei = targetType.GetEvent ("ValueChanged");\r
                                //no dynamic update if ValueChanged interface is not implemented\r
@@ -846,7 +852,7 @@ namespace go
                                        Type handlerArgsType = evtParams [1].ParameterType;\r
 \r
                                        Type[] args = {typeof(object), typeof(object),handlerArgsType};\r
-                                       dm = new DynamicMethod("dynHandle",\r
+                                       dm = new DynamicMethod(grouped[0].NewDynMethodId,\r
                                                typeof(void), \r
                                                args,\r
                                                sourceType);\r
@@ -881,33 +887,33 @@ namespace go
                                #endregion\r
 \r
                                i = 0;\r
-                               foreach (ResolvedBinding rb in grouped) {\r
+                               foreach (Binding b in grouped) {\r
                                        #region initialize target with actual value\r
                                        object targetValue = null;\r
-                                       if (rb.Member != null){\r
-                                               if (rb.Member.MemberType == MemberTypes.Property)\r
-                                                       targetValue = (rb.Member as PropertyInfo).GetGetMethod ().Invoke (rb.Target, null);\r
-                                               else if (rb.Member.MemberType == MemberTypes.Field)\r
-                                                       targetValue = (rb.Member as FieldInfo).GetValue (rb.Target);\r
-                                               else if (rb.Member.MemberType == MemberTypes.Method){\r
-                                                       MethodInfo mthSrc = rb.Member as MethodInfo;\r
+                                       if (b.Target.Member != null){\r
+                                               if (b.Target.Member.MemberType == MemberTypes.Property)\r
+                                                       targetValue = b.Target.Property.GetGetMethod ().Invoke (b.Target.Instance, null);\r
+                                               else if (b.Target.Member.MemberType == MemberTypes.Field)\r
+                                                       targetValue = b.Target.Field.GetValue (b.Target.Instance);\r
+                                               else if (b.Target.Member.MemberType == MemberTypes.Method){\r
+                                                       MethodInfo mthSrc = b.Target.Method;\r
                                                        if (mthSrc.IsDefined(typeof(ExtensionAttribute), false))\r
-                                                               targetValue = mthSrc.Invoke(null, new object[] {rb.Target});\r
+                                                               targetValue = mthSrc.Invoke(null, new object[] {b.Target.Instance});\r
                                                        else\r
-                                                               targetValue = mthSrc.Invoke(rb.Target, null);\r
+                                                               targetValue = mthSrc.Invoke(b.Target.Instance, null);\r
                                                }else\r
                                                        throw new Exception ("unandled source member type for binding");                                                \r
-                                       }else if (string.IsNullOrEmpty(rb.Binding.Expression))\r
+                                       }else if (string.IsNullOrEmpty(b.Expression))\r
                                                targetValue= grouped [0].Target;//empty binding exp=> bound to target object by default\r
                                        //TODO: handle other dest type conversions\r
-                                       if (rb.Binding.Property.PropertyType == typeof(string)){\r
+                                       if (b.Source.Property.PropertyType == typeof(string)){\r
                                                if (targetValue == null){\r
                                                        //set default value\r
 \r
                                                }else\r
                                                        targetValue = targetValue.ToString ();\r
                                        }\r
-                                       rb.Binding.Property.GetSetMethod ().Invoke (this, new object[] { targetValue });\r
+                                       b.Source.Property.GetSetMethod ().Invoke (this, new object[] { targetValue });\r
                                        #endregion\r
 \r
                                        //if no dyn update, skip jump table\r
@@ -915,10 +921,10 @@ namespace go
                                                continue;\r
 \r
                                        il.Emit (OpCodes.Ldloc_0);\r
-                                       if (rb.Member != null)\r
-                                               il.Emit (OpCodes.Ldstr, rb.Member.Name);\r
+                                       if (b.Target.Member != null)\r
+                                               il.Emit (OpCodes.Ldstr, b.Target.Member.Name);\r
                                        else\r
-                                               il.Emit (OpCodes.Ldstr, rb.Binding.Expression);\r
+                                               il.Emit (OpCodes.Ldstr, b.Expression);\r
                                        il.Emit (OpCodes.Callvirt, stringEquals);\r
                                        il.Emit (OpCodes.Brtrue, jumpTable[i]);\r
                                        i++;\r
@@ -930,7 +936,7 @@ namespace go
                                il.Emit (OpCodes.Br, endMethod);\r
 \r
                                i = 0;\r
-                               foreach (ResolvedBinding rb in grouped) {\r
+                               foreach (Binding b in grouped) {\r
 \r
                                        il.MarkLabel (jumpTable [i]);\r
                                        il.Emit(OpCodes.Ldloc_1);\r
@@ -938,24 +944,24 @@ namespace go
                                        //by default, target value type is deducted from source member type to allow\r
                                        //memberless binding, if targetMember exists, it will be used to determine target\r
                                        //value type for conversion\r
-                                       Type targetValueType = rb.Binding.Property.PropertyType;\r
-                                       if (rb.Member != null) {\r
-                                               if (rb.Member.MemberType == MemberTypes.Property)\r
-                                                       targetValueType = (rb.Member as PropertyInfo).PropertyType;\r
-                                               else if (rb.Member.MemberType == MemberTypes.Field)\r
-                                                       targetValueType = (rb.Member as FieldInfo).FieldType;\r
+                                       Type targetValueType = b.Source.Property.PropertyType;\r
+                                       if (b.Target.Member != null) {\r
+                                               if (b.Target.Member.MemberType == MemberTypes.Property)\r
+                                                       targetValueType = b.Target.Property.PropertyType;\r
+                                               else if (b.Target.Member.MemberType == MemberTypes.Field)\r
+                                                       targetValueType = b.Target.Field.FieldType;\r
                                                else\r
                                                        throw new Exception ("unhandle target member type in binding");\r
                                        }\r
                                        \r
                                        if (!targetValueType.IsValueType)\r
                                                il.Emit(OpCodes.Castclass, targetValueType);\r
-                                       else if (rb.Binding.Property.PropertyType != targetValueType)\r
-                                               il.Emit(OpCodes.Callvirt, CompilerServices.GetConvertMethod( rb.Binding.Property.PropertyType ));\r
+                                       else if (b.Source.Property.PropertyType != targetValueType)\r
+                                               il.Emit(OpCodes.Callvirt, CompilerServices.GetConvertMethod( b.Source.Property.PropertyType ));\r
                                        else\r
-                                               il.Emit(OpCodes.Unbox_Any, rb.Binding.Property.PropertyType);\r
+                                               il.Emit(OpCodes.Unbox_Any, b.Source.Property.PropertyType);\r
 \r
-                                       il.Emit(OpCodes.Callvirt, rb.Binding.Property.GetSetMethod());\r
+                                       il.Emit(OpCodes.Callvirt, b.Source.Property.GetSetMethod());\r
                                        il.Emit (OpCodes.Br, endMethod);\r
                                        i++;\r
 \r
@@ -966,7 +972,7 @@ namespace go
 \r
                                Delegate del = dm.CreateDelegate(ei.EventHandlerType, this);\r
                                MethodInfo addHandler = ei.GetAddMethod ();\r
-                               addHandler.Invoke(grouped [0].Target, new object[] {del});\r
+                               addHandler.Invoke(grouped [0].Target.Instance, new object[] {del});\r
                        }\r
                }\r
                /// <summary>\r
@@ -978,13 +984,13 @@ namespace go
                        Type sourceType = this.GetType();\r
 \r
                        #region Retrieve EventHandler parameter type\r
-                       MethodInfo evtInvoke = binding.Event.EventHandlerType.GetMethod ("Invoke");\r
+                       MethodInfo evtInvoke = binding.Source.Event.EventHandlerType.GetMethod ("Invoke");\r
                        ParameterInfo[] evtParams = evtInvoke.GetParameters ();\r
                        Type handlerArgsType = evtParams [1].ParameterType;\r
                        #endregion\r
 \r
                        Type[] args = {typeof(object), typeof(object),handlerArgsType};\r
-                       DynamicMethod dm = new DynamicMethod("dynHandle",\r
+                       DynamicMethod dm = new DynamicMethod(binding.NewDynMethodId,\r
                                typeof(void), \r
                                args,\r
                                sourceType);\r
@@ -996,7 +1002,7 @@ namespace go
                        string src = binding.Expression.Trim();\r
 \r
                        if (! (src.StartsWith("{") || src.EndsWith ("}"))) \r
-                               throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", binding.SourceMember.Name, binding.Expression));\r
+                               throw new Exception (string.Format("GOML:Malformed {0} Event handler: {1}", binding.Source.Member.Name, binding.Expression));\r
 \r
                        src = src.Substring (1, src.Length - 2);\r
                        string[] srcLines = src.Split (new char[] { ';' });\r
@@ -1084,8 +1090,8 @@ namespace go
 \r
                        #endregion\r
 \r
-                       Delegate del = dm.CreateDelegate(binding.Event.EventHandlerType,this);\r
-                       MethodInfo addHandler = binding.Event.GetAddMethod ();\r
+                       Delegate del = dm.CreateDelegate(binding.Source.Event.EventHandlerType,this);\r
+                       MethodInfo addHandler = binding.Source.Event.GetAddMethod ();\r
                        addHandler.Invoke(this, new object[] {del});\r
                }\r
 \r
@@ -1112,7 +1118,7 @@ namespace go
                                        continue;\r
                                }\r
                                if (mi.MemberType == MemberTypes.Event) {\r
-                                       this.Bindings.Add (new Binding (mi, attValue));\r
+                                       this.Bindings.Add (new Binding (new MemberReference(this, mi), attValue));\r
                                        continue;\r
                                }\r
                                if (mi.MemberType == MemberTypes.Property) {\r
@@ -1159,7 +1165,7 @@ namespace go
                                                if (!attValue.EndsWith("}"))\r
                                                        throw new Exception (string.Format("GOML:Malformed binding: {0}", attValue));\r
 \r
-                                               this.Bindings.Add (new Binding (pi, attValue.Substring (1, attValue.Length - 2)));\r
+                                               this.Bindings.Add (new Binding (new MemberReference(this, pi), attValue.Substring (1, attValue.Length - 2)));\r
                                                continue;\r
                                        }\r
 \r
@@ -1276,27 +1282,20 @@ namespace go
                ///  and delete ref of this in Shared interface refs\r
                /// </summary>\r
                public virtual void ClearBinding(){\r
-//                     object ds = this.DataSource;\r
-//                     if (ds != null) {\r
-//                             Type dataSourceType = ds.GetType ();\r
-//                             EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged");\r
-//                             if (evtInfo != null) {\r
-//                                     FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged");\r
-//                                     MulticastDelegate multicastDelegate = evtFi.GetValue (ds) as MulticastDelegate;\r
-//                                     if (multicastDelegate != null) {                                \r
-//                                             foreach (Delegate d in multicastDelegate.GetInvocationList()) {\r
-//                                                     string dn = d.Method.Name;\r
-//                                                     if (!dn.StartsWith ("dynHandle_"))\r
-//                                                             continue;\r
-//                                                     int did = int.Parse (dn.Substring (10));\r
-//                                                     if (this.DynamicMethodIds.Contains (did))\r
-//                                                             evtInfo.RemoveEventHandler (ds, d);\r
-//                                             }\r
-//                                     }\r
-//                             }\r
-//                     }\r
-//                     Interface.Unreference (this);\r
-\r
+                       foreach (Binding b in Bindings) {\r
+                               if (string.IsNullOrEmpty (b.DynMethodId))\r
+                                       continue;\r
+                               Type dataSourceType = b.Target.Instance.GetType ();\r
+                               EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged");\r
+                               FieldInfo evtFi = CompilerServices.GetEventHandlerField (dataSourceType, "ValueChanged");\r
+                               MulticastDelegate multicastDelegate = evtFi.GetValue (b.Target.Instance) as MulticastDelegate;\r
+                               if (multicastDelegate != null) {                                \r
+                                       foreach (Delegate d in multicastDelegate.GetInvocationList()) {                                         \r
+                                               if (d.Method.Name == b.DynMethodId)\r
+                                                       evtInfo.RemoveEventHandler (b.Target.Instance, d);\r
+                                       }\r
+                               }\r
+                       }\r
                }\r
        }\r
 }\r
index 304e48b634a8a513cfd5699c3996fc45bb0cabd7..2ce0266bfd32321ebbeb961b39d9c2248efe3e9f 100644 (file)
@@ -454,53 +454,6 @@ namespace go
                        return result;
                }
 
-               public static void resolveGOML (object hostClass)
-               {
-                       foreach (DynAttribute es in GOMLResolver) {
-//                             if (string.IsNullOrEmpty(es.Value))
-//                                     continue;
-
-                               Type dstType = es.Source.GetType ();
-                               MemberInfo miTarget = dstType.GetMember (es.MemberName).FirstOrDefault ();
-
-                               if (miTarget == null) {
-                                       Debug.WriteLine ("'{0}' Member not found in '{1}' type.", es.MemberName, dstType.ToString ());
-                                       continue;
-                               }
-                               
-                               if (miTarget.MemberType == MemberTypes.Event) {
-                                       if (es.Value.StartsWith ("{")) {
-                                               CompilerServices.CompileEventSource (es);
-                                       } else {                                        
-                                               MethodInfo mi = hostClass.GetType ().GetMethod (es.Value, BindingFlags.NonPublic | BindingFlags.Public
-                                                               | BindingFlags.Instance);
-
-                                               object effectiveHostClass = hostClass;
-                                               if (mi == null) {
-                                                       //TODO: hack to have it work, hostClass and dataSource should be clearly separated
-                                                       mi = OpenTKGameWindow.currentWindow.GetType ().GetMethod (es.Value, BindingFlags.NonPublic | BindingFlags.Public
-                                                       | BindingFlags.Instance);
-                                                       if (mi == null) {
-                                                               Debug.WriteLine ("Handler Method not found: " + es.Value);
-                                                               continue;
-                                                       }
-                                                       effectiveHostClass = OpenTKGameWindow.currentWindow;
-                                               }
-
-                                               EventInfo ei = es.Source.GetType ().GetEvent (es.MemberName);
-                                               MethodInfo addHandler = ei.GetAddMethod ();
-                                               Delegate del = Delegate.CreateDelegate (ei.EventHandlerType, effectiveHostClass, mi);
-
-
-                                               addHandler.Invoke (es.Source, new object[] { del });
-
-                                       }
-                               } else {
-                                       CompilerServices.ResolveBinding (es, hostClass);
-                               }
-                       }
-                       GOMLResolutionStack.Pop ();                     
-               }
 
                #endregion
        }