diff options
| author | j-p <jp.bruyere@live.be> | 2017-08-28 05:12:19 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-08-28 05:12:19 +0200 |
| commit | 1d9aa6aa61da3dd5f1a1a488018ceb8b5a88f2af (patch) | |
| tree | e7e9aed2ad7b0947855ce9d70a52267b128fec0c /src/GraphicObjects | |
| parent | d6d7eda88ae12d6c47d6c158a5a9527a47447745 (diff) | |
full IDisposable implementation (#34)
* full implementation of IDisposable, not stable, lock and still leaking
* override dispose in popper to handle _content not yet in graphic tree (when never shown), test focusedWidget when disposing
* prevent canceling thread multiple times causing a deadlock
* test parent type when trying to close window
Diffstat (limited to 'src/GraphicObjects')
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 55 | ||||
| -rw-r--r-- | src/GraphicObjects/Group.cs | 16 | ||||
| -rw-r--r-- | src/GraphicObjects/Popper.cs | 9 | ||||
| -rw-r--r-- | src/GraphicObjects/PrivateContainer.cs | 11 | ||||
| -rw-r--r-- | src/GraphicObjects/TemplatedGroup.cs | 16 | ||||
| -rw-r--r-- | src/GraphicObjects/Window.cs | 7 |
6 files changed, 78 insertions, 36 deletions
diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 8fd9a6e9..93e812de 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -41,22 +41,51 @@ namespace Crow public class GraphicObject : ILayoutable, IValueChange, IDisposable { #region IDisposable implementation + protected bool disposed = false; - public virtual void Dispose () - { - #if DEBUG_DISPOSE - Debug.WriteLine ("{0} Disposed", this.ToString()); - #endif + public void Dispose(){ + Dispose(true); + GC.SuppressFinalize(this); + } + ~GraphicObject(){ + Dispose(false); + } + protected virtual void Dispose(bool disposing){ + if (disposed){ + #if DEBUG_DISPOSE + Debug.WriteLine ("Trying to dispose already disposed obj: {0}", this.ToString()); + #endif + return; + } - parent = null; - if (IsQueueForRedraw) - Debugger.Break (); - if (!localDataSourceIsNull) - DataSource = null; + if (disposing) { + #if DEBUG_DISPOSE + Debug.WriteLine ("Disposing: {0}", this.ToString()); + if (IsQueueForRedraw) + throw new Exception("Trying to dispose an object queued for Redraw: " + this.ToString()); + #endif + if (currentInterface.HoverWidget != null) { + if (currentInterface.HoverWidget.IsOrIsInside(this)) + currentInterface.HoverWidget = null; + } + if (currentInterface.ActiveWidget != null) { + if (currentInterface.ActiveWidget.IsOrIsInside (this)) + currentInterface.ActiveWidget = null; + } + if (currentInterface.FocusedWidget != null) { + if (currentInterface.FocusedWidget.IsOrIsInside (this)) + currentInterface.FocusedWidget = null; + } + if (!localDataSourceIsNull) + DataSource = null; + parent = null; + } else + Debug.WriteLine ("!!! Finalized by GC: {0}", this.ToString ()); Clipping?.Dispose (); bmp?.Dispose (); - } + disposed = true; + } #endregion internal static ulong currentUid = 0; @@ -826,7 +855,9 @@ namespace Crow /// <summary> /// return true if this is contained inside go /// </summary> - public bool IsInside(GraphicObject go){ + public bool IsOrIsInside(GraphicObject go){ + if (this == go) + return true; ILayoutable p = this.Parent; while (p != null) { if (p == go) diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index f3026290..e7d7d4d4 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -73,13 +73,9 @@ namespace Crow public virtual void RemoveChild(GraphicObject child) { child.LayoutChanged -= OnChildLayoutChanges; - child.Parent = null; //check if HoverWidget is removed from Tree - if (currentInterface.HoverWidget != null) { - if (currentInterface.HoverWidget.IsInside(this)) - currentInterface.HoverWidget = null; - } + lock (children) Children.Remove(child); @@ -366,11 +362,13 @@ namespace Crow } #endregion - public override void Dispose () + protected override void Dispose (bool disposing) { - foreach (GraphicObject c in children) - c.Dispose (); - base.Dispose (); + if (disposing) { + foreach (GraphicObject c in children) + c.Dispose (); + } + base.Dispose (disposing); } } } diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index 3ba6d711..d6e36346 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -240,5 +240,14 @@ namespace Crow } Unpoped.Raise (this, e); } + + protected override void Dispose (bool disposing) + { + if (_content != null && disposing) { + if (_content.Parent == null) + _content.Dispose (); + } + base.Dispose (disposing); + } } } diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index 89b30753..077f732f 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -54,14 +54,9 @@ namespace Crow if (child != null) { //check if HoverWidget is removed from Tree - if (currentInterface.HoverWidget != null) { - if (currentInterface.HoverWidget.IsInside(this)) - currentInterface.HoverWidget = null; - } contentSize = new Size (0, 0); child.LayoutChanged -= OnChildLayoutChanges; child.Dispose (); - child.Parent = null; this.RegisterForGraphicUpdate (); } @@ -213,11 +208,11 @@ namespace Crow } #endregion - public override void Dispose () + protected override void Dispose (bool disposing) { - if (child != null) + if (disposing && child != null) child.Dispose (); - base.Dispose (); + base.Dispose (disposing); } } } diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs index e4e29404..1cbc4935 100644 --- a/src/GraphicObjects/TemplatedGroup.cs +++ b/src/GraphicObjects/TemplatedGroup.cs @@ -273,8 +273,10 @@ namespace Crow ItemTemplates ["default"] = Interface.GetItemTemplate (ItemTemplate); for (int i = 1; i <= (data.Count / itemPerPage) + 1; i++) { - if ((bool)loadingThread?.cancel) + if ((bool)loadingThread?.cancelRequested) { + this.Dispose (); return; + } loadPage (i); Thread.Sleep (1); } @@ -315,8 +317,10 @@ namespace Crow for (int i = (pageNum - 1) * itemPerPage; i < pageNum * itemPerPage; i++) { if (i >= data.Count) break; - if ((bool)loadingThread?.cancel) + if ((bool)loadingThread?.cancelRequested) { + page.Dispose (); return; + } loadItem (i, page); } @@ -336,7 +340,7 @@ namespace Crow string getItempKey(Type dataType, object o){ try { return dataType.GetProperty (_dataTest).GetGetMethod ().Invoke (o, null).ToString(); - } catch (Exception ex) { + } catch { return dataType.FullName; } } @@ -426,11 +430,11 @@ namespace Crow SelectedIndex = data.IndexOf((sender as GraphicObject).DataSource); } - public override void Dispose () + protected override void Dispose (bool disposing) { - if (loadingThread != null) + if (disposing && loadingThread != null) loadingThread.Cancel (); - base.Dispose (); + base.Dispose (disposing); } } } diff --git a/src/GraphicObjects/Window.cs b/src/GraphicObjects/Window.cs index e0c97ea9..176e8d90 100644 --- a/src/GraphicObjects/Window.cs +++ b/src/GraphicObjects/Window.cs @@ -391,7 +391,12 @@ namespace Crow protected void close(){ Closing.Raise (this, null); - currentInterface.DeleteWidget (this); + if (Parent is Interface) + (Parent as Interface).DeleteWidget (this); + else if (Parent is Group) + (Parent as Group).RemoveChild (this); + else if (Parent is PrivateContainer) + (Parent as Container).Child = null; } } } |