]> O.S.I.I.S - jp/crow.git/commitdiff
Clear Bindings when GraphicObject is destroyed
authorjpbruyere <jp.bruyere@hotmail.com>
Mon, 14 Sep 2015 10:30:20 +0000 (12:30 +0200)
committerjpbruyere <jp.bruyere@hotmail.com>
Mon, 14 Sep 2015 10:30:20 +0000 (12:30 +0200)
src/CompilerServices/CompilerServices.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Group.cs
src/GraphicObjects/PrivateContainer.cs
src/OpenTKGameWindow.cs

index f383c8eea3e26e574c88abc2f56f21efe7309ed3..b6a43eb14b7b48b4a138a7171c6b2c274997da95 100644 (file)
@@ -12,32 +12,6 @@ namespace go
 {
        public static class CompilerServices
        {
-               public static void createDynHandler(string eventName, 
-                       object dstObj, Type handlerArgsType, string destProp, string src)
-               {
-                       Type dstType = dstObj.GetType ();
-
-                       Type[] args = {typeof(object), handlerArgsType};
-                       DynamicMethod hello = new DynamicMethod("dynHandle",
-                               typeof(void), 
-                               args, 
-                               dstType.Module);
-
-                       MethodInfo dstMi = dstType.GetProperty (destProp).GetSetMethod ();
-                       FieldInfo srcFi = typeof(go.Color).GetField (src, BindingFlags.Static|BindingFlags.Public);
-                       ILGenerator il = hello.GetILGenerator(256);
-
-                       il.Emit(OpCodes.Ldarg_0);
-                       il.Emit (OpCodes.Ldsfld, srcFi);
-                       il.Emit(OpCodes.Callvirt, dstMi);
-                       il.Emit(OpCodes.Ret);
-                       //hello.DefineParameter(1, ParameterAttributes.In, "instance");
-                       //hello.DefineParameter(2, ParameterAttributes.In, "value");
-                       FieldInfo fi = getEventHandlerField (dstType, eventName);
-                       Delegate del = hello.CreateDelegate(fi.FieldType);
-                       fi.SetValue(dstObj, del);
-
-               }
                static int dynHandleCpt = 0;
                /// <summary>
                /// Compile events expression in GOML attributes
@@ -60,6 +34,10 @@ namespace go
                                typeof(void), 
                                args, 
                                srcType.Module);
+                       
+                       es.Source.DynamicMethodIds.Add (dynHandleCpt);
+
+                       dynHandleCpt++;
 
                        #region IL generation
                        ILGenerator il = dm.GetILGenerator(256);
@@ -155,7 +133,7 @@ namespace go
 
                        #endregion
 
-                       FieldInfo evtFi = getEventHandlerField (srcType, es.MemberName);
+                       FieldInfo evtFi = GetEventHandlerField (srcType, es.MemberName);
                        Delegate del = dm.CreateDelegate(evtFi.FieldType);
                        evtFi.SetValue(es.Source, del);
                }
@@ -269,6 +247,10 @@ namespace go
                                args, 
                                srcType.Module, true);
 
+                       (binding.Source as GraphicObject).DynamicMethodIds.Add (dynHandleCpt);
+
+                       dynHandleCpt++;
+
                        //register target object reference
                        int dstIdx = Interface.References.IndexOf(binding.Source);
 
@@ -385,7 +367,7 @@ namespace go
                }
                #endregion
                        
-               public static FieldInfo getEventHandlerField(Type type, string eventName)
+               public static FieldInfo GetEventHandlerField(Type type, string eventName)
                {
                        FieldInfo fi;
                        Type ty = type;
index f8ffb51155c90faa06cbab0b8dee2453b6a69073..c9f7a39fa4be19d49b1583feacb1999deea882da 100644 (file)
@@ -21,6 +21,8 @@ namespace go
 {\r
        public class GraphicObject : IXmlSerializable, ILayoutable, IValueChange\r
        {\r
+               internal List<int> DynamicMethodIds = new List<int> ();\r
+\r
                #region IValueChange implementation\r
                public event EventHandler<ValueChangeEventArgs> ValueChanged;\r
                public virtual void NotifyValueChanged(string MemberName, object _value)\r
@@ -304,7 +306,17 @@ namespace go
                        get { return _minimumSize; }\r
                        set { _minimumSize = value; }\r
                }\r
-               [XmlIgnore]public object DataSource;\r
+               object dataSource;\r
+\r
+               [XmlIgnore]public object DataSource {\r
+                       set {\r
+                               dataSource = value;\r
+                       }\r
+                       get {                           \r
+                               return dataSource == null ? \r
+                                       Parent is GraphicObject ? (Parent as GraphicObject).DataSource : null : dataSource;\r
+                       }\r
+               }\r
                #endregion\r
 \r
                /// <summary>\r
@@ -632,7 +644,7 @@ namespace go
                        using (ImageSurface draw =\r
                 new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, stride)) {\r
                                using (Context gr = new Context (draw)) {\r
-                                       gr.Antialias = Antialias.Subpixel;\r
+                                       gr.Antialias = Antialias.Gray;\r
                                        onDraw (gr);\r
                                }\r
                                draw.Flush ();\r
@@ -917,5 +929,31 @@ namespace go
                }\r
                #endregion\r
 \r
+               /// <summary>\r
+               /// Remove dynamic delegates by ids from dataSource\r
+               ///  and delete ref of this in Shared interface refs\r
+               /// </summary>\r
+               public virtual void ClearBinding(){\r
+                       if (this.DataSource == null)\r
+                               return;\r
+                       object ds = this.DataSource;\r
+                       Type dataSourceType = ds.GetType ();\r
+                       EventInfo evtInfo = dataSourceType.GetEvent ("ValueChanged");\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
+                               {\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
+                       Interface.References.Remove (this);\r
+               }\r
        }\r
 }\r
index d9e35aa8eafa110f2639371565237c00261f6377..87a9ee5ccfcc259e362bb3bfc76221c934336efd 100644 (file)
@@ -278,5 +278,11 @@ namespace go
         }\r
     \r
                #endregion\r
+\r
+               public override void ClearBinding(){\r
+                       foreach (GraphicObject c in children)\r
+                               c.ClearBinding ();\r
+                       base.ClearBinding ();\r
+               }\r
        }\r
 }\r
index b6391621fa5d4a57a9e4d5af29bc11bb805304da..010fca7195e1b7b85035cb7eb1e918b7a927e351 100644 (file)
@@ -146,6 +146,13 @@ namespace go
                                child.checkHoverWidget (e);
                }
                #endregion
+
+               public override void ClearBinding ()
+               {
+                       if (child != null)
+                               child.ClearBinding ();
+                       base.ClearBinding ();
+               }
        }
 }
 
index 355ae304018bcd555ed8782c74ea40b5cfa1e3d8..a50a05be51eb6eef4c13cedaec8d513fde924251 100755 (executable)
@@ -86,13 +86,16 @@ namespace go
                public void DeleteWidget(GraphicObject g)\r
                {\r
                        g.Visible = false;//trick to ensure clip is added to refresh zone\r
+                       g.ClearBinding();\r
                        GraphicObjects.Remove (g);\r
                }\r
                /// <summary> Remove all Graphic objects from top container </summary>\r
                public void ClearInterface()\r
                {\r
-                       foreach (GraphicObject g in GraphicObjects)\r
+                       foreach (GraphicObject g in GraphicObjects) {\r
                                g.Visible = false;\r
+                               g.ClearBinding ();\r
+                       }\r
                        GraphicObjects.Clear ();\r
                }\r
                public void Quit ()\r