using System; using System.Collections.Generic; using UnityEngine; namespace WK { public sealed class NotificationCenter : Singleton { public delegate void NotificatonHandler(params object[] args); private Dictionary>> m_EventListeners = new Dictionary>>(); /// /// 当前在调用中的回调 /// private HashSet> m_CurInvokingCallbacks = new HashSet>(); 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>()); } Dictionary> dictionary = m_EventListeners[notificationName]; object key = ((sender != null) ? sender : this); if (!dictionary.ContainsKey(key)) { dictionary.Add(key, new List()); } List list = dictionary[key]; if (m_CurInvokingCallbacks.Contains(list)) { list = (dictionary[key] = new List(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> dictionary = m_EventListeners[notificationName]; object key = ((sender != null) ? sender : this); if (!dictionary.ContainsKey(key)) { return; } List list = dictionary[key]; int num = list.IndexOf(handler); if (num != -1) { if (m_CurInvokingCallbacks.Contains(list)) { list = (dictionary[key] = new List(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> 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> dictionary = m_EventListeners[notificationName]; if (sender != null && dictionary.ContainsKey(sender)) { List 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 list2 = dictionary[this]; m_CurInvokingCallbacks.Add(list2); for (int j = 0; j < list2.Count; j++) { list2[j](p); } m_CurInvokingCallbacks.Remove(list2); } } } } }