Unity 之事件系统
游戏开发过程中事件是非常多的,可以通过 Messenger 事件系统来解藕,用法如下:
1 使用方法 2 3 例子:在按下拍照按钮后通知刷新好友面板 4 步骤1、添加事件字段,该字段具有唯一性 5 在MessangerEventDef脚本(可以每个功能都有一个事件字段脚本,类似于消息)中添加字段"Demo_EventType". 6 7 步骤2、广播事件:在按下拍照按钮方法中调用 8 Messenger.Broadcast(MessangerEventDef.Demo_EventType); 9 10 步骤3、在OnEnable()方法中注册事件:在FriendUI_Ctrl中的OnEnable方法中添加 11 Messenger.AddListener(MessangerEventDef.Demo_EventType, OnCall); 12 13 步骤4、在OnDisable()方法中移除事件:在FriendUI_Ctrl中的OnDisable方法中添加 14 Messenger.RemoveListener(MessangerEventDef.Demo_EventType, OnCall); 15 16 void OnCall() 17 { 18 Debug.LogError("===OnCall=="); 19 //TODO 刷新好友相关代码 20 } 21 22 注意事项 23 1、AddListener和RemoveListener必须成对出现。
代码如下:
1 // Messenger.cs v1.0 by Magnus Wolffelt, magnus.wolffelt@gmail.com 2 // 3 // Inspired by and based on Rod Hyde's Messenger: 4 // http://www.unifycommunity.com/wiki/index.php?title=CSharpMessenger 5 // 6 // This is a C# messenger (notification center). It uses delegates 7 // and generics to provide type-checked messaging between event producers and 8 // event consumers, without the need for producers or consumers to be aware of 9 // each other. The major improvement from Hyde's implementation is that 10 // there is more extensive error detection, preventing silent bugs. 11 // 12 // Usage example: 13 // Messenger<float>.AddListener("myEvent", MyEventHandler); 14 // ... 15 // Messenger<float>.Broadcast("myEvent", 1.0f); 16 17 18 using System; 19 using System.Collections.Generic; 20 21 namespace Common.Messenger 22 { 23 public enum MessengerMode : byte 24 { 25 DONT_REQUIRE_LISTENER, 26 REQUIRE_LISTENER, 27 } 28 29 30 static internal class MessengerInternal 31 { 32 static public Dictionary<string, Delegate> eventTable = new Dictionary<string, Delegate>(); 33 static public readonly MessengerMode DEFAULT_MODE = MessengerMode.DONT_REQUIRE_LISTENER; 34 35 static public void OnListenerAdding(string eventType, Delegate listenerBeingAdded) 36 { 37 if (!eventTable.ContainsKey(eventType)) 38 { 39 eventTable.Add(eventType, null); 40 } 41 42 Delegate d = eventTable[eventType]; 43 if (d != null && d.GetType() != listenerBeingAdded.GetType()) 44 { 45 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)); 46 } 47 } 48 49 static public void OnListenerRemoving(string eventType, Delegate listenerBeingRemoved) 50 { 51 if (eventTable.ContainsKey(eventType)) 52 { 53 Delegate d = eventTable[eventType]; 54 55 if (d == null) 56 { 57 throw new ListenerException(string.Format("Attempting to remove listener with for event type {0} but current listener is null.", eventType)); 58 } 59 else if (d.GetType() != listenerBeingRemoved.GetType()) 60 { 61 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)); 62 } 63 } 64 else 65 { 66 throw new ListenerException(string.Format("Attempting to remove listener for type {0} but Messenger doesn't know about this event type.", eventType)); 67 } 68 } 69 70 static public void OnListenerRemoved(string eventType) 71 { 72 if (eventTable[eventType] == null) 73 { 74 eventTable.Remove(eventType); 75 } 76 } 77 78 static public void OnBroadcasting(string eventType, MessengerMode mode) 79 { 80 if (mode == MessengerMode.REQUIRE_LISTENER && !eventTable.ContainsKey(eventType)) 81 { 82 throw new MessengerInternal.BroadcastException(string.Format("Broadcasting message {0} but no listener found.", eventType)); 83 } 84 } 85 86 static public BroadcastException CreateBroadcastSignatureException(string eventType) 87 { 88 return new BroadcastException(string.Format("Broadcasting message {0} but listeners have a different signature than the broadcaster.", eventType)); 89 } 90 91 public class BroadcastException : Exception 92 { 93 public BroadcastException(string msg) 94 : base(msg) 95 { 96 } 97 } 98 99 public class ListenerException : Exception 100 { 101 public ListenerException(string msg) 102 : base(msg) 103 { 104 } 105 } 106 } 107 108 109 // No parameters 110 static public class Messenger 111 { 112 private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; 113 114 static public void AddListener(string eventType, Callback handler) 115 { 116 MessengerInternal.OnListenerAdding(eventType, handler); 117 eventTable[eventType] = (Callback)eventTable[eventType] + handler; 118 } 119 120 static public void RemoveListener(string eventType, Callback handler) 121 { 122 MessengerInternal.OnListenerRemoving(eventType, handler); 123 eventTable[eventType] = (Callback)eventTable[eventType] - handler; 124 MessengerInternal.OnListenerRemoved(eventType); 125 } 126 127 static public void Broadcast(string eventType) 128 { 129 Broadcast(eventType, MessengerInternal.DEFAULT_MODE); 130 } 131 132 static public void Broadcast(string eventType, MessengerMode mode) 133 { 134 MessengerInternal.OnBroadcasting(eventType, mode); 135 Delegate d; 136 if (eventTable.TryGetValue(eventType, out d)) 137 { 138 Callback callback = d as Callback; 139 if (callback != null) 140 { 141 callback(); 142 } 143 else 144 { 145 throw MessengerInternal.CreateBroadcastSignatureException(eventType); 146 } 147 } 148 } 149 } 150 151 // One parameter 152 static public class Messenger<T> 153 { 154 private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; 155 156 static public void AddListener(string eventType, Callback<T> handler) 157 { 158 MessengerInternal.OnListenerAdding(eventType, handler); 159 eventTable[eventType] = (Callback<T>)eventTable[eventType] + handler; 160 } 161 162 static public void RemoveListener(string eventType, Callback<T> handler) 163 { 164 MessengerInternal.OnListenerRemoving(eventType, handler); 165 eventTable[eventType] = (Callback<T>)eventTable[eventType] - handler; 166 MessengerInternal.OnListenerRemoved(eventType); 167 } 168 169 static public void Broadcast(string eventType, T arg1) 170 { 171 Broadcast(eventType, arg1, MessengerInternal.DEFAULT_MODE); 172 } 173 174 static public void Broadcast(string eventType, T arg1, MessengerMode mode) 175 { 176 MessengerInternal.OnBroadcasting(eventType, mode); 177 Delegate d; 178 if (eventTable.TryGetValue(eventType, out d)) 179 { 180 Callback<T> callback = d as Callback<T>; 181 if (callback != null) 182 { 183 callback(arg1); 184 } 185 else 186 { 187 throw MessengerInternal.CreateBroadcastSignatureException(eventType); 188 } 189 } 190 } 191 } 192 193 194 // Two parameters 195 static public class Messenger<T, U> 196 { 197 private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; 198 199 static public void AddListener(string eventType, Callback<T, U> handler) 200 { 201 MessengerInternal.OnListenerAdding(eventType, handler); 202 eventTable[eventType] = (Callback<T, U>)eventTable[eventType] + handler; 203 } 204 205 static public void RemoveListener(string eventType, Callback<T, U> handler) 206 { 207 MessengerInternal.OnListenerRemoving(eventType, handler); 208 eventTable[eventType] = (Callback<T, U>)eventTable[eventType] - handler; 209 MessengerInternal.OnListenerRemoved(eventType); 210 } 211 212 static public void Broadcast(string eventType, T arg1, U arg2) 213 { 214 Broadcast(eventType, arg1, arg2, MessengerInternal.DEFAULT_MODE); 215 } 216 217 static public void Broadcast(string eventType, T arg1, U arg2, MessengerMode mode) 218 { 219 MessengerInternal.OnBroadcasting(eventType, mode); 220 Delegate d; 221 if (eventTable.TryGetValue(eventType, out d)) 222 { 223 Callback<T, U> callback = d as Callback<T, U>; 224 if (callback != null) 225 { 226 callback(arg1, arg2); 227 } 228 else 229 { 230 throw MessengerInternal.CreateBroadcastSignatureException(eventType); 231 } 232 } 233 } 234 } 235 236 237 // Three parameters 238 static public class Messenger<T, U, V> 239 { 240 private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; 241 242 static public void AddListener(string eventType, Callback<T, U, V> handler) 243 { 244 MessengerInternal.OnListenerAdding(eventType, handler); 245 eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] + handler; 246 } 247 248 static public void RemoveListener(string eventType, Callback<T, U, V> handler) 249 { 250 MessengerInternal.OnListenerRemoving(eventType, handler); 251 eventTable[eventType] = (Callback<T, U, V>)eventTable[eventType] - handler; 252 MessengerInternal.OnListenerRemoved(eventType); 253 } 254 255 static public void Broadcast(string eventType, T arg1, U arg2, V arg3) 256 { 257 Broadcast(eventType, arg1, arg2, arg3, MessengerInternal.DEFAULT_MODE); 258 } 259 260 static public void Broadcast(string eventType, T arg1, U arg2, V arg3, MessengerMode mode) 261 { 262 MessengerInternal.OnBroadcasting(eventType, mode); 263 Delegate d; 264 if (eventTable.TryGetValue(eventType, out d)) 265 { 266 Callback<T, U, V> callback = d as Callback<T, U, V>; 267 if (callback != null) 268 { 269 callback(arg1, arg2, arg3); 270 } 271 else 272 { 273 throw MessengerInternal.CreateBroadcastSignatureException(eventType); 274 } 275 } 276 } 277 } 278 279 // Four parameters 280 static public class Messenger<T, U, V, W> 281 { 282 private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; 283 284 static public void AddListener(string eventType, Callback<T, U, V, W> handler) 285 { 286 MessengerInternal.OnListenerAdding(eventType, handler); 287 eventTable[eventType] = (Callback<T, U, V, W>)eventTable[eventType] + handler; 288 } 289 290 static public void RemoveListener(string eventType, Callback<T, U, V, W> handler) 291 { 292 MessengerInternal.OnListenerRemoving(eventType, handler); 293 eventTable[eventType] = (Callback<T, U, V, W>)eventTable[eventType] - handler; 294 MessengerInternal.OnListenerRemoved(eventType); 295 } 296 297 static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4) 298 { 299 Broadcast(eventType, arg1, arg2, arg3, arg4, MessengerInternal.DEFAULT_MODE); 300 } 301 302 static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, MessengerMode mode) 303 { 304 MessengerInternal.OnBroadcasting(eventType, mode); 305 Delegate d; 306 if (eventTable.TryGetValue(eventType, out d)) 307 { 308 Callback<T, U, V, W> callback = d as Callback<T, U, V, W>; 309 if (callback != null) 310 { 311 callback(arg1, arg2, arg3, arg4); 312 } 313 else 314 { 315 throw MessengerInternal.CreateBroadcastSignatureException(eventType); 316 } 317 } 318 } 319 } 320 321 // Five parameters 322 static public class Messenger<T, U, V, W, X> 323 { 324 private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; 325 326 static public void AddListener(string eventType, Callback<T, U, V, W, X> handler) 327 { 328 MessengerInternal.OnListenerAdding(eventType, handler); 329 eventTable[eventType] = (Callback<T, U, V, W, X>)eventTable[eventType] + handler; 330 } 331 332 static public void RemoveListener(string eventType, Callback<T, U, V, W, X> handler) 333 { 334 MessengerInternal.OnListenerRemoving(eventType, handler); 335 eventTable[eventType] = (Callback<T, U, V, W, X>)eventTable[eventType] - handler; 336 MessengerInternal.OnListenerRemoved(eventType); 337 } 338 339 static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5) 340 { 341 Broadcast(eventType, arg1, arg2, arg3, arg4, arg5, MessengerInternal.DEFAULT_MODE); 342 } 343 344 static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5, MessengerMode mode) 345 { 346 MessengerInternal.OnBroadcasting(eventType, mode); 347 Delegate d; 348 if (eventTable.TryGetValue(eventType, out d)) 349 { 350 Callback<T, U, V, W, X> callback = d as Callback<T, U, V, W, X>; 351 if (callback != null) 352 { 353 callback(arg1, arg2, arg3, arg4, arg5); 354 } 355 else 356 { 357 throw MessengerInternal.CreateBroadcastSignatureException(eventType); 358 } 359 } 360 } 361 } 362 363 // Six parameters 364 static public class Messenger<T, U, V, W, X, Y> 365 { 366 private static Dictionary<string, Delegate> eventTable = MessengerInternal.eventTable; 367 368 static public void AddListener(string eventType, Callback<T, U, V, W, X, Y> handler) 369 { 370 MessengerInternal.OnListenerAdding(eventType, handler); 371 eventTable[eventType] = (Callback<T, U, V, W, X, Y>)eventTable[eventType] + handler; 372 } 373 374 static public void RemoveListener(string eventType, Callback<T, U, V, W, X, Y> handler) 375 { 376 MessengerInternal.OnListenerRemoving(eventType, handler); 377 eventTable[eventType] = (Callback<T, U, V, W, X, Y>)eventTable[eventType] - handler; 378 MessengerInternal.OnListenerRemoved(eventType); 379 } 380 381 static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6) 382 { 383 Broadcast(eventType, arg1, arg2, arg3, arg4, arg5, arg6, MessengerInternal.DEFAULT_MODE); 384 } 385 386 static public void Broadcast(string eventType, T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6, MessengerMode mode) 387 { 388 MessengerInternal.OnBroadcasting(eventType, mode); 389 Delegate d; 390 if (eventTable.TryGetValue(eventType, out d)) 391 { 392 Callback<T, U, V, W, X, Y> callback = d as Callback<T, U, V, W, X, Y>; 393 if (callback != null) 394 { 395 callback(arg1, arg2, arg3, arg4, arg5, arg6); 396 } 397 else 398 { 399 throw MessengerInternal.CreateBroadcastSignatureException(eventType); 400 } 401 } 402 } 403 } 404 }
1 // MessengerUnitTest.cs v1.0 by Magnus Wolffelt, magnus.wolffelt@gmail.com 2 // 3 // Delegates used in Messenger.cs. 4 namespace Common.Messenger 5 { 6 public delegate void Callback(); 7 public delegate void Callback<T>(T arg1); 8 public delegate void Callback<T, U>(T arg1, U arg2); 9 public delegate void Callback<T, U, V>(T arg1, U arg2, V arg3); 10 public delegate void Callback<T, U, V, W>(T arg1, U arg2, V arg3, W arg4); 11 public delegate void Callback<T, U, V, W, X>(T arg1, U arg2, V arg3, W arg4, X arg5); 12 public delegate void Callback<T, U, V, W, X, Y>(T arg1, U arg2, V arg3, W arg4, X arg5, Y arg6); 13 14 public delegate T CallbackReturn<T>(); 15 public delegate T CallbackReturn<T, U>(U arg1); 16 }
1 namespace Common.Messenger 2 { 3 /// <summary> 4 /// This class is used to define all eventId. 5 /// Event string must be different. 6 /// </summary> 7 public class MessengerEventDef 8 { 9 10 } 11 }