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

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();
49
- private readonly Stack<List<object>> _interceptors = new();
50
- private readonly Stack<List<int>> _interceptorKeys = new();
51
-
52
- public Action RegisterUntargeted<T>(MessageHandler messageHandler) where T : IUntargetedMessage
81
+ private readonly Stack<
82
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>>
83
+ > _sortedHandlers = new();
84
+ private readonly Stack<List<List<object>>> _interceptors = new();
85
+ private readonly Stack<List<object>> _innerInterceptorsStack = new();
86
+
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,54 +967,65 @@
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 List<List<object>> interceptorStack,
973
+ out List<object> interceptorObjects
974
+ )
549
975
  {
550
- if (!_interceptsByType.TryGetValue(type, out interceptors) || interceptors.Count <= 0)
976
+ if (
977
+ !_interceptsByType.TryGetValue(
978
+ type,
979
+ out SortedDictionary<int, List<object>> interceptors
980
+ )
981
+ || interceptors.Count <= 0
982
+ )
551
983
  {
552
- interceptorKeys = default;
553
984
  interceptorStack = default;
985
+ interceptorObjects = default;
554
986
  return false;
555
987
  }
556
988
 
557
989
  if (!_interceptors.TryPop(out interceptorStack))
558
990
  {
559
- interceptorStack = new List<object>();
991
+ interceptorStack = new List<List<object>>(interceptors.Values);
992
+ }
993
+ else
994
+ {
995
+ interceptorStack.Clear();
996
+ interceptorStack.AddRange(interceptors.Values);
560
997
  }
561
998
 
562
- if (!_interceptorKeys.TryPop(out interceptorKeys))
999
+ if (!_innerInterceptorsStack.TryPop(out interceptorObjects))
563
1000
  {
564
- interceptorKeys = new List<int>();
1001
+ interceptorObjects = new List<object>();
565
1002
  }
566
1003
 
567
1004
  return true;
568
1005
  }
569
1006
 
570
- private bool RunUntargetedInterceptors<T>(Type type, ref T message) where T : IUntargetedMessage
1007
+ private bool RunUntargetedInterceptors<T>(Type type, ref T message)
1008
+ where T : IUntargetedMessage
571
1009
  {
572
- if (!TryGetInterceptorCaches(
573
- type,
574
- out SortedDictionary<int, List<object>> interceptors,
575
- out List<int> interceptorKeys,
576
- out List<object> interceptorStack))
1010
+ if (
1011
+ !TryGetInterceptorCaches(
1012
+ type,
1013
+ out List<List<object>> interceptorStack,
1014
+ out List<object> interceptorObjects
1015
+ )
1016
+ )
577
1017
  {
578
1018
  return true;
579
1019
  }
580
1020
 
581
1021
  try
582
1022
  {
583
- interceptorKeys.Clear();
584
- interceptorKeys.AddRange(interceptors.Keys);
585
- foreach (int priority in interceptorKeys)
1023
+ foreach (List<object> stack in interceptorStack)
586
1024
  {
587
- if (!interceptors.TryGetValue(priority, out List<object> untypedInterceptors) || untypedInterceptors.Count <= 0)
588
- {
589
- continue;
590
- }
1025
+ interceptorObjects.Clear();
1026
+ interceptorObjects.AddRange(stack);
591
1027
 
592
- interceptorStack.Clear();
593
- interceptorStack.AddRange(untypedInterceptors);
594
-
595
- foreach (object transformer in interceptorStack)
1028
+ foreach (object transformer in interceptorObjects)
596
1029
  {
597
1030
  if (transformer is not UntargetedInterceptor<T> typedTransformer)
598
1031
  {
@@ -609,38 +1042,34 @@
609
1042
  finally
610
1043
  {
611
1044
  _interceptors.Push(interceptorStack);
612
- _interceptorKeys.Push(interceptorKeys);
1045
+ _innerInterceptorsStack.Push(interceptorObjects);
613
1046
  }
614
1047
 
615
1048
  return true;
616
1049
  }
617
1050
 
618
- private bool RunTargetedInterceptors<T>(Type type, ref T message, ref InstanceId target) where T : ITargetedMessage
1051
+ private bool RunTargetedInterceptors<T>(Type type, ref T message, ref InstanceId target)
1052
+ where T : ITargetedMessage
619
1053
  {
620
- if (!TryGetInterceptorCaches(
1054
+ if (
1055
+ !TryGetInterceptorCaches(
621
1056
  type,
622
- out SortedDictionary<int, List<object>> interceptors,
623
- out List<int> interceptorKeys,
624
- out List<object> interceptorStack))
1057
+ out List<List<object>> interceptorStack,
1058
+ out List<object> interceptorObjects
1059
+ )
1060
+ )
625
1061
  {
626
1062
  return true;
627
1063
  }
628
1064
 
629
1065
  try
630
1066
  {
631
- interceptorKeys.Clear();
632
- interceptorKeys.AddRange(interceptors.Keys);
633
- foreach (int priority in interceptorKeys)
1067
+ foreach (List<object> stack in interceptorStack)
634
1068
  {
635
- if (!interceptors.TryGetValue(priority, out List<object> untypedInterceptors) || untypedInterceptors.Count <= 0)
636
- {
637
- continue;
638
- }
639
-
640
- interceptorStack.Clear();
641
- interceptorStack.AddRange(untypedInterceptors);
1069
+ interceptorObjects.Clear();
1070
+ interceptorObjects.AddRange(stack);
642
1071
 
643
- foreach (object transformer in interceptorStack)
1072
+ foreach (object transformer in interceptorObjects)
644
1073
  {
645
1074
  if (transformer is not TargetedInterceptor<T> typedTransformer)
646
1075
  {
@@ -657,38 +1086,34 @@
657
1086
  finally
658
1087
  {
659
1088
  _interceptors.Push(interceptorStack);
660
- _interceptorKeys.Push(interceptorKeys);
1089
+ _innerInterceptorsStack.Push(interceptorObjects);
661
1090
  }
662
1091
 
663
1092
  return true;
664
1093
  }
665
1094
 
666
- private bool RunBroadcastInterceptors<T>(Type type, ref T message, ref InstanceId source) where T : IBroadcastMessage
1095
+ private bool RunBroadcastInterceptors<T>(Type type, ref T message, ref InstanceId source)
1096
+ where T : IBroadcastMessage
667
1097
  {
668
- if (!TryGetInterceptorCaches(
1098
+ if (
1099
+ !TryGetInterceptorCaches(
669
1100
  type,
670
- out SortedDictionary<int, List<object>> interceptors,
671
- out List<int> interceptorKeys,
672
- out List<object> interceptorStack))
1101
+ out List<List<object>> interceptorStack,
1102
+ out List<object> interceptorObjects
1103
+ )
1104
+ )
673
1105
  {
674
1106
  return true;
675
1107
  }
676
1108
 
677
1109
  try
678
1110
  {
679
- interceptorKeys.Clear();
680
- interceptorKeys.AddRange(interceptors.Keys);
681
- foreach (int priority in interceptorKeys)
1111
+ foreach (List<object> stack in interceptorStack)
682
1112
  {
683
- if (!interceptors.TryGetValue(priority, out List<object> untypedInterceptors) || untypedInterceptors.Count <= 0)
684
- {
685
- continue;
686
- }
1113
+ interceptorObjects.Clear();
1114
+ interceptorObjects.AddRange(stack);
687
1115
 
688
- interceptorStack.Clear();
689
- interceptorStack.AddRange(untypedInterceptors);
690
-
691
- foreach (object transformer in interceptorStack)
1116
+ foreach (object transformer in interceptorObjects)
692
1117
  {
693
1118
  if (transformer is not BroadcastInterceptor<T> typedTransformer)
694
1119
  {
@@ -705,84 +1130,172 @@
705
1130
  finally
706
1131
  {
707
1132
  _interceptors.Push(interceptorStack);
708
- _interceptorKeys.Push(interceptorKeys);
1133
+ _innerInterceptorsStack.Push(interceptorObjects);
709
1134
  }
710
1135
 
711
1136
  return true;
712
1137
  }
713
1138
 
714
- private bool InternalUntargetedBroadcast<TMessage>(ref TMessage message, Type type) where TMessage : IMessage
1139
+ private bool InternalUntargetedBroadcast<TMessage>(ref TMessage message, Type type)
1140
+ where TMessage : IMessage
715
1141
  {
716
- if (!_sinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers) || handlers.Count <= 0)
1142
+ if (
1143
+ !_sinks.TryGetValue(
1144
+ type,
1145
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
1146
+ )
1147
+ || sortedHandlers.Count <= 0
1148
+ )
717
1149
  {
718
1150
  return false;
719
1151
  }
720
1152
 
721
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
1153
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
1154
+ GetOrAddMessageHandlerStack(sortedHandlers);
722
1155
  try
723
1156
  {
724
- foreach (MessageHandler handler in messageHandlers)
1157
+ foreach (KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList)
725
1158
  {
726
- handler.HandleUntargetedMessage(ref message, this);
1159
+ int priority = handlers.Key;
1160
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1161
+ handlers.Value.Keys
1162
+ );
1163
+ try
1164
+ {
1165
+ foreach (MessageHandler handler in messageHandlers)
1166
+ {
1167
+ handler.HandleUntargetedMessage(ref message, this, priority);
1168
+ }
1169
+ }
1170
+ finally
1171
+ {
1172
+ _messageHandlers.Push(messageHandlers);
1173
+ }
727
1174
  }
728
1175
  }
729
1176
  finally
730
1177
  {
731
- _messageHandlers.Push(messageHandlers);
1178
+ _sortedHandlers.Push(handlerList);
732
1179
  }
733
1180
 
734
1181
  return true;
735
1182
  }
736
1183
 
737
1184
  private bool InternalTargetedWithoutTargetingBroadcast<TMessage>(
738
- ref InstanceId target, ref TMessage message, Type type) where TMessage : ITargetedMessage
1185
+ ref InstanceId target,
1186
+ ref TMessage message,
1187
+ Type type
1188
+ )
1189
+ where TMessage : ITargetedMessage
739
1190
  {
740
- if (!_sinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers) || handlers.Count <= 0)
1191
+ if (
1192
+ !_sinks.TryGetValue(
1193
+ type,
1194
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
1195
+ )
1196
+ || sortedHandlers.Count <= 0
1197
+ )
741
1198
  {
742
1199
  return false;
743
1200
  }
744
1201
 
745
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
1202
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
1203
+ GetOrAddMessageHandlerStack(sortedHandlers);
746
1204
  try
747
1205
  {
748
- foreach (MessageHandler handler in messageHandlers)
1206
+ foreach (KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList)
749
1207
  {
750
- handler.HandleTargetedWithoutTargeting(ref target, ref message, this);
1208
+ int priority = handlers.Key;
1209
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1210
+ handlers.Value.Keys
1211
+ );
1212
+ try
1213
+ {
1214
+ foreach (MessageHandler handler in messageHandlers)
1215
+ {
1216
+ handler.HandleTargetedWithoutTargeting(
1217
+ ref target,
1218
+ ref message,
1219
+ this,
1220
+ priority
1221
+ );
1222
+ }
1223
+ }
1224
+ finally
1225
+ {
1226
+ _messageHandlers.Push(messageHandlers);
1227
+ }
751
1228
  }
752
1229
  }
753
1230
  finally
754
1231
  {
755
- _messageHandlers.Push(messageHandlers);
1232
+ _sortedHandlers.Push(handlerList);
756
1233
  }
757
1234
 
758
1235
  return true;
759
1236
  }
760
1237
 
761
1238
  private bool InternalBroadcastWithoutSource<TMessage>(
762
- ref InstanceId target, ref TMessage message, Type type) where TMessage : IBroadcastMessage
1239
+ ref InstanceId target,
1240
+ ref TMessage message,
1241
+ Type type
1242
+ )
1243
+ where TMessage : IBroadcastMessage
763
1244
  {
764
- if (!_sinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers) || handlers.Count <= 0)
1245
+ if (
1246
+ !_sinks.TryGetValue(
1247
+ type,
1248
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> sortedHandlers
1249
+ )
1250
+ || sortedHandlers.Count <= 0
1251
+ )
765
1252
  {
766
1253
  return false;
767
1254
  }
768
1255
 
769
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(handlers.Keys);
1256
+ List<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlerList =
1257
+ GetOrAddMessageHandlerStack(sortedHandlers);
770
1258
  try
771
1259
  {
772
- foreach (MessageHandler handler in messageHandlers)
1260
+ foreach (KeyValuePair<int, Dictionary<MessageHandler, int>> handlers in handlerList)
773
1261
  {
774
- handler.HandleSourcedBroadcastWithoutSource(ref target, ref message, this);
1262
+ int priority = handlers.Key;
1263
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1264
+ handlers.Value.Keys
1265
+ );
1266
+ try
1267
+ {
1268
+ foreach (MessageHandler handler in messageHandlers)
1269
+ {
1270
+ handler.HandleSourcedBroadcastWithoutSource(
1271
+ ref target,
1272
+ ref message,
1273
+ this,
1274
+ priority
1275
+ );
1276
+ }
1277
+ }
1278
+ finally
1279
+ {
1280
+ _messageHandlers.Push(messageHandlers);
1281
+ }
775
1282
  }
776
1283
  }
777
1284
  finally
778
1285
  {
779
- _messageHandlers.Push(messageHandlers);
1286
+ _sortedHandlers.Push(handlerList);
780
1287
  }
781
1288
 
782
1289
  return true;
783
1290
  }
784
1291
 
785
- private Action InternalRegisterUntargeted<T>(MessageHandler messageHandler, Dictionary<Type, Dictionary<MessageHandler, int>> sinks, RegistrationMethod registrationMethod) where T : IMessage
1292
+ private Action InternalRegisterUntargeted<T>(
1293
+ MessageHandler messageHandler,
1294
+ Dictionary<Type, SortedDictionary<int, Dictionary<MessageHandler, int>>> sinks,
1295
+ RegistrationMethod registrationMethod,
1296
+ int priority
1297
+ )
1298
+ where T : IMessage
786
1299
  {
787
1300
  if (messageHandler == null)
788
1301
  {
@@ -792,55 +1305,101 @@
792
1305
  InstanceId handlerOwnerId = messageHandler.owner;
793
1306
  Type type = typeof(T);
794
1307
 
795
- if (!sinks.TryGetValue(type, out Dictionary<MessageHandler, int> handlers))
1308
+ if (
1309
+ !sinks.TryGetValue(
1310
+ type,
1311
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> handlers
1312
+ )
1313
+ )
796
1314
  {
797
- handlers = new Dictionary<MessageHandler, int>();
1315
+ handlers = new SortedDictionary<int, Dictionary<MessageHandler, int>>();
798
1316
  sinks[type] = handlers;
799
1317
  }
800
1318
 
801
- if (!handlers.TryGetValue(messageHandler, out int count))
1319
+ if (!handlers.TryGetValue(priority, out Dictionary<MessageHandler, int> handler))
802
1320
  {
803
- count = 0;
1321
+ handler = new Dictionary<MessageHandler, int>();
1322
+ handlers[priority] = handler;
804
1323
  }
805
1324
 
806
- handlers[messageHandler] = count + 1;
807
- _log.Log(new MessagingRegistration(handlerOwnerId, type, RegistrationType.Register, registrationMethod));
1325
+ int count = handler.GetValueOrDefault(messageHandler, 0);
1326
+
1327
+ handler[messageHandler] = count + 1;
1328
+ _log.Log(
1329
+ new MessagingRegistration(
1330
+ handlerOwnerId,
1331
+ type,
1332
+ RegistrationType.Register,
1333
+ registrationMethod
1334
+ )
1335
+ );
808
1336
 
809
1337
  return () =>
810
1338
  {
811
- _log.Log(new MessagingRegistration(handlerOwnerId, type, RegistrationType.Deregister, registrationMethod));
812
- if (!sinks.TryGetValue(type, out handlers) || !handlers.TryGetValue(messageHandler, out count))
1339
+ _log.Log(
1340
+ new MessagingRegistration(
1341
+ handlerOwnerId,
1342
+ type,
1343
+ RegistrationType.Deregister,
1344
+ registrationMethod
1345
+ )
1346
+ );
1347
+ if (
1348
+ !sinks.TryGetValue(type, out handlers)
1349
+ || !handlers.TryGetValue(priority, out handler)
1350
+ || !handler.TryGetValue(messageHandler, out count)
1351
+ )
813
1352
  {
814
- MessagingDebug.Log(LogLevel.Error,
1353
+ MessagingDebug.Log(
1354
+ LogLevel.Error,
815
1355
  "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
816
- type, messageHandler);
1356
+ type,
1357
+ messageHandler
1358
+ );
817
1359
  return;
818
1360
  }
819
1361
 
820
1362
  if (count <= 1)
821
1363
  {
822
- bool complete = handlers.Remove(messageHandler);
823
- bool trulyComplete = true;
1364
+ bool complete = handler.Remove(messageHandler);
1365
+
1366
+ if (handler.Count <= 0)
1367
+ {
1368
+ _ = handlers.Remove(priority);
1369
+ }
1370
+
824
1371
  if (handlers.Count <= 0)
825
1372
  {
826
- trulyComplete = sinks.Remove(type);
1373
+ _ = sinks.Remove(type);
827
1374
  }
828
1375
 
829
- if (!complete || !trulyComplete)
1376
+ if (!complete)
830
1377
  {
831
- MessagingDebug.Log(LogLevel.Error,
1378
+ MessagingDebug.Log(
1379
+ LogLevel.Error,
832
1380
  "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
833
- type, messageHandler);
1381
+ type,
1382
+ messageHandler
1383
+ );
834
1384
  }
835
1385
  }
836
1386
  else
837
1387
  {
838
- handlers[messageHandler] = count - 1;
1388
+ handler[messageHandler] = count - 1;
839
1389
  }
840
1390
  };
841
1391
  }
842
1392
 
843
- private Action InternalRegisterWithContext<T>(InstanceId context, MessageHandler messageHandler, Dictionary<Type, Dictionary<InstanceId, Dictionary<MessageHandler, int>>> sinks, RegistrationMethod registrationMethod)
1393
+ private Action InternalRegisterWithContext<T>(
1394
+ InstanceId context,
1395
+ MessageHandler messageHandler,
1396
+ Dictionary<
1397
+ Type,
1398
+ Dictionary<InstanceId, SortedDictionary<int, Dictionary<MessageHandler, int>>>
1399
+ > sinks,
1400
+ RegistrationMethod registrationMethod,
1401
+ int priority
1402
+ )
844
1403
  {
845
1404
  if (messageHandler == null)
846
1405
  {
@@ -848,40 +1407,87 @@
848
1407
  }
849
1408
 
850
1409
  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>>();
1410
+ if (
1411
+ !sinks.TryGetValue(
1412
+ type,
1413
+ out Dictionary<
1414
+ InstanceId,
1415
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
1416
+ > broadcastHandlers
1417
+ )
1418
+ )
1419
+ {
1420
+ broadcastHandlers =
1421
+ new Dictionary<
1422
+ InstanceId,
1423
+ SortedDictionary<int, Dictionary<MessageHandler, int>>
1424
+ >();
854
1425
  sinks[type] = broadcastHandlers;
855
1426
  }
856
1427
 
857
- if (!broadcastHandlers.TryGetValue(context, out Dictionary<MessageHandler, int> handlers))
1428
+ if (
1429
+ !broadcastHandlers.TryGetValue(
1430
+ context,
1431
+ out SortedDictionary<int, Dictionary<MessageHandler, int>> handlers
1432
+ )
1433
+ )
858
1434
  {
859
- handlers = new Dictionary<MessageHandler, int>();
1435
+ handlers = new SortedDictionary<int, Dictionary<MessageHandler, int>>();
860
1436
  broadcastHandlers[context] = handlers;
861
1437
  }
862
1438
 
863
- if (!handlers.TryGetValue(messageHandler, out int count))
1439
+ if (!handlers.TryGetValue(priority, out Dictionary<MessageHandler, int> handler))
864
1440
  {
865
- count = 0;
1441
+ handler = new Dictionary<MessageHandler, int>();
1442
+ handlers[priority] = handler;
866
1443
  }
867
1444
 
868
- handlers[messageHandler] = count + 1;
869
- _log.Log(new MessagingRegistration(context, type, RegistrationType.Register, registrationMethod));
1445
+ int count = handler.GetValueOrDefault(messageHandler, 0);
1446
+
1447
+ handler[messageHandler] = count + 1;
1448
+ _log.Log(
1449
+ new MessagingRegistration(
1450
+ context,
1451
+ type,
1452
+ RegistrationType.Register,
1453
+ registrationMethod
1454
+ )
1455
+ );
870
1456
 
871
1457
  return () =>
872
1458
  {
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))
1459
+ _log.Log(
1460
+ new MessagingRegistration(
1461
+ context,
1462
+ type,
1463
+ RegistrationType.Deregister,
1464
+ registrationMethod
1465
+ )
1466
+ );
1467
+ if (
1468
+ !sinks.TryGetValue(type, out broadcastHandlers)
1469
+ || !broadcastHandlers.TryGetValue(context, out handlers)
1470
+ || !handlers.TryGetValue(priority, out handler)
1471
+ || !handler.TryGetValue(messageHandler, out count)
1472
+ )
875
1473
  {
876
- MessagingDebug.Log(LogLevel.Error,
1474
+ MessagingDebug.Log(
1475
+ LogLevel.Error,
877
1476
  "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
878
- type, messageHandler);
1477
+ type,
1478
+ messageHandler
1479
+ );
879
1480
  return;
880
1481
  }
881
1482
 
882
1483
  if (count <= 1)
883
1484
  {
884
- bool complete = handlers.Remove(messageHandler);
1485
+ bool complete = handler.Remove(messageHandler);
1486
+ if (handler.Count <= 0)
1487
+ {
1488
+ _ = handlers.Remove(priority);
1489
+ }
1490
+
885
1491
  if (handlers.Count <= 0)
886
1492
  {
887
1493
  _ = broadcastHandlers.Remove(context);
@@ -894,19 +1500,44 @@
894
1500
 
895
1501
  if (!complete)
896
1502
  {
897
- MessagingDebug.Log(LogLevel.Error,
1503
+ MessagingDebug.Log(
1504
+ LogLevel.Error,
898
1505
  "Received over-deregistration of {0} for {1}. Check to make sure you're not calling (de)registration multiple times.",
899
- type, messageHandler);
1506
+ type,
1507
+ messageHandler
1508
+ );
900
1509
  }
901
1510
  }
902
1511
  else
903
1512
  {
904
- handlers[messageHandler] = count - 1;
1513
+ handler[messageHandler] = count - 1;
905
1514
  }
906
1515
  };
907
1516
  }
908
1517
 
909
- private List<MessageHandler> GetOrAddMessageHandlerStack(IEnumerable<MessageHandler> handlers)
1518
+ private List<
1519
+ KeyValuePair<int, Dictionary<MessageHandler, int>>
1520
+ > GetOrAddMessageHandlerStack(
1521
+ IEnumerable<KeyValuePair<int, Dictionary<MessageHandler, int>>> handlers
1522
+ )
1523
+ {
1524
+ if (
1525
+ !_sortedHandlers.TryPop(
1526
+ out List<KeyValuePair<int, Dictionary<MessageHandler, int>>> messageHandlers
1527
+ )
1528
+ )
1529
+ {
1530
+ return new List<KeyValuePair<int, Dictionary<MessageHandler, int>>>(handlers);
1531
+ }
1532
+
1533
+ messageHandlers.Clear();
1534
+ messageHandlers.AddRange(handlers);
1535
+ return messageHandlers;
1536
+ }
1537
+
1538
+ private List<MessageHandler> GetOrAddMessageHandlerStack(
1539
+ IEnumerable<MessageHandler> handlers
1540
+ )
910
1541
  {
911
1542
  if (!_messageHandlers.TryPop(out List<MessageHandler> messageHandlers))
912
1543
  {
@@ -919,40 +1550,73 @@
919
1550
  }
920
1551
 
921
1552
  // 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
1553
+ private static Action<IUntargetedMessage> UntargetedBroadcastReflectionHelper<T>(
1554
+ IMessageBus messageBus,
1555
+ MethodInfo methodInfo
1556
+ )
1557
+ where T : IUntargetedMessage
923
1558
  {
924
- FastUntargetedBroadcast<T> untargetedBroadcast = (FastUntargetedBroadcast<T>) Delegate.CreateDelegate(typeof(FastUntargetedBroadcast<T>), messageBus, methodInfo);
1559
+ FastUntargetedBroadcast<T> untargetedBroadcast =
1560
+ (FastUntargetedBroadcast<T>)
1561
+ Delegate.CreateDelegate(
1562
+ typeof(FastUntargetedBroadcast<T>),
1563
+ messageBus,
1564
+ methodInfo
1565
+ );
1566
+
1567
+ return UntypedBroadcast;
1568
+
925
1569
  void UntypedBroadcast(IUntargetedMessage message)
926
1570
  {
927
- T typedMessage = (T) message;
1571
+ T typedMessage = (T)message;
928
1572
  untargetedBroadcast(ref typedMessage);
929
1573
  }
930
-
931
- return UntypedBroadcast;
932
1574
  }
933
1575
 
934
- private static Action<InstanceId, ITargetedMessage> TargetedBroadcastReflectionHelper<T>(IMessageBus messageBus, MethodInfo methodInfo) where T : ITargetedMessage
1576
+ private static Action<InstanceId, ITargetedMessage> TargetedBroadcastReflectionHelper<T>(
1577
+ IMessageBus messageBus,
1578
+ MethodInfo methodInfo
1579
+ )
1580
+ where T : ITargetedMessage
935
1581
  {
936
- FastTargetedBroadcast<T> targetedBroadcast = (FastTargetedBroadcast<T>) Delegate.CreateDelegate(typeof(FastTargetedBroadcast<T>), messageBus, methodInfo);
1582
+ FastTargetedBroadcast<T> targetedBroadcast =
1583
+ (FastTargetedBroadcast<T>)
1584
+ Delegate.CreateDelegate(
1585
+ typeof(FastTargetedBroadcast<T>),
1586
+ messageBus,
1587
+ methodInfo
1588
+ );
1589
+
1590
+ return UntypedBroadcast;
1591
+
937
1592
  void UntypedBroadcast(InstanceId target, ITargetedMessage message)
938
1593
  {
939
- T typedMessage = (T) message;
1594
+ T typedMessage = (T)message;
940
1595
  targetedBroadcast(ref target, ref typedMessage);
941
1596
  }
942
-
943
- return UntypedBroadcast;
944
1597
  }
945
1598
 
946
- private static Action<InstanceId, IBroadcastMessage> SourcedBroadcastReflectionHelper<T>(IMessageBus messageBus, MethodInfo methodInfo) where T : IBroadcastMessage
1599
+ private static Action<InstanceId, IBroadcastMessage> SourcedBroadcastReflectionHelper<T>(
1600
+ IMessageBus messageBus,
1601
+ MethodInfo methodInfo
1602
+ )
1603
+ where T : IBroadcastMessage
947
1604
  {
948
- FastSourcedBroadcast<T> sourcedBroadcast = (FastSourcedBroadcast<T>)Delegate.CreateDelegate(typeof(FastSourcedBroadcast<T>), messageBus, methodInfo);
1605
+ FastSourcedBroadcast<T> sourcedBroadcast =
1606
+ (FastSourcedBroadcast<T>)
1607
+ Delegate.CreateDelegate(
1608
+ typeof(FastSourcedBroadcast<T>),
1609
+ messageBus,
1610
+ methodInfo
1611
+ );
1612
+
1613
+ return UntypedBroadcast;
1614
+
949
1615
  void UntypedBroadcast(InstanceId target, IBroadcastMessage message)
950
1616
  {
951
1617
  T typedMessage = (T)message;
952
1618
  sourcedBroadcast(ref target, ref typedMessage);
953
1619
  }
954
-
955
- return UntypedBroadcast;
956
1620
  }
957
1621
  }
958
1622
  }