sync with devel/master branch
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI / src / internal / Button.cs
index de51409..51a416c 100755 (executable)
@@ -55,28 +55,39 @@ namespace Tizen.NUI.UIComponents
         /// <summary>
         /// To make Button instance be disposed.
         /// </summary>
-        public override void Dispose()
+        protected override void Dispose(DisposeTypes type)
         {
-            if (!Window.IsInstalled())
+            if (disposed)
             {
-                DisposeQueue.Instance.Add(this);
                 return;
             }
 
-            lock (this)
+            if (type == DisposeTypes.Explicit)
             {
-                if (swigCPtr.Handle != global::System.IntPtr.Zero)
+                //Called by User
+                //Release your own managed resources here.
+                //You should release all of your own disposable objects here.
+
+            }
+
+            //Release your own unmanaged resources here.
+            //You should not access any managed member here except static instance.
+            //because the execution order of Finalizes is non-deterministic.
+
+            //Unreference this from if a static instance refer to this. 
+            ViewRegistry.UnregisterView(this);
+
+            if (swigCPtr.Handle != global::System.IntPtr.Zero)
+            {
+                if (swigCMemOwn)
                 {
-                    if (swigCMemOwn)
-                    {
-                        swigCMemOwn = false;
-                        NDalicPINVOKE.delete_Button(swigCPtr);
-                    }
-                    swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
+                    swigCMemOwn = false;
+                    NDalicPINVOKE.delete_Button(swigCPtr);
                 }
-                global::System.GC.SuppressFinalize(this);
-                base.Dispose();
+                swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
             }
+
+            base.Dispose(type);
         }
 
 
@@ -508,31 +519,69 @@ namespace Tizen.NUI.UIComponents
                 return (obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr;
             }
 
+            //A Flag to check who called Dispose(). (By User or DisposeQueue)
+            private bool isDisposeQueued = false;
+            //A Flat to check if it is already disposed.
+            protected bool disposed = false;
+
             ~Property()
             {
-                DisposeQueue.Instance.Add(this);
+                if (!isDisposeQueued)
+                {
+                    isDisposeQueued = true;
+                    DisposeQueue.Instance.Add(this);
+                }
             }
 
-            public virtual void Dispose()
+            public void Dispose()
             {
-                if (!Window.IsInstalled()) {
-                    DisposeQueue.Instance.Add(this);
+                //Throw excpetion if Dispose() is called in separate thread.
+                if (!Window.IsInstalled())
+                {
+                    throw new System.InvalidOperationException("This API called from separate thread. This API must be called from MainThread.");
+                }
+
+                if (isDisposeQueued)
+                {
+                    Dispose(DisposeTypes.Implicit);
+                }
+                else
+                {
+                    Dispose(DisposeTypes.Explicit);
+                    System.GC.SuppressFinalize(this);
+                }
+            }
+
+            protected virtual void Dispose(DisposeTypes type)
+            {
+                if (disposed)
+                {
                     return;
                 }
 
-                lock (this)
+                if (type == DisposeTypes.Explicit)
                 {
-                    if (swigCPtr.Handle != global::System.IntPtr.Zero)
+                    //Called by User
+                    //Release your own managed resources here.
+                    //You should release all of your own disposable objects here.
+
+                }
+
+                //Release your own unmanaged resources here.
+                //You should not access any managed member here except static instance.
+                //because the execution order of Finalizes is non-deterministic.
+
+                if (swigCPtr.Handle != global::System.IntPtr.Zero)
+                {
+                    if (swigCMemOwn)
                     {
-                        if (swigCMemOwn)
-                        {
-                            swigCMemOwn = false;
-                            NDalicPINVOKE.delete_Button_Property(swigCPtr);
-                        }
-                        swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
+                        swigCMemOwn = false;
+                        NDalicPINVOKE.delete_Button_Property(swigCPtr);
                     }
-                    global::System.GC.SuppressFinalize(this);
+                    swigCPtr = new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero);
                 }
+
+                disposed = true;
             }
 
             internal static readonly int UNSELECTED_VISUAL = NDalicManualPINVOKE.Button_Property_UNSELECTED_VISUAL_get();