diff options
| author | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2017-08-27 06:51:36 +0200 |
|---|---|---|
| committer | Jean-Philippe Bruyère <jp_bruyere@hotmail.com> | 2017-08-27 06:51:36 +0200 |
| commit | 6cbe9f9d2a604cdbb74f46f3710ea3dc60a87e55 (patch) | |
| tree | 7e3e675b2f6b14d320b124389b25fde003b63ea6 /src | |
| parent | 3025ab70f5fc51819f5980908a8a98d5d6426b7e (diff) | |
first step in implementing a dispose mechanism for graphic objects
Diffstat (limited to 'src')
| -rw-r--r-- | src/CompilerServices/CompilerServices.cs | 2 | ||||
| -rw-r--r-- | src/CrowThread.cs | 2 | ||||
| -rw-r--r-- | src/GraphicObjects/GraphicObject.cs | 71 | ||||
| -rw-r--r-- | src/GraphicObjects/Group.cs | 14 | ||||
| -rw-r--r-- | src/GraphicObjects/PrivateContainer.cs | 9 | ||||
| -rw-r--r-- | src/GraphicObjects/TemplatedControl.cs | 6 | ||||
| -rw-r--r-- | src/GraphicObjects/TemplatedGroup.cs | 12 | ||||
| -rw-r--r-- | src/Interface.cs | 51 |
8 files changed, 135 insertions, 32 deletions
diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index 5884ee66..5409aa5e 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -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); diff --git a/src/CrowThread.cs b/src/CrowThread.cs index 857ec1a3..fbcdc956 100644 --- a/src/CrowThread.cs +++ b/src/CrowThread.cs @@ -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; diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index aad6e327..8fd9a6e9 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -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 =""; diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index a02b9669..f3026290 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -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 (); + } } } diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index 499f998f..89b30753 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -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 (); + } } } diff --git a/src/GraphicObjects/TemplatedControl.cs b/src/GraphicObjects/TemplatedControl.cs index b0d752ed..ba580dae 100644 --- a/src/GraphicObjects/TemplatedControl.cs +++ b/src/GraphicObjects/TemplatedControl.cs @@ -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)); diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs index 4e997598..e4e29404 100644 --- a/src/GraphicObjects/TemplatedGroup.cs +++ b/src/GraphicObjects/TemplatedGroup.cs @@ -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 (); + } } } diff --git a/src/Interface.cs b/src/Interface.cs index adcb2830..baa46667 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -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) |