[Xaml] Provide method so that user can dispose all xaml objects
authorFang Xiaohui <xiaohui.fang@samsung.com>
Thu, 15 Jul 2021 08:08:29 +0000 (16:08 +0800)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Mon, 19 Jul 2021 09:01:03 +0000 (18:01 +0900)
13 files changed:
src/Tizen.NUI/src/internal/EXaml/Action/AddExistInstanceAction.cs
src/Tizen.NUI/src/internal/EXaml/Action/CreateInstanceAction.cs
src/Tizen.NUI/src/internal/EXaml/Action/GetObjectByPropertyAction.cs
src/Tizen.NUI/src/internal/EXaml/Action/GetValueAction.cs
src/Tizen.NUI/src/internal/EXaml/Action/OtherActions.cs
src/Tizen.NUI/src/internal/EXaml/GlobalDataList.cs
src/Tizen.NUI/src/internal/EXaml/LoadEXaml.cs
src/Tizen.NUI/src/internal/EXaml/Operation/AddEvent.cs
src/Tizen.NUI/src/internal/EXaml/Operation/CreateInstance.cs
src/Tizen.NUI/src/internal/EXaml/Operation/GatherBindableProperties.cs
src/Tizen.NUI/src/internal/EXaml/Operation/GatherStaticInstance.cs
src/Tizen.NUI/src/internal/EXaml/Operation/RemoveEvent.cs [new file with mode: 0755]
src/Tizen.NUI/src/public/EXaml/EXamlExtensions.cs

index 475bd04de39d0dbe91d182513576c402f128facb..9b4f9c84ed0c00991c2a905bcce00819537575fb 100755 (executable)
@@ -61,6 +61,7 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            getValueListOp = null;
         }
 
         public void OnActive()
index 2b09a000d5a3f8da60853a8521070047b57c95c4..f5bd7703552d721343ee4e652f5fd282fe97581b 100755 (executable)
@@ -68,6 +68,10 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            getTypeIndexOp = null;
+            getXFactoryMethodIndexOp = null;
+            getParamListOp = null;
+            getStaticInstanceOp = null;
         }
 
         public void OnActive()
index 66d5a16764a957ac1fdb5156a18a2c4b176ec878..cd82b342a4920fadb277c30f09668aa4cb99300b 100755 (executable)
@@ -56,6 +56,7 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            childOp = null;
         }
 
         public void OnActive()
index 481a2125c58c8662ccc19317b01a2af97c4ca76e..f960bc791d8e3d4216414736438b1c2809c723d2 100755 (executable)
@@ -207,6 +207,7 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            getValueList = null;
             valueString = "";
         }
 
index 944e01d65ac704a3fe60451d37bf3e57fb57ddd9..b1b9f9338a0a3e153fb9b84a6c4bdd3a8c0ce803 100755 (executable)
@@ -56,6 +56,7 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            getValues = null;
         }
 
         public void OnActive()
index aacd8c0592cadbaca2ff8bc87803a055ec549a52..162eeb2269f4ef24c255223b8b982a49e82e6438 100755 (executable)
@@ -40,6 +40,11 @@ namespace Tizen.NUI.EXaml
             get;
         } = new List<Operation>();
 
+        internal List<Operation> RemoveEventOperations
+        {
+            get;
+        } = new List<Operation>();
+
         internal List<object> GatheredInstances
         {
             get;
index c39e90250b7477ff98a171a8d4cc10e215d0b487..40c262a47f4451596dd7b7b67d2941127e1b6284 100755 (executable)
@@ -169,7 +169,7 @@ namespace Tizen.NUI.EXaml
             return globalDataList;
         }
 
-        internal static void Load(object view, string xaml)
+        internal static void Load(object view, string xaml, out object xamlData)
         {
             var globalDataList = GatherDataList(xaml);
 
@@ -179,6 +179,8 @@ namespace Tizen.NUI.EXaml
             {
                 op.Do();
             }
+
+            xamlData = globalDataList;
         }
 
         internal static void Load(object view, object preloadData)
@@ -197,5 +199,16 @@ namespace Tizen.NUI.EXaml
                 op.Do();
             }
         }
+
+        internal static void RemoveEventsInXaml(object eXamlData)
+        {
+            if (eXamlData is GlobalDataList globalDataList)
+            {
+                foreach (var op in globalDataList.RemoveEventOperations)
+                {
+                    op.Do();
+                }
+            }
+        }
     }
 }
index 2202292b20c23510131f713daf6f1faccfd1eefc..ebf27283e362cdf53faca97ca56ef850190f578b 100755 (executable)
@@ -45,7 +45,26 @@ namespace Tizen.NUI.EXaml
             try
             {
                 var methodInfo = globalDataList.GatheredMethods[valueIndex];
-                eventInfo.AddEventHandler(instance, methodInfo.CreateDelegate(eventInfo.EventHandlerType, element));
+                Delegate eventDelegate = null;
+
+                if (methodInfo.IsStatic)
+                {
+                    eventDelegate = methodInfo.CreateDelegate(eventInfo.EventHandlerType);
+                }
+                else
+                {
+                    eventDelegate = methodInfo.CreateDelegate(eventInfo.EventHandlerType, element);
+                }
+
+                if (null != eventDelegate)
+                {
+                    eventInfo.AddEventHandler(instance, eventDelegate);
+                    globalDataList.RemoveEventOperations.Add(new RemoveEvent(eventDelegate, instance, eventInfo));
+                }
+                else
+                {
+                    throw new Exception($"Can't create delegate for method {methodInfo.DeclaringType.FullName}.{methodInfo.Name}");
+                }
             }
             catch (ArgumentException ae)
             {
index a91420e7d8f22409f4a1c09a01deb60163d41093..72b07cf4c879af5c94751903861313b06bd9738f 100755 (executable)
@@ -40,9 +40,11 @@ namespace Tizen.NUI.EXaml
 
         public void Do()
         {
+            object obj = null;
+
             if (0 == globalDataList.GatheredInstances.Count && null != globalDataList.Root)
             {
-                globalDataList.GatheredInstances.Add(globalDataList.Root);
+                obj = globalDataList.Root;
             }
             else
             {
@@ -54,11 +56,11 @@ namespace Tizen.NUI.EXaml
                 {
                     if (null == xFactoryMethod)
                     {
-                        globalDataList.GatheredInstances.Add(Activator.CreateInstance(type));
+                        obj = Activator.CreateInstance(type);
                     }
                     else
                     {
-                        globalDataList.GatheredInstances.Add(xFactoryMethod.Invoke(null, Array.Empty<object>()));
+                        obj = xFactoryMethod.Invoke(null, Array.Empty<object>());
                     }
                 }
                 else
@@ -78,25 +80,34 @@ namespace Tizen.NUI.EXaml
 
                     if (null == xFactoryMethod)
                     {
-                        globalDataList.GatheredInstances.Add(Activator.CreateInstance(type, paramList.ToArray()));
+                        obj = Activator.CreateInstance(type, paramList.ToArray());
                     }
                     else
                     {
-                        globalDataList.GatheredInstances.Add(xFactoryMethod.Invoke(null, paramList.ToArray()));
+                        obj = xFactoryMethod.Invoke(null, paramList.ToArray());
                     }
                 }
             }
 
-            if (1 == globalDataList.GatheredInstances.Count)
+            if (null != obj)
             {
-                var rootObject = globalDataList.GatheredInstances[0] as BindableObject;
-                if (null != rootObject)
+                globalDataList.GatheredInstances.Add(obj);
+
+                if (obj is BindableObject bindableObject)
                 {
-                    rootObject.IsCreateByXaml = true;
-                    NameScope nameScope = new NameScope();
-                    NameScope.SetNameScope(rootObject, nameScope);
+                    bindableObject.IsCreateByXaml = true;
+
+                    if (1 == globalDataList.GatheredInstances.Count)
+                    {
+                        NameScope nameScope = new NameScope();
+                        NameScope.SetNameScope(bindableObject, nameScope);
+                    }
                 }
             }
+            else
+            {
+                throw new Exception($"Can't create instance typeIndex:{typeIndex}");
+            }
         }
 
         private int typeIndex;
index 720f0858c078ae22c4f5bb5fb29254874e9b73d6..f88697950ffcdd452c46120a4f00cf7afc4e4448 100755 (executable)
@@ -38,6 +38,11 @@ namespace Tizen.NUI.EXaml
         public void Do()
         {
             var type = globalDataList.GatheredTypes[typeIndex];
+            if (null == type)
+            {
+                throw new Exception($"Type of index {typeIndex} is null");
+            }
+
             var field = type.GetField(fi => fi.Name == propertyName && fi.IsStatic && fi.IsPublic);
             if (null == field)
             {
index fb25b2d88ba981f3fd3dbde0f594fab5ec370d33..0a63e4a67774c8f6d2f65e70ae5612f23ec2fb85 100755 (executable)
@@ -42,9 +42,11 @@ namespace Tizen.NUI.EXaml
 
         public void Do()
         {
+            object obj = null;
+
             if (0 == globalDataList.GatheredInstances.Count && null != globalDataList.Root)
             {
-                globalDataList.GatheredInstances.Add(globalDataList.Root);
+                obj = globalDataList.Root;
             }
             else
             {
@@ -52,26 +54,43 @@ namespace Tizen.NUI.EXaml
 
                 if (null != fieldName)
                 {
-                    var instance = type.GetField(fieldName, BindingFlags.Static | BindingFlags.Public).GetValue(null);
-                    globalDataList.GatheredInstances.Add(instance);
+                    obj = type.GetField(fieldName, BindingFlags.Static | BindingFlags.Public).GetValue(null);
                 }
                 else
                 {
-                    var instance = type.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public).GetValue(null);
-                    globalDataList.GatheredInstances.Add(instance);
+                    obj = type.GetProperty(propertyName, BindingFlags.Static | BindingFlags.Public).GetValue(null);
                 }
             }
 
-            if (1 == globalDataList.GatheredInstances.Count)
+            if (null != obj)
             {
-                var rootObject = globalDataList.GatheredInstances[0] as BindableObject;
-                if (null != rootObject)
+                globalDataList.GatheredInstances.Add(obj);
+
+                if (obj is BindableObject bindableObject)
                 {
-                    rootObject.IsCreateByXaml = true;
-                    NameScope nameScope = new NameScope();
-                    NameScope.SetNameScope(rootObject, nameScope);
+                    bindableObject.IsCreateByXaml = true;
+
+                    if (1 == globalDataList.GatheredInstances.Count)
+                    {
+                        NameScope nameScope = new NameScope();
+                        NameScope.SetNameScope(bindableObject, nameScope);
+                    }
                 }
             }
+            else
+            {
+                string name = null;
+                if (null != fieldName)
+                {
+                    name = fieldName;
+                }
+                else
+                {
+                    name = propertyName;
+                }
+
+                throw new Exception($"Can't gather static instance typeIndex:{typeIndex}, name:{name}");
+            }
         }
 
         private int typeIndex;
diff --git a/src/Tizen.NUI/src/internal/EXaml/Operation/RemoveEvent.cs b/src/Tizen.NUI/src/internal/EXaml/Operation/RemoveEvent.cs
new file mode 100755 (executable)
index 0000000..9b7a261
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using System.Text;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Binding.Internals;
+
+namespace Tizen.NUI.EXaml
+{
+    internal class RemoveEvent : Operation
+    {
+        public RemoveEvent(Delegate eventDelegate, object instance, EventInfo eventInfo)
+        {
+            this.instance = instance;
+            this.eventInfo = eventInfo;
+            this.eventDelegate = eventDelegate;
+        }
+
+        public void Do()
+        {
+            try
+            {
+                eventInfo.RemoveEventHandler(instance, eventDelegate);
+            }
+            catch (ArgumentException ae)
+            {
+                Tizen.Log.Fatal("EXaml", ae.ToString());
+            }
+        }
+
+        private object instance;
+        private EventInfo eventInfo;
+        private Delegate eventDelegate;
+    }
+}
index ff2df56381c41ce2fb19d3ceaad15a4e6e7c239b..3134b22f995da06ea3e2b43cfde8ef87b9a3297a 100755 (executable)
@@ -20,6 +20,7 @@ using System.ComponentModel;
 using System.IO;
 using System.Reflection;
 using System.Text;
+using Tizen.NUI.BaseComponents;
 
 namespace Tizen.NUI.EXaml
 {
@@ -38,6 +39,33 @@ namespace Tizen.NUI.EXaml
             return view;
         }
 
+        /// Internal used, will never be opened.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void RemoveEventsInXaml(object eXamlData)
+        {
+            LoadEXaml.RemoveEventsInXaml(eXamlData);
+        }
+
+        /// Internal used, will never be opened.
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static void DisposeXamlElements(object view)
+        {
+            if (view is Container container)
+            {
+                for (int i = (int)container.ChildCount - 1; i >= 0; i--)
+                {
+                    var child = container.Children[i];
+
+                    if (child.IsCreateByXaml)
+                    {
+                        child.Unparent();
+                        DisposeXamlElements(child);
+                        child.Dispose();
+                    }
+                }
+            }
+        }
+
         /// Internal used, will never be opened.
         [EditorBrowsable(EditorBrowsableState.Never)]
         public static T LoadFromEXamlPath<T>(this T view, Type callingType)
@@ -80,11 +108,13 @@ namespace Tizen.NUI.EXaml
 
         /// Internal used, will never be opened.
         [EditorBrowsable(EditorBrowsableState.Never)]
-        public static T LoadFromEXamlByRelativePath<T>(this T view, string eXamlPath)
+        public static object LoadFromEXamlByRelativePath<T>(this T view, string eXamlPath)
         {
+            object eXamlData = null;
+
             if (null == eXamlPath)
             {
-                return view;
+                return eXamlData;
             }
 
             MainAssembly = view.GetType().Assembly;
@@ -105,14 +135,14 @@ namespace Tizen.NUI.EXaml
                 reader.Close();
                 reader.Dispose();
 
-                LoadEXaml.Load(view, xaml);
+                LoadEXaml.Load(view, xaml, out eXamlData);
             }
             else
             {
-                throw new Exception($"Can't find examl file {eXamlPath}");
+                throw new Exception($"Can't find examl file {likelyResourcePath}");
             }
 
-            return view;
+            return eXamlData;
         }
 
         /// Used for TCT and TC coverage, will never be opened.