123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- // #define LOG_ALL_MESSAGES
- //#define LOG_ADD_LISTENER
- //#define LOG_BROADCAST_MESSAGE
- //#define REQUIRE_LISTENER
- using UnityEngine;
- using System.Collections;
- using System.Collections.Generic;
- using System;
- public class EventNotificationCenter
- {
- public Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>();
- // Message handlers that should never be removed, regardless of calling Cleanup
- private List< string > permanentMessages = new List< string > ();
- public delegate void Callback();
- public delegate void Callback<T>(T arg1);
- public delegate void Callback<T, U>(T arg1, U arg2);
- public delegate void Callback<T, U, V>(T arg1, U arg2, V arg3);
- private static EventNotificationCenter instance;
- public static EventNotificationCenter GetInstance()
- {
- if(null == instance)
- instance = new EventNotificationCenter();
- return instance;
- }
- EventNotificationCenter()
- {
- eventTable.Clear();
- permanentMessages.Clear();
- }
- //Marks a certain message as permanent.
- public void MarkAsPermanent(string eventType)
- {
- #if LOG_ALL_MESSAGES
- Debug.Log("Messenger MarkAsPermanent \t\"" + eventType + "\"");
- #endif
-
- permanentMessages.Add( eventType );
- }
-
-
- public void Cleanup()
- {
- #if LOG_ALL_MESSAGES
- Debug.Log("MESSENGER Cleanup. Make sure that none of necessary listeners are removed.");
- #endif
-
- List< string > messagesToRemove = new List<string>();
-
- foreach (KeyValuePair<string, Delegate> pair in eventTable)
- {
- bool wasFound = false;
-
- foreach (string message in permanentMessages)
- {
- if (pair.Key == message)
- {
- wasFound = true;
- break;
- }
- }
-
- if (!wasFound)
- messagesToRemove.Add( pair.Key );
- }
-
- foreach (string message in messagesToRemove)
- {
- eventTable.Remove( message );
- }
- }
-
- public void PrintEventTable()
- {
- Debug.Log("\t\t\t=== MESSENGER PrintEventTable ===");
-
- foreach (KeyValuePair<string, Delegate> pair in eventTable)
- {
- Debug.Log("\t\t\t" + pair.Key + "\t\t" + pair.Value);
- }
-
- Debug.Log("\n");
- }
- // -- 1. 事件防御处理
- private void OnListenerAdding(string eventType, Delegate listenerBeingAdded)
- {
- #if LOG_ALL_MESSAGES || LOG_ADD_LISTENER
- Debug.Log("MESSENGER OnListenerAdding \t\"" + eventType + "\"\t{" + listenerBeingAdded.Target + " -> " + listenerBeingAdded.Method + "}");
- #endif
-
- if (!eventTable.ContainsKey(eventType))
- {
- eventTable.Add(eventType, null );
- }
-
- Delegate d = eventTable[eventType];
- if (d != null && d.GetType() != listenerBeingAdded.GetType())
- {
- throw new ListenerException(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", eventType, d.GetType().Name, listenerBeingAdded.GetType().Name));
- }
- }
-
- private void OnListenerRemoving(string eventType, Delegate listenerBeingRemoved)
- {
- #if LOG_ALL_MESSAGES
- Debug.Log("MESSENGER OnListenerRemoving \t\"" + eventType + "\"\t{" + listenerBeingRemoved.Target + " -> " + listenerBeingRemoved.Method + "}");
- #endif
-
- if (eventTable.ContainsKey(eventType))
- {
- Delegate d = eventTable[eventType];
- if (d == null)
- {
- throw new ListenerException(string.Format("Attempting to remove listener with for event type \"{0}\" but current listener is null.", eventType));
- }
- else if (d.GetType() != listenerBeingRemoved.GetType())
- {
- throw new ListenerException(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", eventType, d.GetType().Name, listenerBeingRemoved.GetType().Name));
- }
- }
- else
- {
- YmDebug.LogCR(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", eventType));
- //throw new ListenerException(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", eventType));
- }
- }
-
- private void OnListenerRemoved(string eventType)
- {
- if (eventTable[eventType] == null)
- {
- eventTable.Remove(eventType);
- }
- }
-
- private void OnBroadcasting(string eventType)
- {
- #if REQUIRE_LISTENER
- if (!eventTable.ContainsKey(eventType))
- {
- throw new BroadcastException(string.Format("Broadcasting message \"{0}\" but no listener found. Try marking the message with Messenger.MarkAsPermanent.", eventType));
- }
- #endif
- }
-
- private BroadcastException CreateBroadcastSignatureException(string eventType)
- {
- return new BroadcastException(string.Format("Broadcasting message \"{0}\" but listeners have a different signature than the broadcaster.", eventType));
- }
-
- public class BroadcastException : Exception
- {
- public BroadcastException(string msg): base(msg)
- {
- }
- }
-
- public class ListenerException : Exception
- {
- public ListenerException(string msg): base(msg)
- {
- }
- }
- // -- 2. 添加事件
- //No parameters
- public void AddListener(string eventType, Callback handler)
- {
- OnListenerAdding(eventType, handler);
- eventTable[eventType] = (Callback)eventTable[eventType] + handler;
- }
-
- //Single parameter
- public void AddListener<T>(string eventType, Callback<T> handler) {
- if (handler == null ){
- return;
- }
- OnListenerAdding(eventType, handler);
- eventTable[eventType] = (Callback<T>)eventTable[eventType] + handler;
- }
- //Two parameters
- public void AddListener<T, U>(string eventType, Callback<T, U> handler)
- {
- if (handler == null ){
- return;
- }
- OnListenerAdding(eventType, handler);
- eventTable[eventType] = (Callback<T, U>)eventTable[eventType] + handler;
- }
-
- //Three parameters
- public void AddListener<T, U, V>(string eventType, Callback<T, U, V> handler)
- {
- if (handler == null ){
- return;
- }
- OnListenerAdding(eventType, handler);
- eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] + handler;
- }
- // -- 3. 删除事件
- //No parameters
- public void RemoveListener(string eventType, Callback handler)
- {
- if (handler == null){
- return;
- }
- OnListenerRemoving(eventType, handler);
- if (eventTable.ContainsKey(eventType))
- {
- eventTable[eventType] = (Callback)eventTable[eventType] - handler;
- OnListenerRemoved(eventType);
- }
- }
-
- //Single parameter
- public void RemoveListener<T>(string eventType, Callback<T> handler)
- {
- if (handler == null){
- return;
- }
- OnListenerRemoving(eventType, handler);
- if (eventTable.ContainsKey(eventType))
- {
- eventTable[eventType] = (Callback<T>)eventTable[eventType] - handler;
- OnListenerRemoved(eventType);
- }
- }
-
- //Two parameters
- public void RemoveListener<T, U>(string eventType, Callback<T, U> handler)
- {
- if (handler == null){
- return;
- }
- OnListenerRemoving(eventType, handler);
- if (eventTable.ContainsKey(eventType))
- {
- eventTable[eventType] = (Callback<T, U>)eventTable[eventType] - handler;
- OnListenerRemoved(eventType);
- }
- }
-
- //Three parameters
- public void RemoveListener<T, U, V>(string eventType, Callback<T, U, V> handler)
- {
- if (handler == null){
- return;
- }
- OnListenerRemoving(eventType, handler);
- if (eventTable.ContainsKey(eventType))
- {
- eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] - handler;
- OnListenerRemoved(eventType);
- }
- }
- // -- 4. 广播事件
- //No parameters
- public void Broadcast(string eventType)
- {
- if (eventType == null ){
- return;
- }
- #if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
- Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
- #endif
- OnBroadcasting(eventType);
-
- Delegate d;
- if (eventTable.TryGetValue(eventType, out d))
- {
- Callback callback = d as Callback;
-
- if (callback != null)
- {
- List<Callback> removedDel = new List<Callback>();
- foreach(Delegate del in callback.GetInvocationList() ){
- //Debug.Log(" del is " + del.Target.GetType().ToString() );
- bool isCalled = false;
- if (del.Target is MonoBehaviour){
- MonoBehaviour mono = (MonoBehaviour)del.Target;
- if (mono != null){
- Callback cb = (Callback)del;
- isCalled = true;
- cb();
- }
- }else if (del.Target!=null){
- Callback cb = (Callback)del;
- isCalled = true;
- cb();
- }
- if (!isCalled){
- YmDebug.Log("the object represent is null " + eventType );
- removedDel.Add((Callback)del);
- }
- }
- if (eventTable.ContainsKey(eventType)){
- foreach (Callback rDel in removedDel)
- {
- callback = callback - rDel;
- }
- eventTable[eventType] = callback;
- }
- }
- else
- {
- YmDebug.LogCR("callback is destroyed ");
- // throw CreateBroadcastSignatureException(eventType);
- }
- }
- }
-
- //Single parameter
- public void Broadcast<T>(string eventType, T arg1)
- {
- if (eventType == null ){
- return;
- }
- #if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
- Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
- #endif
- OnBroadcasting(eventType);
-
- Delegate d;
-
- if (eventTable.TryGetValue(eventType, out d)) {
- Callback<T> callback = d as Callback<T>;
- if (callback != null)
- {
- List<Callback<T>> removedDel = new List<Callback<T>>();
- foreach(Delegate del in callback.GetInvocationList() ){
- //Debug.Log(i + " del is " + del.Target.GetType().ToString() );
- bool isCalled = false;
- if (del.Target is MonoBehaviour){
- MonoBehaviour mono = (MonoBehaviour)del.Target;
- if (mono != null){
- Callback<T> cb = (Callback<T>)del;
- cb(arg1);
- isCalled = true;
- }
- }else if (del.Target!=null){
- Callback<T> cb = (Callback<T>)del;
- cb(arg1);
- isCalled = true;
- }
- if (!isCalled){
- removedDel.Add((Callback<T>)del);
- }
- }
- if (eventTable.ContainsKey(eventType)){
- foreach (Callback<T> rDel in removedDel)
- {
- callback = callback - rDel;
- }
- eventTable[eventType] = callback;
- }
- }
- else
- {
- YmDebug.LogCR("callback is destroyed ");
- // throw CreateBroadcastSignatureException(eventType);
- }
- }
- }
-
- //Two parameters
- public void Broadcast<T, U>(string eventType, T arg1, U arg2)
- {
- if (eventType == null ){
- return;
- }
- #if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
- Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
- #endif
- OnBroadcasting(eventType);
-
- Delegate d;
- if (eventTable.TryGetValue(eventType, out d))
- {
- Callback<T, U> callback = d as Callback<T, U>;
-
- if (callback != null)
- {
- List<Callback<T, U>> removedDel = new List<Callback<T, U>>();
- foreach(Delegate del in callback.GetInvocationList() ){
- //Debug.Log(i + " del is " + del.Target.GetType().ToString() );
- bool isCalled = false;
- if (del.Target is MonoBehaviour){
- MonoBehaviour mono = (MonoBehaviour)del.Target;
- if (mono != null){
- Callback<T, U> cb = (Callback<T, U>)del;
- cb(arg1, arg2);
- isCalled = true;
- }
- }else if (del.Target!=null){
- Callback<T, U> cb = (Callback<T, U>)del;
- cb(arg1, arg2);
- isCalled = true;
- }
- if (!isCalled){
- removedDel.Add((Callback<T, U>)del);
- }
- }
- if (eventTable.ContainsKey(eventType)){
- foreach (Callback<T, U> rDel in removedDel)
- {
- callback = callback - rDel;
- }
- eventTable[eventType] = callback;
- }
- }
- else
- {
- YmDebug.LogCR("callback is destroyed ");
- // throw CreateBroadcastSignatureException(eventType);
- }
- }
- }
-
- //Three parameters
- public void Broadcast<T, U, V>(string eventType, T arg1, U arg2, V arg3)
- {
- if (eventType == null ){
- return;
- }
- #if LOG_ALL_MESSAGES || LOG_BROADCAST_MESSAGE
- Debug.Log("MESSENGER\t" + System.DateTime.Now.ToString("hh:mm:ss.fff") + "\t\t\tInvoking \t\"" + eventType + "\"");
- #endif
- OnBroadcasting(eventType);
-
- Delegate d;
- if (eventTable.TryGetValue(eventType, out d))
- {
- Callback<T, U, V> callback = d as Callback<T, U, V>;
-
- if (callback != null)
- {
- List<Callback<T, U, V>> removedDel = new List<Callback<T, U, V>>();
- foreach(Delegate del in callback.GetInvocationList() ){
- //Debug.Log(i + " del is " + del.Target.GetType().ToString() );
- bool isCalled = false;
- if (del.Target is MonoBehaviour){
- MonoBehaviour mono = (MonoBehaviour)del.Target;
- if (mono != null){
- Callback<T, U, V> cb = (Callback<T, U, V>)del;
- cb(arg1, arg2, arg3);
- isCalled = true;
- }
- }else if (del.Target!=null){
- Callback<T, U, V> cb = (Callback<T, U, V>)del;
- cb(arg1, arg2, arg3);
- isCalled = true;
- }
- if (!isCalled){
- removedDel.Add((Callback<T, U, V>)del);
- }
- }
- if (eventTable.ContainsKey(eventType)){
- foreach (Callback<T, U, V> rDel in removedDel)
- {
- callback = callback - rDel;
- }
- eventTable[eventType] = callback;
- }
- }
- else
- {
- YmDebug.LogCR("callback is destroyed ");
- // throw CreateBroadcastSignatureException(eventType);
- }
- }
- }
- // todo:
- public void DelayBroadcast(float d)
- {
- }
- }
|