[NUI] Delete the used window in widget
authorsunghyun kim <scholb.kim@samsung.com>
Mon, 19 Jun 2023 01:39:40 +0000 (10:39 +0900)
committerhuiyu <35286162+huiyueun@users.noreply.github.com>
Tue, 11 Jul 2023 05:46:11 +0000 (14:46 +0900)
Delete the used window so that the window can be deleted normally when deleting the widget.
this is for memory leak issue.

src/Tizen.NUI/src/internal/Widget/WidgetImpl.cs
src/Tizen.NUI/src/public/Widget/Widget.cs
test/Tizen.NUI.WidgetViewTest/0.Template/Tizen.NUI.WidgetTest/SimpleWidgetApp.cs
test/Tizen.NUI.WidgetViewTest/0.Template/Tizen.NUI.WidgetViewTest/SimpleWidgetViewApp.cs

index b2850db..15e8ef7 100755 (executable)
@@ -35,6 +35,21 @@ namespace Tizen.NUI
             //throw new global::System.MethodAccessException("C++ destructor does not have public access");
         }
 
+        protected override void Dispose(DisposeTypes type)
+        {
+            if (disposed)
+            {
+                return;
+            }
+
+            if (type == DisposeTypes.Explicit)
+            {
+                SwigDirectorDisconnect();
+            }
+
+            base.Dispose(type);
+        }
+
         public class WIdgetInstanceOnCreateArgs : EventArgs
         {
             private string contentInfo;
@@ -298,6 +313,20 @@ namespace Tizen.NUI
             Interop.WidgetImpl.DirectorConnect(SwigCPtr, swigDelegate0, swigDelegate1, swigDelegate2, swigDelegate3, swigDelegate4, swigDelegate5, swigDelegate6, swigDelegate7);
         }
 
+        private void SwigDirectorDisconnect()
+        {
+            swigDelegate0 = null;
+            swigDelegate1 = null;
+            swigDelegate2 = null;
+            swigDelegate3 = null;
+            swigDelegate4 = null;
+            swigDelegate5 = null;
+            swigDelegate6 = null;
+            swigDelegate7 = null;
+
+            Interop.WidgetImpl.DirectorConnect(SwigCPtr,  null, null, null, null, null, null, null, null);
+        }
+
         private bool SwigDerivedClassHasMethod(string methodName, global::System.Type[] methodTypes)
         {
             global::System.Reflection.MethodInfo methodInfo = this.GetType().GetMethod(methodName, global::System.Reflection.BindingFlags.Public | global::System.Reflection.BindingFlags.NonPublic | global::System.Reflection.BindingFlags.Instance, null, methodTypes, null);
@@ -312,6 +341,12 @@ namespace Tizen.NUI
             {
                 ret = new Window(window, true);
             }
+            else
+            {
+                System.Runtime.InteropServices.HandleRef CPtr = new System.Runtime.InteropServices.HandleRef(this, window);
+                Interop.BaseHandle.DeleteBaseHandle(CPtr);
+                CPtr = new System.Runtime.InteropServices.HandleRef(null, IntPtr.Zero);
+            }
             OnCreate(contentInfo, ret);
         }
 
@@ -337,6 +372,12 @@ namespace Tizen.NUI
             {
                 ret = new Window(window, true);
             }
+            else
+            {
+                System.Runtime.InteropServices.HandleRef CPtr = new System.Runtime.InteropServices.HandleRef(this, window);
+                Interop.BaseHandle.DeleteBaseHandle(CPtr);
+                CPtr = new System.Runtime.InteropServices.HandleRef(null, IntPtr.Zero);
+            }
             OnResize(ret);
         }
 
index ce65cb5..a10d238 100755 (executable)
@@ -46,8 +46,6 @@ namespace Tizen.NUI
             widgetImpl.WidgetInstanceResumed += OnWidgetInstanceResumed;
             widgetImpl.WidgetInstanceResized += OnWidgetInstanceResized;
             widgetImpl.WidgetInstanceUpdated += OnWidgetInstanceUpdated;
-
-            (WidgetApplication.Instance as WidgetApplication)?.AddWidgetInstance(this);
         }
 
         internal Widget(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
index 4189942..79caa8f 100755 (executable)
@@ -122,7 +122,17 @@ namespace WidgetTemplate
 
         protected override void OnTerminate(string contentInfo, TerminationType type)
         {
+            Tizen.Log.Info("NUI", "OnTerminate(BlueWidget) \n");
+            mAnimation.Stop();
+            mAnimation = null;
+            mRootView.Dispose();
+            mRootView = null;
             base.OnTerminate(contentInfo, type);
+
+            // Call GC for deleting window directly
+            global::System.GC.Collect();
+            global::System.GC.WaitForPendingFinalizers();
+            global::System.GC.Collect();
         }
 
         protected override void OnUpdate(string contentInfo, int force)
index 66e9067..061ab2c 100755 (executable)
@@ -62,8 +62,40 @@ namespace WidgetApplicationTemplate
             mWidgetView2.Position = new Position(100, widgetHeight + 110);
             window.GetDefaultLayer().Add(mWidgetView2);
 
+            mTimer = new Timer(4000);
+            mTimer.Tick += onTick;
+            mTimer.Start();
 
+            created = true;
         }
+
+        private bool onTick(object o, Timer.TickEventArgs e)
+        {
+            Window window = GetDefaultWindow();
+            if(created)
+            {
+                WidgetViewManager.Instance.RemoveWidget(mWidgetView2);
+                mWidgetView2.Dispose();
+                mWidgetView2 = null;
+                created = false;
+            }
+            else
+            {
+                Bundle bundle = new Bundle();
+                bundle.AddItem("COUNT", "1");
+                String encodedBundle = bundle.Encode();
+
+                mWidgetView2 = WidgetViewManager.Instance.AddWidget("class2@Tizen.NUI.WidgetTest", encodedBundle, widgetWidth, widgetHeight, 0.0f);
+                mWidgetView2.Position = new Position(100, widgetHeight + 110);
+                window.GetDefaultLayer().Add(mWidgetView2);
+
+                bundle.Dispose();
+                bundle = null;
+                created = true;
+            }
+            return true;
+        }
+
         public void OnKeyEvent(object sender, Window.KeyEventArgs e)
         {
             if (e.Key.State == Key.StateType.Down )
@@ -109,6 +141,11 @@ namespace WidgetApplicationTemplate
         WidgetView mWidgetView2;
         int widgetWidth;
         int widgetHeight;
+
+        Timer mTimer;
+        bool created;
+
+        Window mWindow;
     }
 }