]> O.S.I.I.S - jp/crow.git/commitdiff
first step in implementing a dispose mechanism for graphic objects
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 27 Aug 2017 04:51:36 +0000 (06:51 +0200)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Sun, 27 Aug 2017 04:51:36 +0000 (06:51 +0200)
src/CompilerServices/CompilerServices.cs
src/CrowThread.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Group.cs
src/GraphicObjects/PrivateContainer.cs
src/GraphicObjects/TemplatedControl.cs
src/GraphicObjects/TemplatedGroup.cs
src/Interface.cs

index 5884ee66ba1aa19cfc21b78eed725b8be72156ec..5409aa5e7b2210ac63148d7459fe30ae8d941f6b 100644 (file)
@@ -632,7 +632,9 @@ namespace Crow
                        Type t = instance.GetType ();
                        FieldInfo fiEvt = getEventHandlerField (t, eventName);
                        if (fiEvt == null) {
+                               #if DEBUG_BINDING
                                Debug.WriteLine ("RemoveHandlerByName: Event '" + eventName + "' not found in " + instance);
+                               #endif
                                return;
                        }
                        EventInfo eiEvt = t.GetEvent (eventName);
index 857ec1a32fdb3456c98e0fa3e406f31a0b274786..fbcdc9569d96f2b7796b0a1d250852cba2f60c6e 100644 (file)
@@ -33,6 +33,7 @@ namespace Crow
        /// Thread monitored by current interface with Finished event when state==Stopped
        /// </summary>
        public class CrowThread {
+               public bool cancel = false;
                Thread thread;
                public event EventHandler Finished;
                public GraphicObject Host;
@@ -53,6 +54,7 @@ namespace Crow
                public void Start() { thread.Start();}
                public void Cancel(){
                        if (thread.IsAlive){
+                               cancel = true;
                                //cancelLoading = true;
                                thread.Join ();
                                //cancelLoading = false;
index aad6e327f50abd448abe2e012516d3fa3cd9d7d4..8fd9a6e99a1945c576b01a27295e5481d373509c 100644 (file)
@@ -38,8 +38,27 @@ using System.IO;
 
 namespace Crow
 {
-       public class GraphicObject : ILayoutable, IValueChange
+       public class GraphicObject : ILayoutable, IValueChange, IDisposable
        {
+               #region IDisposable implementation
+
+               public virtual void Dispose ()
+               {
+                       #if DEBUG_DISPOSE
+                       Debug.WriteLine ("{0} Disposed", this.ToString());
+                       #endif
+
+                       parent = null;
+                       if (IsQueueForRedraw)
+                               Debugger.Break ();
+                       if (!localDataSourceIsNull)
+                               DataSource = null;
+                       Clipping?.Dispose ();
+                       bmp?.Dispose ();
+               }
+
+               #endregion
+
                internal static ulong currentUid = 0;
                internal ulong uid = 0;
 
@@ -804,12 +823,27 @@ namespace Crow
                public virtual bool Contains(GraphicObject goToFind){
                        return false;
                }
+               /// <summary>
+               /// return true if this is contained inside go
+               /// </summary>
+               public bool IsInside(GraphicObject go){
+                       ILayoutable p = this.Parent;
+                       while (p != null) {
+                               if (p == go)
+                                       return true;
+                               p = p.Parent;
+                       }
+                       return false;
+               }
 
                #region Queuing
                /// <summary>
                /// Register old and new slot for clipping
                /// </summary>
                public virtual void ClippingRegistration(){
+                       #if DEBUG_UPDATE
+                       Debug.WriteLine (string.Format("ClippingRegistration -> {0}", this.ToString ()));
+                       #endif
                        IsQueueForRedraw = false;
                        if (Parent == null)
                                return;
@@ -821,6 +855,9 @@ namespace Crow
                /// </summary>
                /// <param name="clip">Clip rectangle</param>
                public virtual void RegisterClip(Rectangle clip){
+                       #if DEBUG_UPDATE
+                       Debug.WriteLine (string.Format("RegisterClip -> {1}:{0}", clip, this.ToString ()));
+                       #endif
                        Rectangle  r = clip + ClientRectangle.Position;
                        if (CacheEnabled && !IsDirty)
                                Clipping.UnionRectangle (r);
@@ -835,6 +872,9 @@ namespace Crow
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
                public void RegisterForGraphicUpdate ()
                {
+                       #if DEBUG_UPDATE
+                       Debug.WriteLine (string.Format("RegisterForGraphicUpdate -> {0}", this.ToString ()));
+                       #endif
                        IsDirty = true;
                        if (Width.IsFit || Height.IsFit)
                                RegisterForLayouting (LayoutingType.Sizing);
@@ -845,6 +885,9 @@ namespace Crow
                [MethodImpl(MethodImplOptions.AggressiveInlining)]
                public void RegisterForRedraw ()
                {
+                       #if DEBUG_UPDATE
+                       Debug.WriteLine (string.Format("RegisterForRedraw -> {0}", this.ToString ()));
+                       #endif
                        IsDirty = true;
                        if (RegisteredLayoutings == LayoutingType.None)
                                currentInterface.EnqueueForRepaint (this);
@@ -1091,6 +1134,9 @@ namespace Crow
                /// this trigger the effective drawing routine </summary>
                protected virtual void RecreateCache ()
                {
+                       #if DEBUG_UPDATE
+                       Debug.WriteLine ("RecreateCache -> {0}", this.ToString ());
+                       #endif
                        IsDirty = false;
                        if (bmp != null)
                                bmp.Dispose ();
@@ -1102,6 +1148,9 @@ namespace Crow
                        bmp.Flush ();
                }
                protected virtual void UpdateCache(Context ctx){
+                       #if DEBUG_UPDATE
+                       Debug.WriteLine ("UpdateCache -> {0}", this.ToString ());
+                       #endif
                        Rectangle rb = Slot + Parent.ClientRectangle.Position;
                        if (clearBackground) {
                                        ctx.Save ();
@@ -1119,6 +1168,9 @@ namespace Crow
                /// of the widget </summary>
                public virtual void Paint (ref Context ctx)
                {
+                       #if DEBUG_UPDATE
+                       Debug.WriteLine (string.Format("Paint -> {0}", this.ToString ()));
+                       #endif
                        //TODO:this test should not be necessary
                        if (Slot.Height < 0 || Slot.Width < 0 || parent == null)
                                return;
@@ -1307,7 +1359,22 @@ namespace Crow
                protected virtual void onLogicalParentChanged(object sender, DataSourceChangeEventArgs e) {
                        LogicalParentChanged.Raise (this, e);
                }
-
+               internal void ClearTemplateBinding(){
+                       #if DEBUG_UPDATE
+                       Debug.WriteLine (string.Format("ClearTemplateBinding: {0}", this.ToString()));
+                       #endif
+                       if (ValueChanged == null)
+                               return;
+                       EventInfo eiEvt = this.GetType().GetEvent ("ValueChanged");
+                       foreach (Delegate d in ValueChanged.GetInvocationList()) {
+                               if (d.Method.Name == "dyn_tmpValueChanged") {
+                                       eiEvt.RemoveEventHandler (this, d);
+                                       #if DEBUG_BINDING
+                                       Debug.WriteLine ("\t{0} template binding handler removed in {1} for: {2}", d.Method.Name, this, "ValueChanged");
+                                       #endif
+                               }
+                       }
+               }
                public override string ToString ()
                {
                        string tmp ="";
index a02b9669ac7a1d6ab2d48ce5f55c83c6deb562bb..f3026290e6de145b8c7430fe1cc9b92f2fae1e53 100644 (file)
@@ -73,16 +73,17 @@ namespace Crow
         public virtual void RemoveChild(GraphicObject child)        
                {
                        child.LayoutChanged -= OnChildLayoutChanges;
-                       //child.Parent = null;
+                       child.Parent = null;
 
                        //check if HoverWidget is removed from Tree
                        if (currentInterface.HoverWidget != null) {
-                               if (this.Contains (currentInterface.HoverWidget))
+                               if (currentInterface.HoverWidget.IsInside(this))
                                        currentInterface.HoverWidget = null;
                        }
 
                        lock (children)
                Children.Remove(child);
+                       child.Dispose ();
 
                        if (child == largestChild && Width == Measure.Fit)
                                searchLargestChild ();
@@ -97,8 +98,8 @@ namespace Crow
                                while (Children.Count > 0) {
                                        GraphicObject g = Children [Children.Count - 1];
                                        g.LayoutChanged -= OnChildLayoutChanges;
-                                       g.Parent = null;
                                        Children.RemoveAt (Children.Count - 1);
+                                       g.Dispose ();
                                }
                        }
 
@@ -364,5 +365,12 @@ namespace Crow
                        base.checkHoverWidget (e);
                }
                #endregion
+
+               public override void Dispose ()
+               {
+                       foreach (GraphicObject c in children)
+                               c.Dispose ();
+                       base.Dispose ();
+               }
        }
 }
index 499f998f486557a97a2c50ec09d39c9069d9c6ca..89b3075312a86aaa977859402e386bc42c593a10 100644 (file)
@@ -55,11 +55,12 @@ namespace Crow
                        if (child != null) {
                                //check if HoverWidget is removed from Tree
                                if (currentInterface.HoverWidget != null) {
-                                       if (this.Contains (currentInterface.HoverWidget))
+                                       if (currentInterface.HoverWidget.IsInside(this))
                                                currentInterface.HoverWidget = null;
                                }
                                contentSize = new Size (0, 0);
                                child.LayoutChanged -= OnChildLayoutChanges;
+                               child.Dispose ();
                                child.Parent = null;
                                this.RegisterForGraphicUpdate ();
                        }
@@ -212,6 +213,12 @@ namespace Crow
                }
                #endregion
 
+               public override void Dispose ()
+               {
+                       if (child != null)
+                               child.Dispose ();
+                       base.Dispose ();
+               }
        }
 }
 
index b0d752eda18ff51b29b40e008a98675317f4325d..ba580dae830cd2724adc877e8116d6de65bdd723 100644 (file)
@@ -48,6 +48,9 @@ namespace Crow
                string _template;
                string caption;
 
+               /// <summary>
+               /// Template path
+               /// </summary>
                [XmlAttributeAttribute][DefaultValue(null)]
                public string Template {
                        get { return _template; }
@@ -99,6 +102,9 @@ namespace Crow
 
                protected virtual void loadTemplate(GraphicObject template = null)
                {
+                       if (this.child != null)//template change, bindings has to be reset
+                               this.ClearTemplateBinding();
+                       
                        if (template == null) {
                                if (!Interface.DefaultTemplates.ContainsKey (this.GetType ().FullName))
                                        throw new Exception (string.Format ("No default template found for '{0}'", this.GetType ().FullName));
index 4e9975983b51b17229ee6aeb1951613cc8b5683b..e4e294043ab8972fb002c35dc0f8bff68dc70a4c 100644 (file)
@@ -56,7 +56,6 @@ namespace Crow
 
                int itemPerPage = 50;
                CrowThread loadingThread = null;
-               volatile bool cancelLoading = false;
 
                bool isPaged = false;
 
@@ -274,7 +273,7 @@ namespace Crow
                                ItemTemplates ["default"] = Interface.GetItemTemplate (ItemTemplate);
 
                        for (int i = 1; i <= (data.Count / itemPerPage) + 1; i++) {
-                               if (cancelLoading)
+                               if ((bool)loadingThread?.cancel)
                                        return;
                                loadPage (i);
                                Thread.Sleep (1);
@@ -316,7 +315,7 @@ namespace Crow
                        for (int i = (pageNum - 1) * itemPerPage; i < pageNum * itemPerPage; i++) {
                                if (i >= data.Count)
                                        break;
-                               if (cancelLoading)
+                               if ((bool)loadingThread?.cancel)
                                        return;
 
                                loadItem (i, page);
@@ -426,5 +425,12 @@ namespace Crow
                internal virtual void itemClick(object sender, MouseButtonEventArgs e){
                        SelectedIndex = data.IndexOf((sender as GraphicObject).DataSource);
                }
+
+               public override void Dispose ()
+               {
+                       if (loadingThread != null)
+                               loadingThread.Cancel ();
+                       base.Dispose ();
+               }
        }
 }
index adcb283095acb695be13207dd1427b9c7488fcb5..baa466679281028ac97b114c71035303180d6675 100644 (file)
@@ -593,15 +593,40 @@ namespace Crow
                public void DeleteWidget(GraphicObject g)
                {
                        if (_hoverWidget != null) {
-                               if (g.Contains (_hoverWidget))
+                               if (_hoverWidget.IsInside(g))
                                        HoverWidget = null;
                        }
                        lock (UpdateMutex) {
-                               g.DataSource = null;
-                               g.Visible = false;
+                               RegisterClip (g.ScreenCoordinates (g.LastPaintedSlot));
                                GraphicTree.Remove (g);
+                               g.Parent = null;
+                               g.Dispose ();
                        }
                }
+               /// <summary> Remove all Graphic objects from top container </summary>
+               public void ClearInterface()
+               {
+                       lock (UpdateMutex) {
+                               while (GraphicTree.Count > 0) {
+                                       //TODO:parent is not reset to null because object will be added
+                                       //to ObjectToRedraw list, and without parent, it fails
+                                       GraphicObject g = GraphicTree [0];
+                                       if (_hoverWidget != null) {
+                                               if (_hoverWidget.IsInside(g))
+                                                       HoverWidget = null;
+                                       }
+                                       RegisterClip (g.ScreenCoordinates (g.LastPaintedSlot));
+                                       GraphicTree.RemoveAt (0);
+                                       g.Dispose ();
+                               }
+                       }
+                       #if DEBUG_LAYOUTING
+                       LQIsTries = new List<LQIList>();
+                       curLQIsTries = new LQIList();
+                       LQIs = new List<LQIList>();
+                       curLQIs = new LQIList();
+                       #endif
+               }
                /// <summary> Put widget on top of other root widgets</summary>
                public void PutOnTop(GraphicObject g, bool isOverlay = false)
                {
@@ -626,26 +651,6 @@ namespace Crow
                                EnqueueForRepaint (g);
                        }
                }
-               /// <summary> Remove all Graphic objects from top container </summary>
-               public void ClearInterface()
-               {
-                       lock (UpdateMutex) {
-                               while (GraphicTree.Count > 0) {
-                                       //TODO:parent is not reset to null because object will be added
-                                       //to ObjectToRedraw list, and without parent, it fails
-                                       GraphicObject g = GraphicTree [0];
-                                       g.DataSource = null;
-                                       g.Visible = false;
-                                       GraphicTree.RemoveAt (0);
-                               }
-                       }
-                       #if DEBUG_LAYOUTING
-                       LQIsTries = new List<LQIList>();
-                       curLQIsTries = new LQIList();
-                       LQIs = new List<LQIList>();
-                       curLQIs = new LQIList();
-                       #endif
-               }
 
                /// <summary>Search a Graphic object in the tree named 'nameToFind'</summary>
                public GraphicObject FindByName (string nameToFind)