diff options
author | chai <215380520@qq.com> | 2023-05-15 09:28:11 +0800 |
---|---|---|
committer | chai <215380520@qq.com> | 2023-05-15 09:28:11 +0800 |
commit | 3b036c6de871aa519a1f7fbfb52e09618945041f (patch) | |
tree | d5dc6d4f1d501e4ce3c6d69ca7a698a03634490c /WorldlineKeepers/Assets/Scripts/Tools/Notification | |
parent | 6fb204d494b897907d655b5752196983a82ceba2 (diff) |
*misc
Diffstat (limited to 'WorldlineKeepers/Assets/Scripts/Tools/Notification')
6 files changed, 306 insertions, 0 deletions
diff --git a/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationCenter.cs b/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationCenter.cs new file mode 100644 index 0000000..bb4e08e --- /dev/null +++ b/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationCenter.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using UnityEngine; + +namespace WK +{ + + public class NotificationCenter : Singleton<NotificationCenter> + { + public delegate void NotificatonHandler(params object[] args); + + private Dictionary<string/*eventName*/, Dictionary<object/*publisher*/, List<NotificatonHandler>>> m_EventListeners = new Dictionary<string, Dictionary<object, List<NotificatonHandler>>>(); + + /// <summary> + /// 当前在调用中的回调 + /// </summary> + private HashSet<List<NotificatonHandler>> m_CurInvokingCallbacks = new HashSet<List<NotificatonHandler>>(); + + public void AddObserver(string notificationName, NotificatonHandler handler) + { + AddObserver(null, notificationName, handler); + } + + public void AddObserver(object sender, string notificationName, NotificatonHandler handler) + { + if (handler == null) + { + Debug.LogError("Can't add a null event handler for notification, " + notificationName); + return; + } + if (string.IsNullOrEmpty(notificationName)) + { + Debug.LogError("Can't observe an unnamed notification"); + return; + } + if (!m_EventListeners.ContainsKey(notificationName)) + { + m_EventListeners.Add(notificationName, new Dictionary<object, List<NotificatonHandler>>()); + } + Dictionary<object, List<NotificatonHandler>> dictionary = m_EventListeners[notificationName]; + object key = ((sender != null) ? sender : this); + if (!dictionary.ContainsKey(key)) + { + dictionary.Add(key, new List<NotificatonHandler>()); + } + List<NotificatonHandler> list = dictionary[key]; + if (m_CurInvokingCallbacks.Contains(list)) + { + list = (dictionary[key] = new List<NotificatonHandler>(list)); + } + list.Add(handler); + } + + public void RemoveObserver(string notificationName, NotificatonHandler handler) + { + RemoveObserver(null, notificationName, handler); + } + + public void RemoveObserver(object sender, string notificationName, NotificatonHandler handler) + { + if (handler == null) + { + Debug.LogError("Can't remove a null event handler for notification, " + notificationName); + } + else if (string.IsNullOrEmpty(notificationName)) + { + Debug.LogError("A notification name is required to stop observation"); + } + else + { + if (!m_EventListeners.ContainsKey(notificationName)) + { + return; + } + Dictionary<object, List<NotificatonHandler>> dictionary = m_EventListeners[notificationName]; + object key = ((sender != null) ? sender : this); + if (!dictionary.ContainsKey(key)) + { + return; + } + List<NotificatonHandler> list = dictionary[key]; + int num = list.IndexOf(handler); + if (num != -1) + { + if (m_CurInvokingCallbacks.Contains(list)) + { + list = (dictionary[key] = new List<NotificatonHandler>(list)); + } + list.RemoveAt(num); + } + } + } + + public void Clean() + { + string[] array = new string[m_EventListeners.Keys.Count]; + m_EventListeners.Keys.CopyTo(array, 0); + for (int num = array.Length - 1; num >= 0; num--) + { + string key = array[num]; + Dictionary<object, List<NotificatonHandler>> dictionary = m_EventListeners[key]; + object[] array2 = new object[dictionary.Keys.Count]; + dictionary.Keys.CopyTo(array2, 0); + for (int num2 = array2.Length - 1; num2 >= 0; num2--) + { + object key2 = array2[num2]; + if (dictionary[key2].Count == 0) + { + dictionary.Remove(key2); + } + } + if (dictionary.Count == 0) + { + m_EventListeners.Remove(key); + } + } + } + + public void PostNotification(string notificationName) + { + PostNotification(notificationName, null); + } + + public void PostNotification(object sender, string notificationName) + { + PostNotification(sender, notificationName, null); + } + + public void PostNotification(object sender, string notificationName, params object[] p) + { + if (string.IsNullOrEmpty(notificationName)) + { + Debug.LogError("A notification name is required"); + } + else + { + if (!m_EventListeners.ContainsKey(notificationName)) + { + return; + } + Dictionary<object, List<NotificatonHandler>> dictionary = m_EventListeners[notificationName]; + if (sender != null && dictionary.ContainsKey(sender)) + { + List<NotificatonHandler> list = dictionary[sender]; + m_CurInvokingCallbacks.Add(list); + for (int i = 0; i < list.Count; i++) + { + list[i](p); + } + m_CurInvokingCallbacks.Remove(list); + } + if (dictionary.ContainsKey(this)) + { + List<NotificatonHandler> list2 = dictionary[this]; + m_CurInvokingCallbacks.Add(list2); + for (int j = 0; j < list2.Count; j++) + { + list2[j](p); + } + m_CurInvokingCallbacks.Remove(list2); + } + } + } + + } + +} diff --git a/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationCenter.cs.meta b/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationCenter.cs.meta new file mode 100644 index 0000000..13d54ee --- /dev/null +++ b/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationCenter.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f222398a57afbf446b471ccf17bb9575 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationExtensions.cs b/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationExtensions.cs new file mode 100644 index 0000000..8313f7b --- /dev/null +++ b/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationExtensions.cs @@ -0,0 +1,17 @@ +using System; + +namespace WK +{ + + public interface INotification + { + } + + public static class NotificationExtensions + { + public static void AddObserver(this INotification _this, string msg, NotificationCenter.NotificatonHandler handler) { NotificationCenter.Instance.AddObserver(_this, msg, handler); } + public static void RemoveObserver(this INotification _this, string msg, NotificationCenter.NotificatonHandler handler) { NotificationCenter.Instance.RemoveObserver(_this, msg, handler); } + public static void PostNotification(this INotification _this, string msg, params object[] p) { NotificationCenter.Instance.PostNotification(_this, msg, p); } + + } +} diff --git a/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationExtensions.cs.meta b/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationExtensions.cs.meta new file mode 100644 index 0000000..a805d3a --- /dev/null +++ b/WorldlineKeepers/Assets/Scripts/Tools/Notification/NotificationExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 75fb0f8661eca5c4faf394f140fcae88 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/WorldlineKeepers/Assets/Scripts/Tools/Notification/ScopedNotification.cs b/WorldlineKeepers/Assets/Scripts/Tools/Notification/ScopedNotification.cs new file mode 100644 index 0000000..0002f14 --- /dev/null +++ b/WorldlineKeepers/Assets/Scripts/Tools/Notification/ScopedNotification.cs @@ -0,0 +1,89 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +namespace WK +{ + + public class ScopedNotification + { + public delegate void NotificatonHandler(params object[] args); + + private Dictionary<string, List<NotificatonHandler>> m_EventListeners = new Dictionary<string, List<NotificatonHandler>>(); + + public void AddObserver(string eventName, NotificatonHandler handler) + { + if (handler == null) + { + return; + } + + if (string.IsNullOrEmpty(eventName)) + { + return; + } + + List<NotificatonHandler> handlers; + if (!m_EventListeners.ContainsKey(eventName)) + { + m_EventListeners.Add(eventName, new List<NotificatonHandler>()); + } + + handlers = m_EventListeners[eventName]; + handlers.Add(handler); + } + + public void RemoveObserver(string eventName, NotificatonHandler handler) + { + if(handler == null) { return; } + + if(string.IsNullOrEmpty(eventName)) { return; } + + if (!m_EventListeners.ContainsKey(eventName)) + return; + + List<NotificatonHandler> handlers = m_EventListeners[eventName]; + if(handlers.Contains(handler)) + handlers.Remove(handler); + } + + public void RemoveEvent(string eventName) + { + if (string.IsNullOrEmpty(eventName)) { return; } + if(m_EventListeners.ContainsKey(eventName)) + { + m_EventListeners.Remove(eventName); + } + } + + public void Clean() + { + m_EventListeners.Clear(); + } + + public void PostNotification(string eventName, params object[] args) + { + if (string.IsNullOrEmpty(eventName)) { return; } + + if (!m_EventListeners.ContainsKey(eventName)) + return; + + List<NotificatonHandler> handlers = m_EventListeners[eventName]; + for(int i = 0; i < handlers.Count; i++) + { + var handler = handlers[i]; + if(handler != null) + { + handler(args); + } + } + } + + public void PostNotification(string eventName) + { + PostNotification(eventName, null); + } + + } + +}
\ No newline at end of file diff --git a/WorldlineKeepers/Assets/Scripts/Tools/Notification/ScopedNotification.cs.meta b/WorldlineKeepers/Assets/Scripts/Tools/Notification/ScopedNotification.cs.meta new file mode 100644 index 0000000..4ec5672 --- /dev/null +++ b/WorldlineKeepers/Assets/Scripts/Tools/Notification/ScopedNotification.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 66ddfe88aa791154ea0663b56917da4a +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: |