From 0c60cc12d350be999db940a353a7f41d92d491cc Mon Sep 17 00:00:00 2001 From: Jiyun Yang Date: Fri, 28 Jul 2023 14:55:30 +0900 Subject: [PATCH] [NUI] Add WeakEventProxy class and improve invoke of WeakEvent * WeakEventProxy : The weak event connecting to a normal event. Signed-off-by: Jiyun Yang --- src/Tizen.NUI/src/internal/Common/WeakEvent.cs | 52 +++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/src/Tizen.NUI/src/internal/Common/WeakEvent.cs b/src/Tizen.NUI/src/internal/Common/WeakEvent.cs index 29a4456..a2745cf 100755 --- a/src/Tizen.NUI/src/internal/Common/WeakEvent.cs +++ b/src/Tizen.NUI/src/internal/Common/WeakEvent.cs @@ -25,28 +25,33 @@ namespace Tizen.NUI { private List> handlers = new List>(); - public void Add(T handler) + protected int Count => handlers.Count; + + public virtual void Add(T handler) { handlers.Add(new WeakHandler(handler)); } - public void Remove(T handler) + public virtual void Remove(T handler) { handlers.RemoveAll(item => !item.IsAlive || item.Equals(handler)); } public void Invoke(object sender, EventArgs args) { - var copied = handlers.ToArray(); - foreach (var item in copied) + var disposed = new HashSet>(); + + foreach (var item in handlers) { if (item.IsAlive) { item.Invoke(sender, args); continue; } - handlers.Remove(item); + disposed.Add(item); } + + handlers.RemoveAll(disposed.Contains); } internal class WeakHandler @@ -88,4 +93,41 @@ namespace Tizen.NUI } } } + + /// + /// 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. + /// + internal abstract class WeakEventProxy : WeakEvent> + { + 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, EventArgsT args) + { + Invoke(sender, args as EventArgs); + } + } } -- 2.7.4