aboutsummaryrefslogtreecommitdiffstatsci
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>2017-08-27 06:51:36 +0200
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>2017-08-27 06:51:36 +0200
commit6cbe9f9d2a604cdbb74f46f3710ea3dc60a87e55 (patch)
tree7e3e675b2f6b14d320b124389b25fde003b63ea6 /src
parent3025ab70f5fc51819f5980908a8a98d5d6426b7e (diff)
first step in implementing a dispose mechanism for graphic objects
Diffstat (limited to 'src')
-rw-r--r--src/CompilerServices/CompilerServices.cs2
-rw-r--r--src/CrowThread.cs2
-rw-r--r--src/GraphicObjects/GraphicObject.cs71
-rw-r--r--src/GraphicObjects/Group.cs14
-rw-r--r--src/GraphicObjects/PrivateContainer.cs9
-rw-r--r--src/GraphicObjects/TemplatedControl.cs6
-rw-r--r--src/GraphicObjects/TemplatedGroup.cs12
-rw-r--r--src/Interface.cs51
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)