[NUI] Remove strong references of text components regarding events
authorJiyun Yang <ji.yang@samsung.com>
Tue, 8 Aug 2023 10:27:07 +0000 (19:27 +0900)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 16 Aug 2023 12:04:45 +0000 (21:04 +0900)
* Improve WeakEvent
  * Lazy list initialization
  * Provide count changed callback methods
  * Separate file into WeakEvent and WeakEventProxy
* Fix TextLabel, TextField, TextEditor
  * Do not register event handler to the system event directly.
  * Instead they use WeakEventProxy to get GCed without Dispose call.

Signed-off-by: Jiyun Yang <ji.yang@samsung.com>
src/Tizen.NUI/src/internal/Common/WeakEvent.cs
src/Tizen.NUI/src/internal/Common/WeakEventProxy.cs [new file with mode: 0644]
src/Tizen.NUI/src/public/BaseComponents/TextEditor.cs
src/Tizen.NUI/src/public/BaseComponents/TextField.cs
src/Tizen.NUI/src/public/BaseComponents/TextLabel.cs

index e886b93..83c2c59 100755 (executable)
@@ -29,18 +29,44 @@ namespace Tizen.NUI
 
         public virtual void Add(T handler)
         {
+            if (handlers == null)
+            {
+                handlers = new List<WeakHandler<T>>();
+            }
+
             handlers.Add(new WeakHandler<T>(handler));
+
+            OnCountIncreased();
         }
 
         public virtual void Remove(T handler)
         {
+            if (handlers == null)
+            {
+                return;
+            }
+
+            int count = handlers.Count;
+
             handlers.RemoveAll(item => !item.IsAlive || item.Equals(handler));
+
+            if (count > handlers.Count)
+            {
+                OnCountDicreased();
+            }
         }
 
         public void Invoke(object sender, EventArgs args)
         {
+            if (handlers == null)
+            {
+                return;
+            }
+
             var disposed = new HashSet<WeakHandler<T>>();
 
+            int count = handlers.Count;
+
             foreach (var item in handlers)
             {
                 if (item.IsAlive)
@@ -52,6 +78,20 @@ namespace Tizen.NUI
             }
 
             handlers.RemoveAll(disposed.Contains);
+
+            if (count > handlers.Count)
+            {
+                OnCountDicreased();
+            }
+        }
+
+        protected virtual void OnCountIncreased()
+        {
+        }
+
+
+        protected virtual void OnCountDicreased()
+        {
         }
 
         internal class WeakHandler<U>
@@ -93,76 +133,4 @@ namespace Tizen.NUI
             }
         }
     }
-
-    /// <summary>
-    /// Internal class that helps to make a proxy weak event connecting to a normal source event.
-    /// Note that the source event will have a strong reference of the WeakEventProxy instance instead of handler's.
-    /// Please replace it to WeakEventManager after version up.
-    /// </summary>
-    internal abstract class WeakEventProxy<EventArgsT> : WeakEvent<EventHandler<EventArgsT>>
-    {
-        protected abstract void ConnectToEvent(EventHandler<EventArgsT> handler);
-
-        protected abstract void DisconnectToEvent(EventHandler<EventArgsT> handler);
-
-        public override void Add(EventHandler<EventArgsT> handler)
-        {
-            if (Count == 0)
-            {
-                ConnectToEvent(OnEventInvoked);
-            }
-
-            base.Add(handler);
-        }
-
-        public override void Remove(EventHandler<EventArgsT> handler)
-        {
-            base.Remove(handler);
-
-            if (Count == 0)
-            {
-                DisconnectToEvent(OnEventInvoked);
-            }
-        }
-
-        private void OnEventInvoked(object sender, EventArgsT args)
-        {
-            Invoke(sender, args as EventArgs);
-        }
-    }
-
-    /// <summary>
-    /// The non-generic version of <see cref="WeakEventProxy"/>.
-    /// </summary>
-    internal abstract class WeakEventProxy : WeakEvent<EventHandler>
-    {
-        protected abstract void ConnectToEvent(EventHandler handler);
-
-        protected abstract void DisconnectToEvent(EventHandler handler);
-
-        public override void Add(EventHandler handler)
-        {
-            if (Count == 0)
-            {
-                ConnectToEvent(OnEventInvoked);
-            }
-
-            base.Add(handler);
-        }
-
-        public override void Remove(EventHandler handler)
-        {
-            base.Remove(handler);
-
-            if (Count == 0)
-            {
-                DisconnectToEvent(OnEventInvoked);
-            }
-        }
-
-        private void OnEventInvoked(object sender, EventArgs args)
-        {
-            Invoke(sender, args);
-        }
-    }
 }
diff --git a/src/Tizen.NUI/src/internal/Common/WeakEventProxy.cs b/src/Tizen.NUI/src/internal/Common/WeakEventProxy.cs
new file mode 100644 (file)
index 0000000..0d236e2
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2023 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.
+ *
+ */
+
+extern alias TizenSystemSettings;
+using TizenSystemSettings.Tizen.System;
+
+using System;
+
+namespace Tizen.NUI
+{
+    /// <summary>
+    /// Internal class that helps to make a proxy weak event connecting to a normal source event.
+    /// Note that the source event will have a strong reference of the WeakEventProxy instance instead of handler's.
+    /// Please replace it to WeakEventManager after version up.
+    /// </summary>
+    internal abstract class WeakEventProxy<EventArgsT> : WeakEvent<EventHandler<EventArgsT>>
+    {
+        protected abstract void ConnectToEvent(EventHandler<EventArgsT> handler);
+
+        protected abstract void DisconnectToEvent(EventHandler<EventArgsT> handler);
+
+        protected override void OnCountIncreased()
+        {
+            if (Count == 1)
+            {
+                ConnectToEvent(OnEventInvoked);
+            }
+        }
+
+        protected override void OnCountDicreased()
+        {
+            if (Count == 0)
+            {
+                DisconnectToEvent(OnEventInvoked);
+            }
+        }
+
+        private void OnEventInvoked(object sender, EventArgsT args)
+        {
+            Invoke(sender, args as EventArgs);
+        }
+    }
+
+    /// <summary>
+    /// The non-generic version of <see cref="WeakEventProxy"/>.
+    /// </summary>
+    internal abstract class WeakEventProxy : WeakEvent<EventHandler>
+    {
+        protected abstract void ConnectToEvent(EventHandler handler);
+
+        protected abstract void DisconnectToEvent(EventHandler handler);
+
+        protected override void OnCountIncreased()
+        {
+            if (Count == 1)
+            {
+                ConnectToEvent(OnEventInvoked);
+            }
+        }
+
+        protected override void OnCountDicreased()
+        {
+            if (Count == 0)
+            {
+                DisconnectToEvent(OnEventInvoked);
+            }
+        }
+
+        private void OnEventInvoked(object sender, EventArgs args)
+        {
+            Invoke(sender, args);
+        }
+    }
+
+    internal class SystemFontTypeChanged : WeakEventProxy<FontTypeChangedEventArgs>
+    {
+        protected override void ConnectToEvent(EventHandler<FontTypeChangedEventArgs> handler)
+        {
+            SystemSettings.FontTypeChanged += handler;
+        }
+
+        protected override void DisconnectToEvent(EventHandler<FontTypeChangedEventArgs> handler)
+        {
+            SystemSettings.FontTypeChanged -= handler;
+        }
+    }
+
+    internal class SystemFontSizeChanged : WeakEventProxy<FontSizeChangedEventArgs>
+    {
+        protected override void ConnectToEvent(EventHandler<FontSizeChangedEventArgs> handler)
+        {
+            SystemSettings.FontSizeChanged += handler;
+        }
+
+        protected override void DisconnectToEvent(EventHandler<FontSizeChangedEventArgs> handler)
+        {
+            SystemSettings.FontSizeChanged -= handler;
+        }
+    }
+
+    internal class SystemLocaleLanguageChanged : WeakEventProxy<LocaleLanguageChangedEventArgs>
+    {
+        protected override void ConnectToEvent(EventHandler<LocaleLanguageChangedEventArgs> handler)
+        {
+            SystemSettings.LocaleLanguageChanged += handler;
+        }
+
+        protected override void DisconnectToEvent(EventHandler<LocaleLanguageChangedEventArgs> handler)
+        {
+            SystemSettings.LocaleLanguageChanged -= handler;
+        }
+    }
+}
index 9c6e7a9..0ba45ac 100755 (executable)
@@ -34,6 +34,9 @@ namespace Tizen.NUI.BaseComponents
     {
         static private string defaultStyleName = "Tizen.NUI.BaseComponents.TextEditor";
         static private string defaultFontFamily = "TizenSans";
+        private static SystemFontTypeChanged systemFontTypeChanged = new SystemFontTypeChanged();
+        private static SystemFontSizeChanged systemFontSizeChanged = new SystemFontSizeChanged();
+        private static SystemLocaleLanguageChanged systemLocaleLanguageChanged = new SystemLocaleLanguageChanged();
         private string textEditorTextSid = null;
         private string textEditorPlaceHolderTextSid = null;
         private InputMethodContext inputMethodContext = null;
@@ -2500,7 +2503,7 @@ namespace Tizen.NUI.BaseComponents
 
             if (hasSystemLanguageChanged)
             {
-                SystemSettings.LocaleLanguageChanged -= SystemSettings_LocaleLanguageChanged;
+                systemLocaleLanguageChanged.Remove(SystemSettings_LocaleLanguageChanged);
             }
 
             RemoveSystemSettingsFontTypeChanged();
@@ -2576,7 +2579,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 if (hasSystemLanguageChanged == false)
                 {
-                    SystemSettings.LocaleLanguageChanged += SystemSettings_LocaleLanguageChanged;
+                    systemLocaleLanguageChanged.Add(SystemSettings_LocaleLanguageChanged);
                     hasSystemLanguageChanged = true;
                 }
                 return translatableText;
@@ -2612,7 +2615,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontSizeChanged += SystemSettingsFontSizeChanged;
+                    systemFontSizeChanged.Add(SystemSettingsFontSizeChanged);
                     hasSystemFontSizeChanged = true;
                 }
                 catch (Exception e)
@@ -2629,7 +2632,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontSizeChanged -= SystemSettingsFontSizeChanged;
+                    systemFontSizeChanged.Remove(SystemSettingsFontSizeChanged);
                     hasSystemFontSizeChanged = false;
                 }
                 catch (Exception e)
@@ -2651,7 +2654,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontTypeChanged += SystemSettingsFontTypeChanged;
+                    systemFontTypeChanged.Add(SystemSettingsFontTypeChanged);
                     hasSystemFontTypeChanged = true;
                 }
                 catch (Exception e)
@@ -2668,7 +2671,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontTypeChanged -= SystemSettingsFontTypeChanged;
+                    systemFontTypeChanged.Remove(SystemSettingsFontTypeChanged);
                     hasSystemFontTypeChanged = false;
                 }
                 catch (Exception e)
index d239256..cc4871c 100755 (executable)
@@ -33,6 +33,9 @@ namespace Tizen.NUI.BaseComponents
     {
         static private string defaultStyleName = "Tizen.NUI.BaseComponents.TextField";
         static private string defaultFontFamily = "TizenSans";
+        private static SystemFontTypeChanged systemFontTypeChanged = new SystemFontTypeChanged();
+        private static SystemFontSizeChanged systemFontSizeChanged = new SystemFontSizeChanged();
+        private static SystemLocaleLanguageChanged systemLocaleLanguageChanged = new SystemLocaleLanguageChanged();
         private string textFieldTextSid = null;
         private string textFieldPlaceHolderTextSid = null;
         private string textFieldPlaceHolderTextFocusedSid = null;
@@ -2498,7 +2501,7 @@ namespace Tizen.NUI.BaseComponents
 
             if (hasSystemLanguageChanged)
             {
-                SystemSettings.LocaleLanguageChanged -= SystemSettingsLocaleLanguageChanged;
+                systemLocaleLanguageChanged.Remove(SystemSettingsLocaleLanguageChanged);
             }
 
             RemoveSystemSettingsFontTypeChanged();
@@ -2580,7 +2583,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 if (hasSystemLanguageChanged == false)
                 {
-                    SystemSettings.LocaleLanguageChanged += SystemSettingsLocaleLanguageChanged;
+                    systemLocaleLanguageChanged.Add(SystemSettingsLocaleLanguageChanged);
                     hasSystemLanguageChanged = true;
                 }
                 return translatableText;
@@ -2620,7 +2623,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontSizeChanged += SystemSettingsFontSizeChanged;
+                    systemFontSizeChanged.Add(SystemSettingsFontSizeChanged);
                     hasSystemFontSizeChanged = true;
                 }
                 catch (Exception e)
@@ -2637,7 +2640,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontSizeChanged -= SystemSettingsFontSizeChanged;
+                    systemFontSizeChanged.Remove(SystemSettingsFontSizeChanged);
                     hasSystemFontSizeChanged = false;
                 }
                 catch (Exception e)
@@ -2659,7 +2662,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontTypeChanged += SystemSettingsFontTypeChanged;
+                    systemFontTypeChanged.Add(SystemSettingsFontTypeChanged);
                     hasSystemFontTypeChanged = true;
                 }
                 catch (Exception e)
@@ -2676,7 +2679,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontTypeChanged -= SystemSettingsFontTypeChanged;
+                    systemFontTypeChanged.Remove(SystemSettingsFontTypeChanged);
                     hasSystemFontTypeChanged = false;
                 }
                 catch (Exception e)
index f3b532f..59b1b4f 100755 (executable)
@@ -84,6 +84,9 @@ namespace Tizen.NUI.BaseComponents
 
         static TextLabel() { }
 
+        private static SystemFontTypeChanged systemFontTypeChanged = new SystemFontTypeChanged();
+        private static SystemFontSizeChanged systemFontSizeChanged = new SystemFontSizeChanged();
+        private static SystemLocaleLanguageChanged systemLocaleLanguageChanged = new SystemLocaleLanguageChanged();
         static private string defaultStyleName = "Tizen.NUI.BaseComponents.TextLabel";
         static private string defaultFontFamily = "BreezeSans";
         private string textLabelSid = null;
@@ -216,7 +219,7 @@ namespace Tizen.NUI.BaseComponents
                     Text = translatableText;
                     if (hasSystemLanguageChanged == false)
                     {
-                        SystemSettings.LocaleLanguageChanged += SystemSettingsLocaleLanguageChanged;
+                        systemLocaleLanguageChanged.Add(SystemSettingsLocaleLanguageChanged);
                         hasSystemLanguageChanged = true;
                     }
                 }
@@ -1566,7 +1569,7 @@ namespace Tizen.NUI.BaseComponents
 
             if (hasSystemLanguageChanged)
             {
-                SystemSettings.LocaleLanguageChanged -= SystemSettingsLocaleLanguageChanged;
+                systemLocaleLanguageChanged.Remove(SystemSettingsLocaleLanguageChanged);
             }
 
             RemoveSystemSettingsFontTypeChanged();
@@ -1637,7 +1640,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontSizeChanged += SystemSettingsFontSizeChanged;
+                    systemFontSizeChanged.Add(SystemSettingsFontSizeChanged);
                     hasSystemFontSizeChanged = true;
                 }
                 catch (Exception e)
@@ -1654,7 +1657,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontSizeChanged -= SystemSettingsFontSizeChanged;
+                    systemFontSizeChanged.Remove(SystemSettingsFontSizeChanged);
                     hasSystemFontSizeChanged = false;
                 }
                 catch (Exception e)
@@ -1676,7 +1679,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontTypeChanged += SystemSettingsFontTypeChanged;
+                    systemFontTypeChanged.Add(SystemSettingsFontTypeChanged);
                     hasSystemFontTypeChanged = true;
                 }
                 catch (Exception e)
@@ -1693,7 +1696,7 @@ namespace Tizen.NUI.BaseComponents
             {
                 try
                 {
-                    SystemSettings.FontTypeChanged -= SystemSettingsFontTypeChanged;
+                    systemFontTypeChanged.Remove(SystemSettingsFontTypeChanged);
                     hasSystemFontTypeChanged = false;
                 }
                 catch (Exception e)