This is a C# CallbackEventHandler I wrote to allow registering event categories and events for dispatching within various submodules. Where in another submodule you can register to the particular event category and event for receiving and handling those events in whichever way your application needs. This one uses Unity for log output, but it can be tailored for general purposes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
using System; using System.Collections.Generic; using UnityEngine; namespace Animal { public class CallbackEventHandler { // base class to inherit from for sending and handling event information public class EventInfo { } // register your own EventCategory in your own submodule using the CreateEventCategory function public class EventCategory { public int EventId { get; set; } } private static CallbackEventHandler s_callbackEventHandler = null; public static CallbackEventHandler Get() { if (s_callbackEventHandler == null) { s_callbackEventHandler = new CallbackEventHandler(); } return s_callbackEventHandler; } private static Dictionary< EventCategory, Dictionary< Enum, List<Action<EventInfo>> > > s_eventCallbacks = new Dictionary< EventCategory, Dictionary< Enum, List<Action<EventInfo>> > >(); private static int s_eventIdCounter = 0; // ---------------------------------------------------------------------- public EventCategory CreateEventCategory() { EventCategory eventCategory = new EventCategory { EventId = s_eventIdCounter++ }; s_eventCallbacks.Add(eventCategory, new Dictionary<Enum, List<Action<EventInfo>>>()); return eventCategory; } // call back registration and execution // note: make sure to keep in mind if only the owner needs to Register the event public void RegisterEvent( EventCategory eventCategory, Enum eventMask, Action<EventInfo> callback = null ) { if (s_eventCallbacks.ContainsKey(eventCategory) == false) { Debug.LogWarning(string.Format( "{0} => invalid {1} passed in: {2}", nameof(RegisterEvent), typeof(EventCategory).ToString(), eventCategory) ); return; } var categoryEventCallbacks = s_eventCallbacks[eventCategory]; foreach (Enum e in Enum.GetValues(eventMask.GetType())) { if (eventMask.HasFlag(e) == false) { continue; } Enum eventType = e; if (categoryEventCallbacks.ContainsKey(eventType) == false) { List<Action<EventInfo>> callbackEvents = new List<Action<EventInfo>>(); categoryEventCallbacks.Add(eventType, callbackEvents); categoryEventCallbacks[eventType] = callbackEvents; } // such as in the case when we are initializing the event if (callback == null) { continue; } categoryEventCallbacks[eventType].Add(callback); } } // note: make sure to keep in mind if only the owner needs to Unregister the event public void UnregisterEvent( EventCategory eventCategory, Enum eventMask, Action<EventInfo> callback = null ) { if (s_eventCallbacks.ContainsKey(eventCategory) == false) { Debug.LogWarning(string.Format( "{0} => invalid {1} passed in: {2}", nameof(UnregisterEvent), typeof(EventCategory).ToString(), eventCategory) ); return; } var categoryEventCallbacks = s_eventCallbacks[eventCategory]; foreach (Enum e in Enum.GetValues(eventMask.GetType())) { if (eventMask.HasFlag(e) == false) { continue; } Enum eventType = e; // no events were added if (categoryEventCallbacks.ContainsKey(eventType) == false) { continue; } // will remove all callbacks for the event if none are specified if (callback == null) { categoryEventCallbacks[eventType].Clear(); continue; } // will remove a specific callback for the event if it contains this callback categoryEventCallbacks[eventType].Remove(callback); } } // unregisters the entire event category public void UnregisterEvents(EventCategory eventCategory = null) { // clear everything if this is null if (eventCategory == null) { foreach (var category in s_eventCallbacks) { foreach (var events in category.Value) { events.Value.Clear(); } category.Value.Clear(); } return; } if (s_eventCallbacks.ContainsKey(eventCategory) == false) { Debug.LogWarning(string.Format( "{0} => invalid {1} passed in: {2}", nameof(UnregisterEvents), typeof(EventCategory).ToString(), eventCategory) ); return; } var categoryEventCallbacks = s_eventCallbacks[eventCategory]; foreach (var events in categoryEventCallbacks) { events.Value.Clear(); } categoryEventCallbacks.Clear(); } public void DispatchEvent( EventCategory eventCategory, Enum eventMask, EventInfo eventInfo ) { if (s_eventCallbacks.ContainsKey(eventCategory) == false) { Debug.LogWarning(string.Format( "{0} => invalid {1} passed in: {2}", nameof(DispatchEvent), typeof(EventCategory).ToString(), eventCategory) ); return; } var categoryEventCallbacks = s_eventCallbacks[eventCategory]; foreach (Enum e in Enum.GetValues(eventMask.GetType())) { if (eventMask.HasFlag(e) == false) { continue; } Enum eventType = e; if (categoryEventCallbacks.ContainsKey(eventType) == false) { continue; } foreach (var callback in categoryEventCallbacks[eventType]) { callback(eventInfo); } } } // ---------------------------------------------------------------------- } } |