GenericNotificationCenter.cs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. using UnityEngine;
  2. using System.Collections;
  3. using System;
  4. //Based off http://forum.unity3d.com/threads/37896-Programming-architectures?p=847646&viewfull=1#post847646
  5. //Changed it to static methods (less typing and less indirection)
  6. //Added helper methods for posting notifications
  7. public class GenericNotificationCenter<NT, N>
  8. where NT : struct, IConvertible, IComparable, IFormattable
  9. where N : GenericNotification<NT>, new()
  10. {
  11. public delegate void OnNotificationDelegate(N note);
  12. private static OnNotificationDelegate[] _listeners = new OnNotificationDelegate[System.Enum.GetValues(typeof(NT)).Length];
  13. public static void AddListener(OnNotificationDelegate newListenerDelegate, NT type)
  14. {
  15. int typeInt = type.ToInt32(null);
  16. //Note that these checks will only be done when DEBUG is defined
  17. AVDebug.Assert(!IsAlreadyRegistered(newListenerDelegate, typeInt), "You have already registered this delegate for "+type);
  18. _listeners[typeInt] += newListenerDelegate;
  19. }
  20. static bool IsAlreadyRegistered(OnNotificationDelegate newListenerDelegate, int typeInt)
  21. {
  22. if (_listeners[typeInt] == null)
  23. {
  24. return false;
  25. }
  26. Delegate[] invocationList = _listeners[typeInt].GetInvocationList();
  27. foreach (Delegate d in invocationList)
  28. {
  29. if (d == newListenerDelegate)
  30. {
  31. return true;
  32. }
  33. }
  34. return false;
  35. }
  36. public static void RemoveListener(OnNotificationDelegate listenerDelegate, NT type)
  37. {
  38. int typeInt = type.ToInt32(null);
  39. _listeners[typeInt] -= listenerDelegate;
  40. }
  41. public static void Post(NT type)
  42. {
  43. //AVDebug.Log("Firing "+type.ToString());
  44. N n = new N();
  45. n.type = type;
  46. Post(n);
  47. }
  48. public static void Post(NT type, object data)
  49. {
  50. N n = new N();
  51. n.type = type;
  52. n.data = data;
  53. Post(n);
  54. }
  55. public static void Post(N note)
  56. {
  57. int typeInt = note.type.ToInt32(null);
  58. if (_listeners[typeInt] != null)
  59. {
  60. _listeners[typeInt](note);
  61. }
  62. }
  63. #region For Testing/Debugging only
  64. /// <summary>
  65. /// Used for debugging to outputs the number of listeners to have an idea of how many listeners are currently registered.
  66. /// </summary>
  67. public static void OutputNumOfListeners()
  68. {
  69. for (int i = 0; i < _listeners.Length; i++)
  70. {
  71. NT notificationType = (NT)(object)i;
  72. AVDebug.Log(string.Format("Deligates for notification {0}: {1}", notificationType, GetListenerCount(notificationType)));
  73. }
  74. AVDebug.Log(string.Format("NotificationCenter total delegates count: {0}", GetTotalListenersCount()));
  75. }
  76. public static int GetListenerCount(NT notificationType)
  77. {
  78. var typeListeners = _listeners[notificationType.ToInt32(null)];
  79. if (typeListeners != null)
  80. {
  81. return typeListeners.GetInvocationList().Length;
  82. } else
  83. {
  84. return 0;
  85. }
  86. }
  87. public static int GetTotalListenersCount()
  88. {
  89. int total = 0;
  90. for (int i = 0; i < _listeners.Length; i++)
  91. {
  92. total += GetListenerCount((NT)(object)i);
  93. }
  94. return total;
  95. }
  96. public static void Reset_USE_ONLY_FOR_UNIT_TESTS()
  97. {
  98. _listeners = new OnNotificationDelegate[System.Enum.GetValues(typeof(NT)).Length];
  99. }
  100. #endregion
  101. }