[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 475bd04..9b4f9c8 100755 (executable)
@@ -61,6 +61,7 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            getValueListOp = null;
         }
 
         public void OnActive()
index 2b09a00..f5bd770 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 66d5a16..cd82b34 100755 (executable)
@@ -56,6 +56,7 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            childOp = null;
         }
 
         public void OnActive()
index 481a212..f960bc7 100755 (executable)
@@ -207,6 +207,7 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            getValueList = null;
             valueString = "";
         }
 
index 944e01d..b1b9f93 100755 (executable)
@@ -56,6 +56,7 @@ namespace Tizen.NUI.EXaml
 
         public void Init()
         {
+            getValues = null;
         }
 
         public void OnActive()
index aacd8c0..162eeb2 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 c39e902..40c262a 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 2202292..ebf2728 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 a91420e..72b07cf 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 720f085..f886979 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 fb25b2d..0a63e4a 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 ff2df56..3134b22 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
 {
@@ -40,6 +41,33 @@ namespace Tizen.NUI.EXaml
 
         /// 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)
         {
             if (null == 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.