com.wallstop-studios.dxmessaging 2.0.0-rc06 → 2.0.0-rc07

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -17,28 +17,60 @@
17
17
  public int RegisteredUntargeted => _sinks.Select(kvp => kvp.Value.Count).Sum();
18
18
 
19
19
  private static readonly Type MessageBusType = typeof(MessageBus);
20
+
20
21
  // For use with re-broadcasting to generic methods
21
22
  private static readonly object[] ReflectionMethodArgumentsCache = new object[2];
22
23
 
23
- private const BindingFlags ReflectionHelperBindingFlags = BindingFlags.Static | BindingFlags.NonPublic;
24
+ private const BindingFlags ReflectionHelperBindingFlags =
25
+ BindingFlags.Static | BindingFlags.NonPublic;
24
26
 
25
- private delegate void FastUntargetedBroadcast<T>(ref T message) where T : IUntargetedMessage;
26
- private delegate void FastTargetedBroadcast<T>(ref InstanceId target, ref T message) where T : ITargetedMessage;
27
- private delegate void FastSourcedBroadcast<T>(ref InstanceId target, ref T message) where T : IBroadcastMessage;
27
+ private delegate void FastUntargetedBroadcast<T>(ref T message)
28
+ where T : IUntargetedMessage;
29
+ private delegate void FastTargetedBroadcast<T>(ref InstanceId target, ref T message)
30
+ where T : ITargetedMessage;
31
+ private delegate void FastSourcedBroadcast<T>(ref InstanceId target, ref T message)
32
+ where T : IBroadcastMessage;
28
33
 
29
34
  public RegistrationLog Log => _log;
30
35
 
31
- private readonly Dictionary<Type, Dictionary<MessageHandler, int>> _sinks = new();
32
- private readonly Dictionary<Type, Dictionary<InstanceId, Dictionary<MessageHandler, int>>> _targetedSinks = new();
33
- private readonly Dictionary<Type, Dictionary<InstanceId, Dictionary<MessageHandler, int>>> _broadcastSinks = new();
34
- private readonly Dictionary<Type, Dictionary<MessageHandler, int>> _postProcessingSinks = new();
35
- private readonly Dictionary<Type, Dictionary<InstanceId, Dictionary<MessageHandler, int>>> _postProcessingTargetedSinks = new();
36
- private readonly Dictionary<Type, Dictionary<InstanceId, Dictionary<MessageHandler, int>>> _postProcessingBroadcastSinks = new();
37
- private readonly Dictionary<Type, Dictionary<MessageHandler, int>> _postProcessingTargetedWithoutTargetingSinks = new();
38
- private readonly Dictionary<Type, Dictionary<MessageHandler, int>> _postProcessingBroadcastWithoutSourceSinks = new();
36
+ private readonly Dictionary<
37
+ Type,
38
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
39
+ > _sinks = new();
40
+ private readonly Dictionary<
41
+ Type,
42
+ Dictionary<InstanceId, SortedDictionary<int, Dictionary<MessageHandler, int>>>
43
+ > _targetedSinks = new();
44
+
45
+ private readonly Dictionary<
46
+ Type,
47
+ Dictionary<InstanceId, SortedDictionary<int, Dictionary<MessageHandler, int>>>
48
+ > _broadcastSinks = new();
49
+ private readonly Dictionary<
50
+ Type,
51
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
52
+ > _postProcessingSinks = new();
53
+ private readonly Dictionary<
54
+ Type,
55
+ Dictionary<InstanceId, SortedDictionary<int, Dictionary<MessageHandler, int>>>
56
+ > _postProcessingTargetedSinks = new();
57
+ private readonly Dictionary<
58
+ Type,
59
+ Dictionary<InstanceId, SortedDictionary<int, Dictionary<MessageHandler, int>>>
60
+ > _postProcessingBroadcastSinks = new();
61
+ private readonly Dictionary<
62
+ Type,
63
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
64
+ > _postProcessingTargetedWithoutTargetingSinks = new();
65
+ private readonly Dictionary<
66
+ Type,
67
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
68
+ > _postProcessingBroadcastWithoutSourceSinks = new();
39
69
  private readonly Dictionary<MessageHandler, int> _globalSinks = new();
40
- private readonly Dictionary<Type, SortedDictionary<int, List<object>>> _interceptsByType = new();
41
- private readonly Dictionary<object, Dictionary<int, int>> _uniqueInterceptorsAndPriorities = new();
70
+ private readonly Dictionary<Type, SortedDictionary<int, List<object>>> _interceptsByType =
71
+ new();
72
+ private readonly Dictionary<object, Dictionary<int, int>> _uniqueInterceptorsAndPriorities =
73
+ new();
42
74
 
43
75
  private readonly Dictionary<Type, object> _broadcastMethodsByType = new();
44
76
 
@@ -46,53 +78,115 @@
46
78
 
47
79
  // These are used so we aren't allocating as much every time we send messages
48
80
  private readonly Stack<List<MessageHandler>> _messageHandlers = new();
81
+ private readonly Stack<
82
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>>
83
+ > _sortedHandlers = new();
49
84
  private readonly Stack<List<object>> _interceptors = new();
50
85
  private readonly Stack<List<int>> _interceptorKeys = new();
51
86
 
52
- public Action RegisterUntargeted<T>(MessageHandler messageHandler) where T : IUntargetedMessage
87
+ public Action RegisterUntargeted<T>(MessageHandler messageHandler, int priority = 0)
88
+ where T : IUntargetedMessage
53
89
  {
54
- return InternalRegisterUntargeted<T>(messageHandler, _sinks, RegistrationMethod.Untargeted);
90
+ return InternalRegisterUntargeted<T>(
91
+ messageHandler,
92
+ _sinks,
93
+ RegistrationMethod.Untargeted,
94
+ priority
95
+ );
55
96
  }
56
97
 
57
- public Action RegisterTargeted<T>(InstanceId target, MessageHandler messageHandler) where T : ITargetedMessage
98
+ public Action RegisterTargeted<T>(
99
+ InstanceId target,
100
+ MessageHandler messageHandler,
101
+ int priority = 0
102
+ )
103
+ where T : ITargetedMessage
58
104
  {
59
- return InternalRegisterWithContext<T>(target, messageHandler, _targetedSinks, RegistrationMethod.Targeted);
105
+ return InternalRegisterWithContext<T>(
106
+ target,
107
+ messageHandler,
108
+ _targetedSinks,
109
+ RegistrationMethod.Targeted,
110
+ priority
111
+ );
60
112
  }
61
113
 
62
- public Action RegisterSourcedBroadcast<T>(InstanceId source, MessageHandler messageHandler) where T : IBroadcastMessage
114
+ public Action RegisterSourcedBroadcast<T>(
115
+ InstanceId source,
116
+ MessageHandler messageHandler,
117
+ int priority = 0
118
+ )
119
+ where T : IBroadcastMessage
63
120
  {
64
- return InternalRegisterWithContext<T>(source, messageHandler, _broadcastSinks, RegistrationMethod.Broadcast);
121
+ return InternalRegisterWithContext<T>(
122
+ source,
123
+ messageHandler,
124
+ _broadcastSinks,
125
+ RegistrationMethod.Broadcast,
126
+ priority
127
+ );
65
128
  }
66
129
 
67
- public Action RegisterSourcedBroadcastWithoutSource<T>(MessageHandler messageHandler) where T : IBroadcastMessage
130
+ public Action RegisterSourcedBroadcastWithoutSource<T>(
131
+ MessageHandler messageHandler,
132
+ int priority = 0
133
+ )
134
+ where T : IBroadcastMessage
68
135
  {
69
- return InternalRegisterUntargeted<T>(messageHandler, _sinks, RegistrationMethod.BroadcastWithoutSource);
136
+ return InternalRegisterUntargeted<T>(
137
+ messageHandler,
138
+ _sinks,
139
+ RegistrationMethod.BroadcastWithoutSource,
140
+ priority
141
+ );
70
142
  }
71
143
 
72
- public Action RegisterTargetedWithoutTargeting<T>(MessageHandler messageHandler) where T : ITargetedMessage
144
+ public Action RegisterTargetedWithoutTargeting<T>(
145
+ MessageHandler messageHandler,
146
+ int priority = 0
147
+ )
148
+ where T : ITargetedMessage
73
149
  {
74
- return InternalRegisterUntargeted<T>(messageHandler, _sinks, RegistrationMethod.TargetedWithoutTargeting);
150
+ return InternalRegisterUntargeted<T>(
151
+ messageHandler,
152
+ _sinks,
153
+ RegistrationMethod.TargetedWithoutTargeting,
154
+ priority
155
+ );
75
156
  }
76
157
 
77
158
  public Action RegisterGlobalAcceptAll(MessageHandler messageHandler)
78
159
  {
79
- if (!_globalSinks.TryGetValue(messageHandler, out int count))
80
- {
81
- count = 0;
82
- }
160
+ int count = _globalSinks.GetValueOrDefault(messageHandler, 0);
83
161
 
84
162
  Type type = typeof(IMessage);
85
163
  _globalSinks[messageHandler] = count + 1;
86
- _log.Log(new MessagingRegistration(messageHandler.owner, type, RegistrationType.Register, RegistrationMethod.GlobalAcceptAll));
164
+ _log.Log(
165
+ new MessagingRegistration(
166
+ messageHandler.owner,
167
+ type,
168
+ RegistrationType.Register,
169
+ RegistrationMethod.GlobalAcceptAll
170
+ )
171
+ );
87
172
 
88
173
  return () =>
89
174
  {
90
- _log.Log(new MessagingRegistration(messageHandler.owner, type, RegistrationType.Deregister, RegistrationMethod.GlobalAcceptAll));
175
+ _log.Log(
176
+ new MessagingRegistration(
177
+ messageHandler.owner,
178
+ type,
179
+ RegistrationType.Deregister,
180
+ RegistrationMethod.GlobalAcceptAll
181
+ )
182
+ );
91
183
  if (!_globalSinks.TryGetValue(messageHandler, out count))
92
184
  {
93
- MessagingDebug.Log(LogLevel.Error,
185
+ MessagingDebug.Log(
186
+ LogLevel.Error,
94
187
  "Received over-deregistration of GlobalAcceptAll for MessageHandler {0}. Check to make sure you're not calling (de)registration multiple times.",
95
- messageHandler);
188
+ messageHandler
189
+ );
96
190
  return;
97
191
  }
98
192
 
@@ -107,50 +201,117 @@
107
201
  };
108
202
  }
109
203
 
110
- public Action RegisterUntargetedInterceptor<T>(UntargetedInterceptor<T> interceptor, int priority = 0) where T : IUntargetedMessage
204
+ public Action RegisterUntargetedInterceptor<T>(
205
+ UntargetedInterceptor<T> interceptor,
206
+ int priority = 0
207
+ )
208
+ where T : IUntargetedMessage
111
209
  {
112
210
  return RegisterInterceptor<T>(interceptor, priority);
113
211
  }
114
212
 
115
- public Action RegisterTargetedInterceptor<T>(TargetedInterceptor<T> interceptor, int priority = 0) where T : ITargetedMessage
213
+ public Action RegisterTargetedInterceptor<T>(
214
+ TargetedInterceptor<T> interceptor,
215
+ int priority = 0
216
+ )
217
+ where T : ITargetedMessage
116
218
  {
117
219
  return RegisterInterceptor<T>(interceptor, priority);
118
220
  }
119
221
 
120
- public Action RegisterBroadcastInterceptor<T>(BroadcastInterceptor<T> interceptor, int priority = 0) where T : IBroadcastMessage
222
+ public Action RegisterBroadcastInterceptor<T>(
223
+ BroadcastInterceptor<T> interceptor,
224
+ int priority = 0
225
+ )
226
+ where T : IBroadcastMessage
121
227
  {
122
228
  return RegisterInterceptor<T>(interceptor, priority);
123
229
  }
124
-
125
- public Action RegisterUntargetedPostProcessor<T>(MessageHandler messageHandler) where T : IUntargetedMessage
230
+
231
+ public Action RegisterUntargetedPostProcessor<T>(
232
+ MessageHandler messageHandler,
233
+ int priority = 0
234
+ )
235
+ where T : IUntargetedMessage
126
236
  {
127
- return InternalRegisterUntargeted<T>(messageHandler, _postProcessingSinks, RegistrationMethod.UntargetedPostProcessor);
237
+ return InternalRegisterUntargeted<T>(
238
+ messageHandler,
239
+ _postProcessingSinks,
240
+ RegistrationMethod.UntargetedPostProcessor,
241
+ priority
242
+ );
128
243
  }
129
244
 
130
- public Action RegisterTargetedPostProcessor<T>(InstanceId target, MessageHandler messageHandler) where T : ITargetedMessage
245
+ public Action RegisterTargetedPostProcessor<T>(
246
+ InstanceId target,
247
+ MessageHandler messageHandler,
248
+ int priority = 0
249
+ )
250
+ where T : ITargetedMessage
131
251
  {
132
- return InternalRegisterWithContext<T>(target, messageHandler, _postProcessingTargetedSinks, RegistrationMethod.TargetedPostProcessor);
252
+ return InternalRegisterWithContext<T>(
253
+ target,
254
+ messageHandler,
255
+ _postProcessingTargetedSinks,
256
+ RegistrationMethod.TargetedPostProcessor,
257
+ priority
258
+ );
133
259
  }
134
260
 
135
- public Action RegisterTargetedWithoutTargetingPostProcessor<T>(MessageHandler messageHandler) where T : ITargetedMessage
261
+ public Action RegisterTargetedWithoutTargetingPostProcessor<T>(
262
+ MessageHandler messageHandler,
263
+ int priority = 0
264
+ )
265
+ where T : ITargetedMessage
136
266
  {
137
- return InternalRegisterUntargeted<T>(messageHandler, _postProcessingTargetedWithoutTargetingSinks, RegistrationMethod.TargetedWithoutTargetingPostProcessor);
267
+ return InternalRegisterUntargeted<T>(
268
+ messageHandler,
269
+ _postProcessingTargetedWithoutTargetingSinks,
270
+ RegistrationMethod.TargetedWithoutTargetingPostProcessor,
271
+ priority
272
+ );
138
273
  }
139
274
 
140
- public Action RegisterBroadcastPostProcessor<T>(InstanceId source, MessageHandler messageHandler) where T : IBroadcastMessage
275
+ public Action RegisterBroadcastPostProcessor<T>(
276
+ InstanceId source,
277
+ MessageHandler messageHandler,
278
+ int priority = 0
279
+ )
280
+ where T : IBroadcastMessage
141
281
  {
142
- return InternalRegisterWithContext<T>(source, messageHandler, _postProcessingBroadcastSinks, RegistrationMethod.BroadcastPostProcessor);
282
+ return InternalRegisterWithContext<T>(
283
+ source,
284
+ messageHandler,
285
+ _postProcessingBroadcastSinks,
286
+ RegistrationMethod.BroadcastPostProcessor,
287
+ priority
288
+ );
143
289
  }
144
290
 
145
- public Action RegisterBroadcastWithoutSourcePostProcessor<T>(MessageHandler messageHandler) where T : IBroadcastMessage
291
+ public Action RegisterBroadcastWithoutSourcePostProcessor<T>(
292
+ MessageHandler messageHandler,
293
+ int priority = 0
294
+ )
295
+ where T : IBroadcastMessage
146
296
  {
147
- return InternalRegisterUntargeted<T>(messageHandler, _postProcessingBroadcastWithoutSourceSinks, RegistrationMethod.BroadcastWithoutSourcePostProcessor);
297
+ return InternalRegisterUntargeted<T>(
298
+ messageHandler,
299
+ _postProcessingBroadcastWithoutSourceSinks,
300
+ RegistrationMethod.BroadcastWithoutSourcePostProcessor,
301
+ priority
302
+ );
148
303
  }
149
304
 
150
- private Action RegisterInterceptor<T>(object interceptor, int priority) where T : IMessage
305
+ private Action RegisterInterceptor<T>(object interceptor, int priority)
306
+ where T : IMessage
151
307
  {
152
308
  Type type = typeof(T);
153
- if (!_interceptsByType.TryGetValue(type, out SortedDictionary<int, List<object>> prioritizedInterceptors))
309
+ if (
310
+ !_interceptsByType.TryGetValue(
311
+ type,
312
+ out SortedDictionary<int, List<object>> prioritizedInterceptors
313
+ )
314
+ )
154
315
  {
155
316
  prioritizedInterceptors = new SortedDictionary<int, List<object>>();
156
317
  _interceptsByType[type] = prioritizedInterceptors;
@@ -162,7 +323,12 @@
162
323
  prioritizedInterceptors[priority] = interceptors;
163
324
  }
164
325
 
165
- if (!_uniqueInterceptorsAndPriorities.TryGetValue(interceptor, out Dictionary<int, int> priorityCount))
326
+ if (
327
+ !_uniqueInterceptorsAndPriorities.TryGetValue(
328
+ interceptor,
329
+ out Dictionary<int, int> priorityCount
330
+ )
331
+ )
166
332
  {
167
333
  priorityCount = new Dictionary<int, int>();
168
334
  _uniqueInterceptorsAndPriorities[interceptor] = priorityCount;
@@ -176,11 +342,25 @@
176
342
 
177
343
  priorityCount[priority] = count + 1;
178
344
 
179
- _log.Log(new MessagingRegistration(InstanceId.EmptyId, type, RegistrationType.Register, RegistrationMethod.Interceptor));
345
+ _log.Log(
346
+ new MessagingRegistration(
347
+ InstanceId.EmptyId,
348
+ type,
349
+ RegistrationType.Register,
350
+ RegistrationMethod.Interceptor
351
+ )
352
+ );
180
353
 
181
354
  return () =>
182
355
  {
183
- _log.Log(new MessagingRegistration(InstanceId.EmptyId, type, RegistrationType.Deregister, RegistrationMethod.Interceptor));
356
+ _log.Log(
357
+ new MessagingRegistration(
358
+ InstanceId.EmptyId,
359
+ type,
360
+ RegistrationType.Deregister,
361
+ RegistrationMethod.Interceptor
362
+ )
363
+ );
184
364
  bool removed = false;
185
365
  if (_uniqueInterceptorsAndPriorities.TryGetValue(interceptor, out priorityCount))
186
366
  {
@@ -195,8 +375,8 @@
195
375
  removed = true;
196
376
  _ = priorityCount.Remove(priority);
197
377
  }
198
- }
199
-
378
+ }
379
+
200
380
  if (priorityCount.Count <= 0)
201
381
  {
202
382
  _uniqueInterceptorsAndPriorities.Remove(interceptor);
@@ -204,9 +384,11 @@
204
384
  }
205
385
  else
206
386
  {
207
- MessagingDebug.Log(LogLevel.Error,
387
+ MessagingDebug.Log(
388
+ LogLevel.Error,
208
389
  "Received over-deregistration of Interceptor {0}. Check to make sure you're not calling (de)registration multiple times.",
209
- interceptor);
390
+ interceptor
391
+ );
210
392
  }
211
393
 
212
394
  bool complete = false;
@@ -222,23 +404,32 @@
222
404
 
223
405
  if (!complete)
224
406
  {
225
- MessagingDebug.Log(LogLevel.Error,
407
+ MessagingDebug.Log(
408
+ LogLevel.Error,
226
409
  "Received over-deregistration of Interceptor {0}. Check to make sure you're not calling (de)registration multiple times.",
227
- interceptor);
410
+ interceptor
411
+ );
228
412
  }
229
413
  }
230
414
  };
231
415
  }
232
-
416
+
233
417
  public void UntypedUntargetedBroadcast(IUntargetedMessage typedMessage)
234
418
  {
235
419
  Type messageType = typedMessage.MessageType;
236
420
  if (!_broadcastMethodsByType.TryGetValue(messageType, out object untargetedMethod))
237
421
  {
238
422
  // ReSharper disable once PossibleNullReferenceException
239
- MethodInfo broadcastMethod = MessageBusType.GetMethod(nameof(UntargetedBroadcast)).MakeGenericMethod(messageType);
423
+ MethodInfo broadcastMethod = MessageBusType
424
+ .GetMethod(nameof(UntargetedBroadcast))
425
+ .MakeGenericMethod(messageType);
240
426
  // ReSharper disable once PossibleNullReferenceException
241
- MethodInfo helperMethod = MessageBusType.GetMethod(nameof(UntargetedBroadcastReflectionHelper), ReflectionHelperBindingFlags).MakeGenericMethod(messageType);
427
+ MethodInfo helperMethod = MessageBusType
428
+ .GetMethod(
429
+ nameof(UntargetedBroadcastReflectionHelper),
430
+ ReflectionHelperBindingFlags
431
+ )
432
+ .MakeGenericMethod(messageType);
242
433
 
243
434
  ReflectionMethodArgumentsCache[0] = this;
244
435
  ReflectionMethodArgumentsCache[1] = broadcastMethod;
@@ -249,8 +440,9 @@
249
440
  Action<IUntargetedMessage> broadcast = (Action<IUntargetedMessage>)untargetedMethod;
250
441
  broadcast.Invoke(typedMessage);
251
442
  }
252
-
253
- public void UntargetedBroadcast<TMessage>(ref TMessage typedMessage) where TMessage : IUntargetedMessage
443
+
444
+ public void UntargetedBroadcast<TMessage>(ref TMessage typedMessage)
445
+ where TMessage : IUntargetedMessage
254
446
  {
255
447
  Type type = typeof(TMessage);
256
448
  if (!RunUntargetedInterceptors(type, ref typedMessage))
@@ -266,38 +458,76 @@
266
458
 
267
459
  bool foundAnyHandlers = InternalUntargetedBroadcast(ref typedMessage, type);
268
460
 
269
- if (_postProcessingSinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers) && 0 < handlers.Count)
461
+ if (
462
+ _postProcessingSinks.TryGetValue(
463
+ type,
464
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
465
+ )
466
+ && 0 < sortedHandlers.Count
467
+ )
270
468
  {
271
469
  foundAnyHandlers = true;
272
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
470
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
471
+ GetOrAddMessageHandlerStack(sortedHandlers);
273
472
  try
274
473
  {
275
- foreach (MessageHandler handler in messageHandlers)
474
+ foreach (
475
+ KeyValuePair<int, Dictionary<MessageHandler, int>> entry in handlerList
476
+ )
276
477
  {
277
- handler.HandleUntargetedPostProcessing(ref typedMessage, this);
478
+ int priority = entry.Key;
479
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
480
+ entry.Value.Keys
481
+ );
482
+ try
483
+ {
484
+ foreach (MessageHandler handler in messageHandlers)
485
+ {
486
+ handler.HandleUntargetedPostProcessing(
487
+ ref typedMessage,
488
+ this,
489
+ priority
490
+ );
491
+ }
492
+ }
493
+ finally
494
+ {
495
+ _messageHandlers.Push(messageHandlers);
496
+ }
278
497
  }
279
498
  }
280
499
  finally
281
500
  {
282
- _messageHandlers.Push(messageHandlers);
501
+ _sortedHandlers.Push(handlerList);
283
502
  }
284
503
  }
285
504
 
286
505
  if (!foundAnyHandlers)
287
506
  {
288
- MessagingDebug.Log(LogLevel.Info, "Could not find a matching untargeted broadcast handler for Message: {0}.", typedMessage);
507
+ MessagingDebug.Log(
508
+ LogLevel.Info,
509
+ "Could not find a matching untargeted broadcast handler for Message: {0}.",
510
+ typedMessage
511
+ );
289
512
  }
290
513
  }
291
-
514
+
292
515
  public void UntypedTargetedBroadcast(InstanceId target, ITargetedMessage typedMessage)
293
516
  {
294
517
  Type messageType = typedMessage.MessageType;
295
518
  if (!_broadcastMethodsByType.TryGetValue(messageType, out object targetedMethod))
296
519
  {
297
520
  // ReSharper disable once PossibleNullReferenceException
298
- MethodInfo broadcastMethod = MessageBusType.GetMethod(nameof(TargetedBroadcast)).MakeGenericMethod(messageType);
521
+ MethodInfo broadcastMethod = MessageBusType
522
+ .GetMethod(nameof(TargetedBroadcast))
523
+ .MakeGenericMethod(messageType);
299
524
  // ReSharper disable once PossibleNullReferenceException
300
- MethodInfo helperMethod = MessageBusType.GetMethod(nameof(TargetedBroadcastReflectionHelper), ReflectionHelperBindingFlags).MakeGenericMethod(messageType);
525
+ MethodInfo helperMethod = MessageBusType
526
+ .GetMethod(
527
+ nameof(TargetedBroadcastReflectionHelper),
528
+ ReflectionHelperBindingFlags
529
+ )
530
+ .MakeGenericMethod(messageType);
301
531
 
302
532
  ReflectionMethodArgumentsCache[0] = this;
303
533
  ReflectionMethodArgumentsCache[1] = broadcastMethod;
@@ -305,11 +535,13 @@
305
535
  _broadcastMethodsByType[messageType] = targetedMethod;
306
536
  }
307
537
 
308
- Action<InstanceId, ITargetedMessage> broadcast = (Action<InstanceId, ITargetedMessage>)targetedMethod;
538
+ Action<InstanceId, ITargetedMessage> broadcast =
539
+ (Action<InstanceId, ITargetedMessage>)targetedMethod;
309
540
  broadcast.Invoke(target, typedMessage);
310
541
  }
311
-
312
- public void TargetedBroadcast<TMessage>(ref InstanceId target, ref TMessage typedMessage) where TMessage : ITargetedMessage
542
+
543
+ public void TargetedBroadcast<TMessage>(ref InstanceId target, ref TMessage typedMessage)
544
+ where TMessage : ITargetedMessage
313
545
  {
314
546
  Type type = typeof(TMessage);
315
547
  if (!RunTargetedInterceptors(type, ref typedMessage, ref target))
@@ -324,89 +556,188 @@
324
556
  }
325
557
 
326
558
  bool foundAnyHandlers = false;
327
- if (_targetedSinks.TryGetValue(type, out Dictionary<InstanceId, Dictionary<MessageHandler, int>> targetedHandlers)
328
- && targetedHandlers.TryGetValue(target, out Dictionary<MessageHandler, int> handlers)
329
- && 0 < handlers.Count)
559
+ if (
560
+ _targetedSinks.TryGetValue(
561
+ type,
562
+ out Dictionary<
563
+ InstanceId,
564
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
565
+ > targetedHandlers
566
+ )
567
+ && targetedHandlers.TryGetValue(
568
+ target,
569
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
570
+ )
571
+ && 0 < sortedHandlers.Count
572
+ )
330
573
  {
331
574
  foundAnyHandlers = true;
332
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
575
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
576
+ GetOrAddMessageHandlerStack(sortedHandlers);
333
577
  try
334
578
  {
335
- foreach (MessageHandler handler in messageHandlers)
579
+ foreach (
580
+ KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList
581
+ )
336
582
  {
337
- handler.HandleTargeted(ref target, ref typedMessage, this);
583
+ int priority = handlers.Key;
584
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
585
+ handlers.Value.Keys
586
+ );
587
+ try
588
+ {
589
+ foreach (MessageHandler handler in messageHandlers)
590
+ {
591
+ handler.HandleTargeted(
592
+ ref target,
593
+ ref typedMessage,
594
+ this,
595
+ priority
596
+ );
597
+ }
598
+ }
599
+ finally
600
+ {
601
+ _messageHandlers.Push(messageHandlers);
602
+ }
338
603
  }
339
604
  }
340
605
  finally
341
606
  {
342
- _messageHandlers.Push(messageHandlers);
607
+ _sortedHandlers.Push(handlerList);
343
608
  }
344
609
  }
345
610
 
346
611
  _ = InternalTargetedWithoutTargetingBroadcast(ref target, ref typedMessage, type);
347
612
 
348
- if (_postProcessingTargetedSinks.TryGetValue(type, out targetedHandlers) && targetedHandlers.TryGetValue(target, out handlers) && 0 < handlers.Count)
613
+ if (
614
+ _postProcessingTargetedSinks.TryGetValue(type, out targetedHandlers)
615
+ && targetedHandlers.TryGetValue(target, out sortedHandlers)
616
+ && 0 < sortedHandlers.Count
617
+ )
349
618
  {
350
619
  foundAnyHandlers = true;
351
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
620
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
621
+ GetOrAddMessageHandlerStack(sortedHandlers);
352
622
  try
353
623
  {
354
- foreach (MessageHandler handler in messageHandlers)
624
+ foreach (
625
+ KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList
626
+ )
355
627
  {
356
- handler.HandleTargetedPostProcessing(ref target, ref typedMessage, this);
628
+ int priority = handlers.Key;
629
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
630
+ handlers.Value.Keys
631
+ );
632
+ try
633
+ {
634
+ foreach (MessageHandler handler in messageHandlers)
635
+ {
636
+ handler.HandleTargetedPostProcessing(
637
+ ref target,
638
+ ref typedMessage,
639
+ this,
640
+ priority
641
+ );
642
+ }
643
+ }
644
+ finally
645
+ {
646
+ _messageHandlers.Push(messageHandlers);
647
+ }
357
648
  }
358
649
  }
359
650
  finally
360
651
  {
361
- _messageHandlers.Push(messageHandlers);
652
+ _sortedHandlers.Push(handlerList);
362
653
  }
363
654
  }
364
655
 
365
- if (_postProcessingTargetedWithoutTargetingSinks.TryGetValue(type, out handlers) && 0 < handlers.Count)
656
+ if (
657
+ _postProcessingTargetedWithoutTargetingSinks.TryGetValue(type, out sortedHandlers)
658
+ && 0 < sortedHandlers.Count
659
+ )
366
660
  {
367
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
661
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
662
+ GetOrAddMessageHandlerStack(sortedHandlers);
368
663
  try
369
664
  {
370
- foreach (MessageHandler handler in messageHandlers)
665
+ foreach (
666
+ KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList
667
+ )
371
668
  {
372
- handler.HandleTargetedWithoutTargetingPostProcessing(ref target, ref typedMessage, this);
669
+ int priority = handlers.Key;
670
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
671
+ handlers.Value.Keys
672
+ );
673
+ try
674
+ {
675
+ foreach (MessageHandler handler in messageHandlers)
676
+ {
677
+ handler.HandleTargetedWithoutTargetingPostProcessing(
678
+ ref target,
679
+ ref typedMessage,
680
+ this,
681
+ priority
682
+ );
683
+ }
684
+ }
685
+ finally
686
+ {
687
+ _messageHandlers.Push(messageHandlers);
688
+ }
373
689
  }
374
690
  }
375
691
  finally
376
692
  {
377
- _messageHandlers.Push(messageHandlers);
693
+ _sortedHandlers.Push(handlerList);
378
694
  }
379
695
  }
380
696
 
381
697
  if (!foundAnyHandlers)
382
698
  {
383
- MessagingDebug.Log(LogLevel.Info, "Could not find a matching targeted broadcast handler for Id: {0}, Message: {1}.", target,
384
- typedMessage);
699
+ MessagingDebug.Log(
700
+ LogLevel.Info,
701
+ "Could not find a matching targeted broadcast handler for Id: {0}, Message: {1}.",
702
+ target,
703
+ typedMessage
704
+ );
385
705
  }
386
706
  }
387
707
 
388
708
  public void UntypedSourcedBroadcast(InstanceId source, IBroadcastMessage typedMessage)
389
709
  {
390
710
  Type messageType = typedMessage.MessageType;
391
- if (!_broadcastMethodsByType.TryGetValue(messageType, out object sourcedBroadcastMethod))
711
+ if (
712
+ !_broadcastMethodsByType.TryGetValue(messageType, out object sourcedBroadcastMethod)
713
+ )
392
714
  {
393
715
  // ReSharper disable once PossibleNullReferenceException
394
- MethodInfo broadcastMethod = MessageBusType.GetMethod(nameof(SourcedBroadcast)).MakeGenericMethod(messageType);
716
+ MethodInfo broadcastMethod = MessageBusType
717
+ .GetMethod(nameof(SourcedBroadcast))
718
+ .MakeGenericMethod(messageType);
395
719
  // ReSharper disable once PossibleNullReferenceException
396
- MethodInfo helperMethod = MessageBusType.GetMethod(nameof(SourcedBroadcastReflectionHelper), ReflectionHelperBindingFlags).MakeGenericMethod(messageType);
397
-
720
+ MethodInfo helperMethod = MessageBusType
721
+ .GetMethod(
722
+ nameof(SourcedBroadcastReflectionHelper),
723
+ ReflectionHelperBindingFlags
724
+ )
725
+ .MakeGenericMethod(messageType);
726
+
398
727
  ReflectionMethodArgumentsCache[0] = this;
399
728
  ReflectionMethodArgumentsCache[1] = broadcastMethod;
400
729
  sourcedBroadcastMethod = helperMethod.Invoke(null, ReflectionMethodArgumentsCache);
401
-
730
+
402
731
  _broadcastMethodsByType[messageType] = sourcedBroadcastMethod;
403
732
  }
404
733
 
405
- Action<InstanceId, IBroadcastMessage> broadcast = (Action<InstanceId, IBroadcastMessage>)sourcedBroadcastMethod;
734
+ Action<InstanceId, IBroadcastMessage> broadcast =
735
+ (Action<InstanceId, IBroadcastMessage>)sourcedBroadcastMethod;
406
736
  broadcast.Invoke(source, typedMessage);
407
737
  }
408
-
409
- public void SourcedBroadcast<TMessage>(ref InstanceId source, ref TMessage typedMessage) where TMessage : IBroadcastMessage
738
+
739
+ public void SourcedBroadcast<TMessage>(ref InstanceId source, ref TMessage typedMessage)
740
+ where TMessage : IBroadcastMessage
410
741
  {
411
742
  Type type = typeof(TMessage);
412
743
  if (!RunBroadcastInterceptors(type, ref typedMessage, ref source))
@@ -421,64 +752,152 @@
421
752
  }
422
753
 
423
754
  bool foundAnyHandlers = false;
424
- if (_broadcastSinks.TryGetValue(type, out Dictionary<InstanceId, Dictionary<MessageHandler, int>> broadcastHandlers)
425
- && broadcastHandlers.TryGetValue(source, out Dictionary<MessageHandler, int> handlers)
426
- && 0 < handlers.Count)
755
+ if (
756
+ _broadcastSinks.TryGetValue(
757
+ type,
758
+ out Dictionary<
759
+ InstanceId,
760
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
761
+ > broadcastHandlers
762
+ )
763
+ && broadcastHandlers.TryGetValue(
764
+ source,
765
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
766
+ )
767
+ && 0 < sortedHandlers.Count
768
+ )
427
769
  {
428
770
  foundAnyHandlers = true;
429
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
771
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
772
+ GetOrAddMessageHandlerStack(sortedHandlers);
430
773
  try
431
774
  {
432
- foreach (MessageHandler handler in messageHandlers)
775
+ foreach (
776
+ KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList
777
+ )
433
778
  {
434
- handler.HandleSourcedBroadcast(ref source, ref typedMessage, this);
779
+ int priority = handlers.Key;
780
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
781
+ handlers.Value.Keys
782
+ );
783
+ try
784
+ {
785
+ foreach (MessageHandler handler in messageHandlers)
786
+ {
787
+ handler.HandleSourcedBroadcast(
788
+ ref source,
789
+ ref typedMessage,
790
+ this,
791
+ priority
792
+ );
793
+ }
794
+ }
795
+ finally
796
+ {
797
+ _messageHandlers.Push(messageHandlers);
798
+ }
435
799
  }
436
800
  }
437
801
  finally
438
802
  {
439
- _messageHandlers.Push(messageHandlers);
803
+ _sortedHandlers.Push(handlerList);
440
804
  }
441
805
  }
442
806
 
443
807
  _ = InternalBroadcastWithoutSource(ref source, ref typedMessage, type);
444
808
 
445
- if (_postProcessingBroadcastSinks.TryGetValue(type, out broadcastHandlers) && broadcastHandlers.TryGetValue(source, out handlers) && 0 < handlers.Count)
809
+ if (
810
+ _postProcessingBroadcastSinks.TryGetValue(type, out broadcastHandlers)
811
+ && broadcastHandlers.TryGetValue(source, out sortedHandlers)
812
+ && 0 < sortedHandlers.Count
813
+ )
446
814
  {
447
815
  foundAnyHandlers = true;
448
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
816
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
817
+ GetOrAddMessageHandlerStack(sortedHandlers);
449
818
  try
450
819
  {
451
- foreach (MessageHandler handler in messageHandlers)
820
+ foreach (
821
+ KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList
822
+ )
452
823
  {
453
- handler.HandleSourcedBroadcastPostProcessing(ref source, ref typedMessage, this);
824
+ int priority = handlers.Key;
825
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
826
+ handlers.Value.Keys
827
+ );
828
+ try
829
+ {
830
+ foreach (MessageHandler handler in messageHandlers)
831
+ {
832
+ handler.HandleSourcedBroadcastPostProcessing(
833
+ ref source,
834
+ ref typedMessage,
835
+ this,
836
+ priority
837
+ );
838
+ }
839
+ }
840
+ finally
841
+ {
842
+ _messageHandlers.Push(messageHandlers);
843
+ }
454
844
  }
455
845
  }
456
846
  finally
457
847
  {
458
- _messageHandlers.Push(messageHandlers);
848
+ _sortedHandlers.Push(handlerList);
459
849
  }
460
850
  }
461
851
 
462
- if (_postProcessingBroadcastWithoutSourceSinks.TryGetValue(type, out handlers) && 0 < handlers.Count)
852
+ if (
853
+ _postProcessingBroadcastWithoutSourceSinks.TryGetValue(type, out sortedHandlers)
854
+ && 0 < sortedHandlers.Count
855
+ )
463
856
  {
464
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
857
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
858
+ GetOrAddMessageHandlerStack(sortedHandlers);
465
859
  try
466
860
  {
467
- foreach (MessageHandler handler in messageHandlers)
861
+ foreach (
862
+ KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList
863
+ )
468
864
  {
469
- handler.HandleSourcedBroadcastWithoutSourcePostProcessing(ref source, ref typedMessage, this);
865
+ int priority = handlers.Key;
866
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
867
+ handlers.Value.Keys
868
+ );
869
+ try
870
+ {
871
+ foreach (MessageHandler handler in messageHandlers)
872
+ {
873
+ handler.HandleSourcedBroadcastWithoutSourcePostProcessing(
874
+ ref source,
875
+ ref typedMessage,
876
+ this,
877
+ priority
878
+ );
879
+ }
880
+ }
881
+ finally
882
+ {
883
+ _messageHandlers.Push(messageHandlers);
884
+ }
470
885
  }
471
886
  }
472
887
  finally
473
888
  {
474
- _messageHandlers.Push(messageHandlers);
889
+ _sortedHandlers.Push(handlerList);
475
890
  }
476
891
  }
477
892
 
478
893
  if (!foundAnyHandlers)
479
894
  {
480
- MessagingDebug.Log(LogLevel.Info, "Could not find a matching sourced broadcast handler for Id: {0}, Message: {1}.",
481
- source, typedMessage);
895
+ MessagingDebug.Log(
896
+ LogLevel.Info,
897
+ "Could not find a matching sourced broadcast handler for Id: {0}, Message: {1}.",
898
+ source,
899
+ typedMessage
900
+ );
482
901
  }
483
902
  }
484
903
 
@@ -524,7 +943,10 @@
524
943
  }
525
944
  }
526
945
 
527
- private void BroadcastGlobalSourcedBroadcast(ref InstanceId source, ref IBroadcastMessage message)
946
+ private void BroadcastGlobalSourcedBroadcast(
947
+ ref InstanceId source,
948
+ ref IBroadcastMessage message
949
+ )
528
950
  {
529
951
  if (_globalSinks.Count <= 0)
530
952
  {
@@ -545,7 +967,12 @@
545
967
  }
546
968
  }
547
969
 
548
- private bool TryGetInterceptorCaches(Type type, out SortedDictionary<int, List<object>> interceptors, out List<int> interceptorKeys, out List<object> interceptorStack)
970
+ private bool TryGetInterceptorCaches(
971
+ Type type,
972
+ out SortedDictionary<int, List<object>> interceptors,
973
+ out List<int> interceptorKeys,
974
+ out List<object> interceptorStack
975
+ )
549
976
  {
550
977
  if (!_interceptsByType.TryGetValue(type, out interceptors) || interceptors.Count <= 0)
551
978
  {
@@ -567,13 +994,17 @@
567
994
  return true;
568
995
  }
569
996
 
570
- private bool RunUntargetedInterceptors<T>(Type type, ref T message) where T : IUntargetedMessage
997
+ private bool RunUntargetedInterceptors<T>(Type type, ref T message)
998
+ where T : IUntargetedMessage
571
999
  {
572
- if (!TryGetInterceptorCaches(
573
- type,
574
- out SortedDictionary<int, List<object>> interceptors,
1000
+ if (
1001
+ !TryGetInterceptorCaches(
1002
+ type,
1003
+ out SortedDictionary<int, List<object>> interceptors,
575
1004
  out List<int> interceptorKeys,
576
- out List<object> interceptorStack))
1005
+ out List<object> interceptorStack
1006
+ )
1007
+ )
577
1008
  {
578
1009
  return true;
579
1010
  }
@@ -584,7 +1015,10 @@
584
1015
  interceptorKeys.AddRange(interceptors.Keys);
585
1016
  foreach (int priority in interceptorKeys)
586
1017
  {
587
- if (!interceptors.TryGetValue(priority, out List<object> untypedInterceptors) || untypedInterceptors.Count <= 0)
1018
+ if (
1019
+ !interceptors.TryGetValue(priority, out List<object> untypedInterceptors)
1020
+ || untypedInterceptors.Count <= 0
1021
+ )
588
1022
  {
589
1023
  continue;
590
1024
  }
@@ -615,13 +1049,17 @@
615
1049
  return true;
616
1050
  }
617
1051
 
618
- private bool RunTargetedInterceptors<T>(Type type, ref T message, ref InstanceId target) where T : ITargetedMessage
1052
+ private bool RunTargetedInterceptors<T>(Type type, ref T message, ref InstanceId target)
1053
+ where T : ITargetedMessage
619
1054
  {
620
- if (!TryGetInterceptorCaches(
1055
+ if (
1056
+ !TryGetInterceptorCaches(
621
1057
  type,
622
1058
  out SortedDictionary<int, List<object>> interceptors,
623
1059
  out List<int> interceptorKeys,
624
- out List<object> interceptorStack))
1060
+ out List<object> interceptorStack
1061
+ )
1062
+ )
625
1063
  {
626
1064
  return true;
627
1065
  }
@@ -632,7 +1070,10 @@
632
1070
  interceptorKeys.AddRange(interceptors.Keys);
633
1071
  foreach (int priority in interceptorKeys)
634
1072
  {
635
- if (!interceptors.TryGetValue(priority, out List<object> untypedInterceptors) || untypedInterceptors.Count <= 0)
1073
+ if (
1074
+ !interceptors.TryGetValue(priority, out List<object> untypedInterceptors)
1075
+ || untypedInterceptors.Count <= 0
1076
+ )
636
1077
  {
637
1078
  continue;
638
1079
  }
@@ -663,13 +1104,17 @@
663
1104
  return true;
664
1105
  }
665
1106
 
666
- private bool RunBroadcastInterceptors<T>(Type type, ref T message, ref InstanceId source) where T : IBroadcastMessage
1107
+ private bool RunBroadcastInterceptors<T>(Type type, ref T message, ref InstanceId source)
1108
+ where T : IBroadcastMessage
667
1109
  {
668
- if (!TryGetInterceptorCaches(
1110
+ if (
1111
+ !TryGetInterceptorCaches(
669
1112
  type,
670
1113
  out SortedDictionary<int, List<object>> interceptors,
671
1114
  out List<int> interceptorKeys,
672
- out List<object> interceptorStack))
1115
+ out List<object> interceptorStack
1116
+ )
1117
+ )
673
1118
  {
674
1119
  return true;
675
1120
  }
@@ -680,7 +1125,10 @@
680
1125
  interceptorKeys.AddRange(interceptors.Keys);
681
1126
  foreach (int priority in interceptorKeys)
682
1127
  {
683
- if (!interceptors.TryGetValue(priority, out List<object> untypedInterceptors) || untypedInterceptors.Count <= 0)
1128
+ if (
1129
+ !interceptors.TryGetValue(priority, out List<object> untypedInterceptors)
1130
+ || untypedInterceptors.Count <= 0
1131
+ )
684
1132
  {
685
1133
  continue;
686
1134
  }
@@ -711,78 +1159,166 @@
711
1159
  return true;
712
1160
  }
713
1161
 
714
- private bool InternalUntargetedBroadcast<TMessage>(ref TMessage message, Type type) where TMessage : IMessage
1162
+ private bool InternalUntargetedBroadcast<TMessage>(ref TMessage message, Type type)
1163
+ where TMessage : IMessage
715
1164
  {
716
- if (!_sinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers) || handlers.Count <= 0)
1165
+ if (
1166
+ !_sinks.TryGetValue(
1167
+ type,
1168
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
1169
+ )
1170
+ || sortedHandlers.Count <= 0
1171
+ )
717
1172
  {
718
1173
  return false;
719
1174
  }
720
1175
 
721
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
1176
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
1177
+ GetOrAddMessageHandlerStack(sortedHandlers);
722
1178
  try
723
1179
  {
724
- foreach (MessageHandler handler in messageHandlers)
1180
+ foreach (KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList)
725
1181
  {
726
- handler.HandleUntargetedMessage(ref message, this);
1182
+ int priority = handlers.Key;
1183
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1184
+ handlers.Value.Keys
1185
+ );
1186
+ try
1187
+ {
1188
+ foreach (MessageHandler handler in messageHandlers)
1189
+ {
1190
+ handler.HandleUntargetedMessage(ref message, this, priority);
1191
+ }
1192
+ }
1193
+ finally
1194
+ {
1195
+ _messageHandlers.Push(messageHandlers);
1196
+ }
727
1197
  }
728
1198
  }
729
1199
  finally
730
1200
  {
731
- _messageHandlers.Push(messageHandlers);
1201
+ _sortedHandlers.Push(handlerList);
732
1202
  }
733
1203
 
734
1204
  return true;
735
1205
  }
736
1206
 
737
1207
  private bool InternalTargetedWithoutTargetingBroadcast<TMessage>(
738
- ref InstanceId target, ref TMessage message, Type type) where TMessage : ITargetedMessage
1208
+ ref InstanceId target,
1209
+ ref TMessage message,
1210
+ Type type
1211
+ )
1212
+ where TMessage : ITargetedMessage
739
1213
  {
740
- if (!_sinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers) || handlers.Count <= 0)
1214
+ if (
1215
+ !_sinks.TryGetValue(
1216
+ type,
1217
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
1218
+ )
1219
+ || sortedHandlers.Count <= 0
1220
+ )
741
1221
  {
742
1222
  return false;
743
1223
  }
744
1224
 
745
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
1225
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
1226
+ GetOrAddMessageHandlerStack(sortedHandlers);
746
1227
  try
747
1228
  {
748
- foreach (MessageHandler handler in messageHandlers)
1229
+ foreach (KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList)
749
1230
  {
750
- handler.HandleTargetedWithoutTargeting(ref target, ref message, this);
1231
+ int priority = handlers.Key;
1232
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1233
+ handlers.Value.Keys
1234
+ );
1235
+ try
1236
+ {
1237
+ foreach (MessageHandler handler in messageHandlers)
1238
+ {
1239
+ handler.HandleTargetedWithoutTargeting(
1240
+ ref target,
1241
+ ref message,
1242
+ this,
1243
+ priority
1244
+ );
1245
+ }
1246
+ }
1247
+ finally
1248
+ {
1249
+ _messageHandlers.Push(messageHandlers);
1250
+ }
751
1251
  }
752
1252
  }
753
1253
  finally
754
1254
  {
755
- _messageHandlers.Push(messageHandlers);
1255
+ _sortedHandlers.Push(handlerList);
756
1256
  }
757
1257
 
758
1258
  return true;
759
1259
  }
760
1260
 
761
1261
  private bool InternalBroadcastWithoutSource<TMessage>(
762
- ref InstanceId target, ref TMessage message, Type type) where TMessage : IBroadcastMessage
1262
+ ref InstanceId target,
1263
+ ref TMessage message,
1264
+ Type type
1265
+ )
1266
+ where TMessage : IBroadcastMessage
763
1267
  {
764
- if (!_sinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers) || handlers.Count <= 0)
1268
+ if (
1269
+ !_sinks.TryGetValue(
1270
+ type,
1271
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
1272
+ )
1273
+ || sortedHandlers.Count <= 0
1274
+ )
765
1275
  {
766
1276
  return false;
767
1277
  }
768
1278
 
769
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
1279
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
1280
+ GetOrAddMessageHandlerStack(sortedHandlers);
770
1281
  try
771
1282
  {
772
- foreach (MessageHandler handler in messageHandlers)
1283
+ foreach (KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList)
773
1284
  {
774
- handler.HandleSourcedBroadcastWithoutSource(ref target, ref message, this);
1285
+ int priority = handlers.Key;
1286
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1287
+ handlers.Value.Keys
1288
+ );
1289
+ try
1290
+ {
1291
+ foreach (MessageHandler handler in messageHandlers)
1292
+ {
1293
+ handler.HandleSourcedBroadcastWithoutSource(
1294
+ ref target,
1295
+ ref message,
1296
+ this,
1297
+ priority
1298
+ );
1299
+ }
1300
+ }
1301
+ finally
1302
+ {
1303
+ _messageHandlers.Push(messageHandlers);
1304
+ }
775
1305
  }
776
1306
  }
777
1307
  finally
778
1308
  {
779
- _messageHandlers.Push(messageHandlers);
1309
+ _sortedHandlers.Push(handlerList);
780
1310
  }
781
1311
 
782
1312
  return true;
783
1313
  }
784
1314
 
785
- private Action InternalRegisterUntargeted<T>(MessageHandler messageHandler, Dictionary<Type, Dictionary<MessageHandler, int>> sinks, RegistrationMethod registrationMethod) where T : IMessage
1315
+ private Action InternalRegisterUntargeted<T>(
1316
+ MessageHandler messageHandler,
1317
+ Dictionary<Type, SortedDictionary<int, Dictionary<MessageHandler, int>>> sinks,
1318
+ RegistrationMethod registrationMethod,
1319
+ int priority
1320
+ )
1321
+ where T : IMessage
786
1322
  {
787
1323
  if (messageHandler == null)
788
1324
  {
@@ -792,55 +1328,101 @@
792
1328
  InstanceId handlerOwnerId = messageHandler.owner;
793
1329
  Type type = typeof(T);
794
1330
 
795
- if (!sinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers))
1331
+ if (
1332
+ !sinks.TryGetValue(
1333
+ type,
1334
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> handlers
1335
+ )
1336
+ )
796
1337
  {
797
- handlers = new Dictionary<MessageHandler, int>();
1338
+ handlers = new SortedDictionary<int, Dictionary<MessageHandler, int>>();
798
1339
  sinks[type] = handlers;
799
1340
  }
800
1341
 
801
- if (!handlers.TryGetValue(messageHandler, out int count))
1342
+ if (!handlers.TryGetValue(priority, out Dictionary<MessageHandler, int> handler))
802
1343
  {
803
- count = 0;
1344
+ handler = new Dictionary<MessageHandler, int>();
1345
+ handlers[priority] = handler;
804
1346
  }
805
1347
 
806
- handlers[messageHandler] = count + 1;
807
- _log.Log(new MessagingRegistration(handlerOwnerId, type, RegistrationType.Register, registrationMethod));
1348
+ int count = handler.GetValueOrDefault(messageHandler, 0);
1349
+
1350
+ handler[messageHandler] = count + 1;
1351
+ _log.Log(
1352
+ new MessagingRegistration(
1353
+ handlerOwnerId,
1354
+ type,
1355
+ RegistrationType.Register,
1356
+ registrationMethod
1357
+ )
1358
+ );
808
1359
 
809
1360
  return () =>
810
1361
  {
811
- _log.Log(new MessagingRegistration(handlerOwnerId, type, RegistrationType.Deregister, registrationMethod));
812
- if (!sinks.TryGetValue(type, out handlers) || !handlers.TryGetValue(messageHandler, out count))
1362
+ _log.Log(
1363
+ new MessagingRegistration(
1364
+ handlerOwnerId,
1365
+ type,
1366
+ RegistrationType.Deregister,
1367
+ registrationMethod
1368
+ )
1369
+ );
1370
+ if (
1371
+ !sinks.TryGetValue(type, out handlers)
1372
+ || !handlers.TryGetValue(priority, out handler)
1373
+ || !handler.TryGetValue(messageHandler, out count)
1374
+ )
813
1375
  {
814
- MessagingDebug.Log(LogLevel.Error,
1376
+ MessagingDebug.Log(
1377
+ LogLevel.Error,
815
1378
  "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
816
- type, messageHandler);
1379
+ type,
1380
+ messageHandler
1381
+ );
817
1382
  return;
818
1383
  }
819
1384
 
820
1385
  if (count <= 1)
821
1386
  {
822
- bool complete = handlers.Remove(messageHandler);
823
- bool trulyComplete = true;
1387
+ bool complete = handler.Remove(messageHandler);
1388
+
1389
+ if (handler.Count <= 0)
1390
+ {
1391
+ _ = handlers.Remove(priority);
1392
+ }
1393
+
824
1394
  if (handlers.Count <= 0)
825
1395
  {
826
- trulyComplete = sinks.Remove(type);
1396
+ _ = sinks.Remove(type);
827
1397
  }
828
1398
 
829
- if (!complete || !trulyComplete)
1399
+ if (!complete)
830
1400
  {
831
- MessagingDebug.Log(LogLevel.Error,
1401
+ MessagingDebug.Log(
1402
+ LogLevel.Error,
832
1403
  "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
833
- type, messageHandler);
1404
+ type,
1405
+ messageHandler
1406
+ );
834
1407
  }
835
1408
  }
836
1409
  else
837
1410
  {
838
- handlers[messageHandler] = count - 1;
1411
+ handler[messageHandler] = count - 1;
839
1412
  }
840
1413
  };
841
1414
  }
842
1415
 
843
- private Action InternalRegisterWithContext<T>(InstanceId context, MessageHandler messageHandler, Dictionary<Type, Dictionary<InstanceId, Dictionary<MessageHandler, int>>> sinks, RegistrationMethod registrationMethod)
1416
+ private Action InternalRegisterWithContext<T>(
1417
+ InstanceId context,
1418
+ MessageHandler messageHandler,
1419
+ Dictionary<
1420
+ Type,
1421
+ Dictionary<InstanceId, SortedDictionary<int, Dictionary<MessageHandler, int>>>
1422
+ > sinks,
1423
+ RegistrationMethod registrationMethod,
1424
+ int priority
1425
+ )
844
1426
  {
845
1427
  if (messageHandler == null)
846
1428
  {
@@ -848,40 +1430,87 @@
848
1430
  }
849
1431
 
850
1432
  Type type = typeof(T);
851
- if (!sinks.TryGetValue(type, out Dictionary<InstanceId, Dictionary<MessageHandler, int>> broadcastHandlers))
852
- {
853
- broadcastHandlers = new Dictionary<InstanceId, Dictionary<MessageHandler, int>>();
1433
+ if (
1434
+ !sinks.TryGetValue(
1435
+ type,
1436
+ out Dictionary<
1437
+ InstanceId,
1438
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
1439
+ > broadcastHandlers
1440
+ )
1441
+ )
1442
+ {
1443
+ broadcastHandlers =
1444
+ new Dictionary<
1445
+ InstanceId,
1446
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
1447
+ >();
854
1448
  sinks[type] = broadcastHandlers;
855
1449
  }
856
1450
 
857
- if (!broadcastHandlers.TryGetValue(context, out Dictionary<MessageHandler, int> handlers))
1451
+ if (
1452
+ !broadcastHandlers.TryGetValue(
1453
+ context,
1454
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> handlers
1455
+ )
1456
+ )
858
1457
  {
859
- handlers = new Dictionary<MessageHandler, int>();
1458
+ handlers = new SortedDictionary<int, Dictionary<MessageHandler, int>>();
860
1459
  broadcastHandlers[context] = handlers;
861
1460
  }
862
1461
 
863
- if (!handlers.TryGetValue(messageHandler, out int count))
1462
+ if (!handlers.TryGetValue(priority, out Dictionary<MessageHandler, int> handler))
864
1463
  {
865
- count = 0;
1464
+ handler = new Dictionary<MessageHandler, int>();
1465
+ handlers[priority] = handler;
866
1466
  }
867
1467
 
868
- handlers[messageHandler] = count + 1;
869
- _log.Log(new MessagingRegistration(context, type, RegistrationType.Register, registrationMethod));
1468
+ int count = handler.GetValueOrDefault(messageHandler, 0);
1469
+
1470
+ handler[messageHandler] = count + 1;
1471
+ _log.Log(
1472
+ new MessagingRegistration(
1473
+ context,
1474
+ type,
1475
+ RegistrationType.Register,
1476
+ registrationMethod
1477
+ )
1478
+ );
870
1479
 
871
1480
  return () =>
872
1481
  {
873
- _log.Log(new MessagingRegistration(context, type, RegistrationType.Deregister, registrationMethod));
874
- if (!sinks.TryGetValue(type, out broadcastHandlers) || !broadcastHandlers.TryGetValue(context, out handlers) || !handlers.TryGetValue(messageHandler, out count))
1482
+ _log.Log(
1483
+ new MessagingRegistration(
1484
+ context,
1485
+ type,
1486
+ RegistrationType.Deregister,
1487
+ registrationMethod
1488
+ )
1489
+ );
1490
+ if (
1491
+ !sinks.TryGetValue(type, out broadcastHandlers)
1492
+ || !broadcastHandlers.TryGetValue(context, out handlers)
1493
+ || !handlers.TryGetValue(priority, out handler)
1494
+ || !handler.TryGetValue(messageHandler, out count)
1495
+ )
875
1496
  {
876
- MessagingDebug.Log(LogLevel.Error,
1497
+ MessagingDebug.Log(
1498
+ LogLevel.Error,
877
1499
  "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
878
- type, messageHandler);
1500
+ type,
1501
+ messageHandler
1502
+ );
879
1503
  return;
880
1504
  }
881
1505
 
882
1506
  if (count <= 1)
883
1507
  {
884
- bool complete = handlers.Remove(messageHandler);
1508
+ bool complete = handler.Remove(messageHandler);
1509
+ if (handler.Count <= 0)
1510
+ {
1511
+ _ = handlers.Remove(priority);
1512
+ }
1513
+
885
1514
  if (handlers.Count <= 0)
886
1515
  {
887
1516
  _ = broadcastHandlers.Remove(context);
@@ -894,19 +1523,44 @@
894
1523
 
895
1524
  if (!complete)
896
1525
  {
897
- MessagingDebug.Log(LogLevel.Error,
1526
+ MessagingDebug.Log(
1527
+ LogLevel.Error,
898
1528
  "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
899
- type, messageHandler);
1529
+ type,
1530
+ messageHandler
1531
+ );
900
1532
  }
901
1533
  }
902
1534
  else
903
1535
  {
904
- handlers[messageHandler] = count - 1;
1536
+ handler[messageHandler] = count - 1;
905
1537
  }
906
1538
  };
907
1539
  }
908
1540
 
909
- private List<MessageHandler> GetOrAddMessageHandlerStack(IEnumerable<MessageHandler> handlers)
1541
+ private List<
1542
+ KeyValuePair<int, Dictionary<MessageHandler, int>>
1543
+ > GetOrAddMessageHandlerStack(
1544
+ IEnumerable<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlers
1545
+ )
1546
+ {
1547
+ if (
1548
+ !_sortedHandlers.TryPop(
1549
+ out List<KeyValuePair<int, Dictionary<MessageHandler, int>>> messageHandlers
1550
+ )
1551
+ )
1552
+ {
1553
+ return new List<KeyValuePair<int, Dictionary<MessageHandler, int>>>(handlers);
1554
+ }
1555
+
1556
+ messageHandlers.Clear();
1557
+ messageHandlers.AddRange(handlers);
1558
+ return messageHandlers;
1559
+ }
1560
+
1561
+ private List<MessageHandler> GetOrAddMessageHandlerStack(
1562
+ IEnumerable<MessageHandler> handlers
1563
+ )
910
1564
  {
911
1565
  if (!_messageHandlers.TryPop(out List<MessageHandler> messageHandlers))
912
1566
  {
@@ -919,40 +1573,73 @@
919
1573
  }
920
1574
 
921
1575
  // https://blogs.msmvps.com/jonskeet/2008/08/09/making-reflection-fly-and-exploring-delegates/
922
- private static Action<IUntargetedMessage> UntargetedBroadcastReflectionHelper<T>(IMessageBus messageBus, MethodInfo methodInfo) where T : IUntargetedMessage
1576
+ private static Action<IUntargetedMessage> UntargetedBroadcastReflectionHelper<T>(
1577
+ IMessageBus messageBus,
1578
+ MethodInfo methodInfo
1579
+ )
1580
+ where T : IUntargetedMessage
923
1581
  {
924
- FastUntargetedBroadcast<T> untargetedBroadcast = (FastUntargetedBroadcast<T>) Delegate.CreateDelegate(typeof(FastUntargetedBroadcast<T>), messageBus, methodInfo);
1582
+ FastUntargetedBroadcast<T> untargetedBroadcast =
1583
+ (FastUntargetedBroadcast<T>)
1584
+ Delegate.CreateDelegate(
1585
+ typeof(FastUntargetedBroadcast<T>),
1586
+ messageBus,
1587
+ methodInfo
1588
+ );
1589
+
1590
+ return UntypedBroadcast;
1591
+
925
1592
  void UntypedBroadcast(IUntargetedMessage message)
926
1593
  {
927
- T typedMessage = (T) message;
1594
+ T typedMessage = (T)message;
928
1595
  untargetedBroadcast(ref typedMessage);
929
1596
  }
930
-
931
- return UntypedBroadcast;
932
1597
  }
933
1598
 
934
- private static Action<InstanceId, ITargetedMessage> TargetedBroadcastReflectionHelper<T>(IMessageBus messageBus, MethodInfo methodInfo) where T : ITargetedMessage
1599
+ private static Action<InstanceId, ITargetedMessage> TargetedBroadcastReflectionHelper<T>(
1600
+ IMessageBus messageBus,
1601
+ MethodInfo methodInfo
1602
+ )
1603
+ where T : ITargetedMessage
935
1604
  {
936
- FastTargetedBroadcast<T> targetedBroadcast = (FastTargetedBroadcast<T>) Delegate.CreateDelegate(typeof(FastTargetedBroadcast<T>), messageBus, methodInfo);
1605
+ FastTargetedBroadcast<T> targetedBroadcast =
1606
+ (FastTargetedBroadcast<T>)
1607
+ Delegate.CreateDelegate(
1608
+ typeof(FastTargetedBroadcast<T>),
1609
+ messageBus,
1610
+ methodInfo
1611
+ );
1612
+
1613
+ return UntypedBroadcast;
1614
+
937
1615
  void UntypedBroadcast(InstanceId target, ITargetedMessage message)
938
1616
  {
939
- T typedMessage = (T) message;
1617
+ T typedMessage = (T)message;
940
1618
  targetedBroadcast(ref target, ref typedMessage);
941
1619
  }
942
-
943
- return UntypedBroadcast;
944
1620
  }
945
1621
 
946
- private static Action<InstanceId, IBroadcastMessage> SourcedBroadcastReflectionHelper<T>(IMessageBus messageBus, MethodInfo methodInfo) where T : IBroadcastMessage
1622
+ private static Action<InstanceId, IBroadcastMessage> SourcedBroadcastReflectionHelper<T>(
1623
+ IMessageBus messageBus,
1624
+ MethodInfo methodInfo
1625
+ )
1626
+ where T : IBroadcastMessage
947
1627
  {
948
- FastSourcedBroadcast<T> sourcedBroadcast = (FastSourcedBroadcast<T>)Delegate.CreateDelegate(typeof(FastSourcedBroadcast<T>), messageBus, methodInfo);
1628
+ FastSourcedBroadcast<T> sourcedBroadcast =
1629
+ (FastSourcedBroadcast<T>)
1630
+ Delegate.CreateDelegate(
1631
+ typeof(FastSourcedBroadcast<T>),
1632
+ messageBus,
1633
+ methodInfo
1634
+ );
1635
+
1636
+ return UntypedBroadcast;
1637
+
949
1638
  void UntypedBroadcast(InstanceId target, IBroadcastMessage message)
950
1639
  {
951
1640
  T typedMessage = (T)message;
952
1641
  sourcedBroadcast(ref target, ref typedMessage);
953
1642
  }
954
-
955
- return UntypedBroadcast;
956
1643
  }
957
1644
  }
958
1645
  }