com.wallstop-studios.dxmessaging 2.0.0-rc15 → 2.0.0-rc17

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.
Files changed (33) hide show
  1. package/.config/dotnet-tools.json +10 -0
  2. package/.editorconfig +184 -0
  3. package/.pre-commit-config.yaml +22 -0
  4. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
  5. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.pdb.meta +7 -0
  6. package/Editor/SetupCscRsp.cs +24 -7
  7. package/README.md +7 -17
  8. package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs +5 -1
  9. package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs +5 -1
  10. package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs +5 -1
  11. package/Runtime/Core/IMessage.cs +13 -0
  12. package/Runtime/Core/InstanceId.cs +6 -16
  13. package/Runtime/Core/MessageBus/MessageBus.cs +1751 -828
  14. package/Runtime/Core/MessageHandler.cs +408 -292
  15. package/Runtime/Unity/MessageAwareComponent.cs +0 -1
  16. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +445 -0
  17. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs.meta +3 -0
  18. package/Tests/Runtime/Benchmarks/PerformanceTests.cs +41 -26
  19. package/Tests/Runtime/Scripts/Components/GenericMessageAwareComponent.cs +19 -0
  20. package/Tests/Runtime/Scripts/Components/GenericMessageAwareComponent.cs.meta +3 -0
  21. package/Tests/Runtime/Scripts/Messages/GenericUntargetedMessage.cs +7 -0
  22. package/Tests/Runtime/Scripts/Messages/GenericUntargetedMessage.cs.meta +3 -0
  23. package/package.json +2 -2
  24. package/Runtime/Core/Attributes/DxAutoMessageTypeAttribute.cs +0 -7
  25. package/Runtime/Core/Attributes/DxAutoMessageTypeAttribute.cs.meta +0 -3
  26. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoMessageTypeGenerator.cs +0 -92
  27. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoMessageTypeGenerator.cs.meta +0 -11
  28. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxBroadcastMessageGenerator.cs +0 -94
  29. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxBroadcastMessageGenerator.cs.meta +0 -3
  30. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxTargetedMessageGenerator.cs +0 -94
  31. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxTargetedMessageGenerator.cs.meta +0 -3
  32. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxUntargetedMessageGenerator.cs +0 -94
  33. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxUntargetedMessageGenerator.cs.meta +0 -3
@@ -11,17 +11,28 @@
11
11
  /// </summary>
12
12
  public sealed class MessageBus : IMessageBus
13
13
  {
14
+ private sealed class HandlerCache<TKey, TValue>
15
+ {
16
+ public readonly SortedList<TKey, TValue> handlers = new();
17
+ public readonly List<KeyValuePair<TKey, TValue>> cache = new();
18
+ public long version;
19
+ public long lastSeenVersion = -1;
20
+ }
21
+
22
+ private sealed class HandlerCache
23
+ {
24
+ public readonly Dictionary<MessageHandler, int> handlers = new();
25
+ public readonly List<MessageHandler> cache = new();
26
+ public long version;
27
+ public long lastSeenVersion = -1;
28
+ }
29
+
14
30
  public int RegisteredTargeted
15
31
  {
16
32
  get
17
33
  {
18
34
  int count = 0;
19
- foreach (
20
- KeyValuePair<
21
- Type,
22
- Dictionary<InstanceId, SortedList<int, SortedList<MessageHandler, int>>>
23
- > entry in _targetedSinks
24
- )
35
+ foreach (var entry in _targetedSinks)
25
36
  {
26
37
  count += entry.Value.Count;
27
38
  }
@@ -51,7 +62,7 @@
51
62
  int count = 0;
52
63
  foreach (var entry in _sinks)
53
64
  {
54
- count += entry.Value.Count;
65
+ count += entry.Value.handlers.Count;
55
66
  }
56
67
 
57
68
  return count;
@@ -75,54 +86,44 @@
75
86
 
76
87
  public RegistrationLog Log => _log;
77
88
 
78
- private readonly Dictionary<Type, SortedList<int, SortedList<MessageHandler, int>>> _sinks =
79
- new();
89
+ private readonly Dictionary<Type, HandlerCache<int, HandlerCache>> _sinks = new();
80
90
  private readonly Dictionary<
81
91
  Type,
82
- Dictionary<InstanceId, SortedList<int, SortedList<MessageHandler, int>>>
92
+ Dictionary<InstanceId, HandlerCache<int, HandlerCache>>
83
93
  > _targetedSinks = new();
84
-
85
94
  private readonly Dictionary<
86
95
  Type,
87
- Dictionary<InstanceId, SortedList<int, SortedList<MessageHandler, int>>>
96
+ Dictionary<InstanceId, HandlerCache<int, HandlerCache>>
88
97
  > _broadcastSinks = new();
98
+ private readonly Dictionary<Type, HandlerCache<int, HandlerCache>> _postProcessingSinks =
99
+ new();
89
100
  private readonly Dictionary<
90
101
  Type,
91
- SortedList<int, SortedList<MessageHandler, int>>
92
- > _postProcessingSinks = new();
93
- private readonly Dictionary<
94
- Type,
95
- Dictionary<InstanceId, SortedList<int, SortedList<MessageHandler, int>>>
102
+ Dictionary<InstanceId, HandlerCache<int, HandlerCache>>
96
103
  > _postProcessingTargetedSinks = new();
97
104
  private readonly Dictionary<
98
105
  Type,
99
- Dictionary<InstanceId, SortedList<int, SortedList<MessageHandler, int>>>
106
+ Dictionary<InstanceId, HandlerCache<int, HandlerCache>>
100
107
  > _postProcessingBroadcastSinks = new();
101
108
  private readonly Dictionary<
102
109
  Type,
103
- SortedList<int, SortedList<MessageHandler, int>>
110
+ HandlerCache<int, HandlerCache>
104
111
  > _postProcessingTargetedWithoutTargetingSinks = new();
105
112
  private readonly Dictionary<
106
113
  Type,
107
- SortedList<int, SortedList<MessageHandler, int>>
114
+ HandlerCache<int, HandlerCache>
108
115
  > _postProcessingBroadcastWithoutSourceSinks = new();
109
- private readonly SortedList<MessageHandler, int> _globalSinks = new();
110
- private readonly Dictionary<Type, SortedList<int, List<object>>> _interceptsByType = new();
116
+ private readonly HandlerCache _globalSinks = new();
117
+ private readonly Dictionary<Type, HandlerCache<int, List<object>>> _interceptsByType =
118
+ new();
111
119
  private readonly Dictionary<object, Dictionary<int, int>> _uniqueInterceptorsAndPriorities =
112
120
  new();
113
121
 
114
122
  private readonly Dictionary<Type, object> _broadcastMethodsByType = new();
123
+ private readonly Stack<List<object>> _innerInterceptorsStack = new();
115
124
 
116
125
  private readonly RegistrationLog _log = new();
117
126
 
118
- // These are used so we aren't allocating as much every time we send messages
119
- private readonly Stack<List<MessageHandler>> _messageHandlers = new();
120
- private readonly Stack<
121
- List<KeyValuePair<int, SortedList<MessageHandler, int>>>
122
- > _sortedHandlers = new();
123
- private readonly Stack<List<List<object>>> _interceptors = new();
124
- private readonly Stack<List<object>> _innerInterceptorsStack = new();
125
-
126
127
  public Action RegisterUntargeted<T>(MessageHandler messageHandler, int priority = 0)
127
128
  where T : IUntargetedMessage
128
129
  {
@@ -196,10 +197,11 @@
196
197
 
197
198
  public Action RegisterGlobalAcceptAll(MessageHandler messageHandler)
198
199
  {
199
- int count = _globalSinks.GetValueOrDefault(messageHandler, 0);
200
+ _globalSinks.version++;
201
+ int count = _globalSinks.handlers.GetValueOrDefault(messageHandler, 0);
200
202
 
201
203
  Type type = typeof(IMessage);
202
- _globalSinks[messageHandler] = count + 1;
204
+ _globalSinks.handlers[messageHandler] = count + 1;
203
205
  _log.Log(
204
206
  new MessagingRegistration(
205
207
  messageHandler.owner,
@@ -211,6 +213,7 @@
211
213
 
212
214
  return () =>
213
215
  {
216
+ _globalSinks.version++;
214
217
  _log.Log(
215
218
  new MessagingRegistration(
216
219
  messageHandler.owner,
@@ -219,7 +222,7 @@
219
222
  RegistrationMethod.GlobalAcceptAll
220
223
  )
221
224
  );
222
- if (!_globalSinks.TryGetValue(messageHandler, out count))
225
+ if (!_globalSinks.handlers.TryGetValue(messageHandler, out count))
223
226
  {
224
227
  if (MessagingDebug.enabled)
225
228
  {
@@ -235,11 +238,11 @@
235
238
 
236
239
  if (count <= 1)
237
240
  {
238
- _ = _globalSinks.Remove(messageHandler);
241
+ _ = _globalSinks.handlers.Remove(messageHandler);
239
242
  }
240
243
  else
241
244
  {
242
- _globalSinks[messageHandler] = count - 1;
245
+ _globalSinks.handlers[messageHandler] = count - 1;
243
246
  }
244
247
  };
245
248
  }
@@ -352,18 +355,24 @@
352
355
  if (
353
356
  !_interceptsByType.TryGetValue(
354
357
  type,
355
- out SortedList<int, List<object>> prioritizedInterceptors
358
+ out HandlerCache<int, List<object>> prioritizedInterceptors
356
359
  )
357
360
  )
358
361
  {
359
- prioritizedInterceptors = new SortedList<int, List<object>>();
362
+ prioritizedInterceptors = new HandlerCache<int, List<object>>();
360
363
  _interceptsByType[type] = prioritizedInterceptors;
361
364
  }
362
365
 
363
- if (!prioritizedInterceptors.TryGetValue(priority, out List<object> interceptors))
366
+ if (
367
+ !prioritizedInterceptors.handlers.TryGetValue(
368
+ priority,
369
+ out List<object> interceptors
370
+ )
371
+ )
364
372
  {
373
+ prioritizedInterceptors.version++;
365
374
  interceptors = new List<object>();
366
- prioritizedInterceptors[priority] = interceptors;
375
+ prioritizedInterceptors.handlers[priority] = interceptors;
367
376
  }
368
377
 
369
378
  if (
@@ -420,7 +429,7 @@
420
429
  }
421
430
  }
422
431
 
423
- if (priorityCount.Count <= 0)
432
+ if (priorityCount.Count == 0)
424
433
  {
425
434
  _uniqueInterceptorsAndPriorities.Remove(interceptor);
426
435
  }
@@ -437,12 +446,15 @@
437
446
  bool complete = false;
438
447
  if (removed)
439
448
  {
440
- if (
441
- _interceptsByType.TryGetValue(type, out prioritizedInterceptors)
442
- && prioritizedInterceptors.TryGetValue(priority, out interceptors)
443
- )
449
+ if (_interceptsByType.TryGetValue(type, out prioritizedInterceptors))
444
450
  {
445
- complete = interceptors.Remove(interceptor);
451
+ prioritizedInterceptors.version++;
452
+ if (
453
+ prioritizedInterceptors.handlers.TryGetValue(priority, out interceptors)
454
+ )
455
+ {
456
+ complete = interceptors.Remove(interceptor);
457
+ }
446
458
  }
447
459
 
448
460
  if (!complete && MessagingDebug.enabled)
@@ -493,7 +505,7 @@
493
505
  return;
494
506
  }
495
507
 
496
- if (0 < _globalSinks.Count)
508
+ if (0 < _globalSinks.handlers.Count)
497
509
  {
498
510
  IUntargetedMessage untargetedMessage = typedMessage;
499
511
  BroadcastGlobalUntargeted(ref untargetedMessage);
@@ -504,36 +516,73 @@
504
516
  if (
505
517
  _postProcessingSinks.TryGetValue(
506
518
  type,
507
- out SortedList<int, SortedList<MessageHandler, int>> sortedHandlers
519
+ out HandlerCache<int, HandlerCache> sortedHandlers
508
520
  )
509
- && 0 < sortedHandlers.Count
521
+ && 0 < sortedHandlers.handlers.Count
510
522
  )
511
523
  {
512
- foundAnyHandlers = true;
513
- if (sortedHandlers.Count == 1)
514
- {
515
- RunUntargetedPostProcessing(
516
- ref typedMessage,
517
- sortedHandlers.Keys[0],
518
- sortedHandlers.Values[0]
519
- );
520
- }
521
- else
524
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
525
+ sortedHandlers
526
+ );
527
+ switch (handlerList.Count)
522
528
  {
523
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
524
- GetOrAddMessageHandlerStack(sortedHandlers);
525
- try
529
+ case 1:
526
530
  {
527
- foreach (
528
- KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList
529
- )
531
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
532
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
533
+ break;
534
+ }
535
+ case 2:
536
+ {
537
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
538
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
539
+ entry = handlerList[1];
540
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
541
+ break;
542
+ }
543
+ case 3:
544
+ {
545
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
546
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
547
+ entry = handlerList[1];
548
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
549
+ entry = handlerList[2];
550
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
551
+ break;
552
+ }
553
+ case 4:
554
+ {
555
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
556
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
557
+ entry = handlerList[1];
558
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
559
+ entry = handlerList[2];
560
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
561
+ entry = handlerList[3];
562
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
563
+ break;
564
+ }
565
+ case 5:
566
+ {
567
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
568
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
569
+ entry = handlerList[1];
570
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
571
+ entry = handlerList[2];
572
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
573
+ entry = handlerList[3];
574
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
575
+ entry = handlerList[4];
576
+ RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
577
+ break;
578
+ }
579
+ default:
580
+ {
581
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
530
582
  {
531
583
  RunUntargetedPostProcessing(ref typedMessage, entry.Key, entry.Value);
532
584
  }
533
- }
534
- finally
535
- {
536
- _sortedHandlers.Push(handlerList);
585
+ break;
537
586
  }
538
587
  }
539
588
  }
@@ -551,45 +600,69 @@
551
600
  private void RunUntargetedPostProcessing<TMessage>(
552
601
  ref TMessage typedMessage,
553
602
  int priority,
554
- SortedList<MessageHandler, int> handlers
603
+ HandlerCache cache
555
604
  )
556
605
  where TMessage : IUntargetedMessage
557
606
  {
558
- switch (handlers.Count)
607
+ if (cache.handlers.Count == 0)
608
+ {
609
+ return;
610
+ }
611
+
612
+ List<MessageHandler> list = cache.cache;
613
+ if (cache.version != cache.lastSeenVersion)
559
614
  {
560
- case <= 0:
615
+ list.Clear();
616
+ Dictionary<MessageHandler, int>.KeyCollection keys = cache.handlers.Keys;
617
+ foreach (MessageHandler handler in keys)
561
618
  {
562
- return;
619
+ list.Add(handler);
563
620
  }
621
+ cache.lastSeenVersion = cache.version;
622
+ }
623
+
624
+ switch (list.Count)
625
+ {
564
626
  case 1:
565
627
  {
566
- MessageHandler handler = handlers.Keys[0];
567
- handler.HandleUntargetedPostProcessing(ref typedMessage, this, priority);
628
+ list[0].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
568
629
  return;
569
630
  }
570
- default:
631
+ case 2:
571
632
  {
572
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
573
- handlers.Keys
574
- );
575
- try
576
- {
577
- foreach (MessageHandler handler in messageHandlers)
578
- {
579
- handler.HandleUntargetedPostProcessing(
580
- ref typedMessage,
581
- this,
582
- priority
583
- );
584
- }
585
- }
586
- finally
587
- {
588
- _messageHandlers.Push(messageHandlers);
589
- }
590
-
591
- break;
633
+ list[0].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
634
+ list[1].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
635
+ return;
636
+ }
637
+ case 3:
638
+ {
639
+ list[0].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
640
+ list[1].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
641
+ list[2].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
642
+ return;
592
643
  }
644
+ case 4:
645
+ {
646
+ list[0].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
647
+ list[1].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
648
+ list[2].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
649
+ list[3].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
650
+ return;
651
+ }
652
+ case 5:
653
+ {
654
+ list[0].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
655
+ list[1].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
656
+ list[2].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
657
+ list[3].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
658
+ list[4].HandleUntargetedPostProcessing(ref typedMessage, this, priority);
659
+ return;
660
+ }
661
+ }
662
+
663
+ foreach (MessageHandler handler in cache.cache)
664
+ {
665
+ handler.HandleUntargetedPostProcessing(ref typedMessage, this, priority);
593
666
  }
594
667
  }
595
668
 
@@ -630,7 +703,7 @@
630
703
  return;
631
704
  }
632
705
 
633
- if (0 < _globalSinks.Count)
706
+ if (0 < _globalSinks.handlers.Count)
634
707
  {
635
708
  ITargetedMessage targetedMessage = typedMessage;
636
709
  BroadcastGlobalTargeted(ref target, ref targetedMessage);
@@ -640,37 +713,74 @@
640
713
  if (
641
714
  _targetedSinks.TryGetValue(
642
715
  type,
643
- out Dictionary<
644
- InstanceId,
645
- SortedList<int, SortedList<MessageHandler, int>>
646
- > targetedHandlers
716
+ out Dictionary<InstanceId, HandlerCache<int, HandlerCache>> targetedHandlers
647
717
  )
648
718
  && targetedHandlers.TryGetValue(
649
719
  target,
650
- out SortedList<int, SortedList<MessageHandler, int>> sortedHandlers
720
+ out HandlerCache<int, HandlerCache> sortedHandlers
651
721
  )
652
- && 0 < sortedHandlers.Count
722
+ && 0 < sortedHandlers.handlers.Count
653
723
  )
654
724
  {
655
725
  foundAnyHandlers = true;
656
- if (sortedHandlers.Count == 1)
657
- {
658
- RunTargetedBroadcast(
659
- ref target,
660
- ref typedMessage,
661
- sortedHandlers.Keys[0],
662
- sortedHandlers.Values[0]
663
- );
664
- }
665
- else
726
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
727
+ sortedHandlers
728
+ );
729
+ switch (handlerList.Count)
666
730
  {
667
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
668
- GetOrAddMessageHandlerStack(sortedHandlers);
669
- try
731
+ case 1:
670
732
  {
671
- foreach (
672
- KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList
673
- )
733
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
734
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
735
+ break;
736
+ }
737
+ case 2:
738
+ {
739
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
740
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
741
+ entry = handlerList[1];
742
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
743
+ break;
744
+ }
745
+ case 3:
746
+ {
747
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
748
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
749
+ entry = handlerList[1];
750
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
751
+ entry = handlerList[2];
752
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
753
+ break;
754
+ }
755
+ case 4:
756
+ {
757
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
758
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
759
+ entry = handlerList[1];
760
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
761
+ entry = handlerList[2];
762
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
763
+ entry = handlerList[3];
764
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
765
+ break;
766
+ }
767
+ case 5:
768
+ {
769
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
770
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
771
+ entry = handlerList[1];
772
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
773
+ entry = handlerList[2];
774
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
775
+ entry = handlerList[3];
776
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
777
+ entry = handlerList[4];
778
+ RunTargetedBroadcast(ref target, ref typedMessage, entry.Key, entry.Value);
779
+ break;
780
+ }
781
+ default:
782
+ {
783
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
674
784
  {
675
785
  RunTargetedBroadcast(
676
786
  ref target,
@@ -679,10 +789,8 @@
679
789
  entry.Value
680
790
  );
681
791
  }
682
- }
683
- finally
684
- {
685
- _sortedHandlers.Push(handlerList);
792
+
793
+ break;
686
794
  }
687
795
  }
688
796
  }
@@ -692,28 +800,143 @@
692
800
  if (
693
801
  _postProcessingTargetedSinks.TryGetValue(type, out targetedHandlers)
694
802
  && targetedHandlers.TryGetValue(target, out sortedHandlers)
695
- && 0 < sortedHandlers.Count
803
+ && 0 < sortedHandlers.handlers.Count
696
804
  )
697
805
  {
698
806
  foundAnyHandlers = true;
699
- if (sortedHandlers.Count == 1)
700
- {
701
- RunTargetedPostProcessing(
702
- ref target,
703
- ref typedMessage,
704
- sortedHandlers.Keys[0],
705
- sortedHandlers.Values[0]
706
- );
707
- }
708
- else
807
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
808
+ sortedHandlers
809
+ );
810
+ switch (handlerList.Count)
709
811
  {
710
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
711
- GetOrAddMessageHandlerStack(sortedHandlers);
712
- try
812
+ case 1:
713
813
  {
714
- foreach (
715
- KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList
716
- )
814
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
815
+ RunTargetedPostProcessing(
816
+ ref target,
817
+ ref typedMessage,
818
+ entry.Key,
819
+ entry.Value
820
+ );
821
+ break;
822
+ }
823
+ case 2:
824
+ {
825
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
826
+ RunTargetedPostProcessing(
827
+ ref target,
828
+ ref typedMessage,
829
+ entry.Key,
830
+ entry.Value
831
+ );
832
+ entry = handlerList[1];
833
+ RunTargetedPostProcessing(
834
+ ref target,
835
+ ref typedMessage,
836
+ entry.Key,
837
+ entry.Value
838
+ );
839
+ break;
840
+ }
841
+ case 3:
842
+ {
843
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
844
+ RunTargetedPostProcessing(
845
+ ref target,
846
+ ref typedMessage,
847
+ entry.Key,
848
+ entry.Value
849
+ );
850
+ entry = handlerList[1];
851
+ RunTargetedPostProcessing(
852
+ ref target,
853
+ ref typedMessage,
854
+ entry.Key,
855
+ entry.Value
856
+ );
857
+ entry = handlerList[2];
858
+ RunTargetedPostProcessing(
859
+ ref target,
860
+ ref typedMessage,
861
+ entry.Key,
862
+ entry.Value
863
+ );
864
+ break;
865
+ }
866
+ case 4:
867
+ {
868
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
869
+ RunTargetedPostProcessing(
870
+ ref target,
871
+ ref typedMessage,
872
+ entry.Key,
873
+ entry.Value
874
+ );
875
+ entry = handlerList[1];
876
+ RunTargetedPostProcessing(
877
+ ref target,
878
+ ref typedMessage,
879
+ entry.Key,
880
+ entry.Value
881
+ );
882
+ entry = handlerList[2];
883
+ RunTargetedPostProcessing(
884
+ ref target,
885
+ ref typedMessage,
886
+ entry.Key,
887
+ entry.Value
888
+ );
889
+ entry = handlerList[3];
890
+ RunTargetedPostProcessing(
891
+ ref target,
892
+ ref typedMessage,
893
+ entry.Key,
894
+ entry.Value
895
+ );
896
+ break;
897
+ }
898
+ case 5:
899
+ {
900
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
901
+ RunTargetedPostProcessing(
902
+ ref target,
903
+ ref typedMessage,
904
+ entry.Key,
905
+ entry.Value
906
+ );
907
+ entry = handlerList[1];
908
+ RunTargetedPostProcessing(
909
+ ref target,
910
+ ref typedMessage,
911
+ entry.Key,
912
+ entry.Value
913
+ );
914
+ entry = handlerList[2];
915
+ RunTargetedPostProcessing(
916
+ ref target,
917
+ ref typedMessage,
918
+ entry.Key,
919
+ entry.Value
920
+ );
921
+ entry = handlerList[3];
922
+ RunTargetedPostProcessing(
923
+ ref target,
924
+ ref typedMessage,
925
+ entry.Key,
926
+ entry.Value
927
+ );
928
+ entry = handlerList[4];
929
+ RunTargetedPostProcessing(
930
+ ref target,
931
+ ref typedMessage,
932
+ entry.Key,
933
+ entry.Value
934
+ );
935
+ break;
936
+ }
937
+ default:
938
+ {
939
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
717
940
  {
718
941
  RunTargetedPostProcessing(
719
942
  ref target,
@@ -722,37 +945,150 @@
722
945
  entry.Value
723
946
  );
724
947
  }
725
- }
726
- finally
727
- {
728
- _sortedHandlers.Push(handlerList);
948
+
949
+ break;
729
950
  }
730
951
  }
731
952
  }
732
953
 
733
954
  if (
734
955
  _postProcessingTargetedWithoutTargetingSinks.TryGetValue(type, out sortedHandlers)
735
- && 0 < sortedHandlers.Count
956
+ && 0 < sortedHandlers.handlers.Count
736
957
  )
737
958
  {
738
- if (sortedHandlers.Count == 1)
739
- {
740
- RunTargetedWithoutTargetingPostProcessing(
741
- ref target,
742
- ref typedMessage,
743
- sortedHandlers.Keys[0],
744
- sortedHandlers.Values[0]
745
- );
746
- }
747
- else
959
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
960
+ sortedHandlers
961
+ );
962
+ switch (handlerList.Count)
748
963
  {
749
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
750
- GetOrAddMessageHandlerStack(sortedHandlers);
751
- try
964
+ case 1:
752
965
  {
753
- foreach (
754
- KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList
755
- )
966
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
967
+ RunTargetedWithoutTargetingPostProcessing(
968
+ ref target,
969
+ ref typedMessage,
970
+ entry.Key,
971
+ entry.Value
972
+ );
973
+ break;
974
+ }
975
+ case 2:
976
+ {
977
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
978
+ RunTargetedWithoutTargetingPostProcessing(
979
+ ref target,
980
+ ref typedMessage,
981
+ entry.Key,
982
+ entry.Value
983
+ );
984
+ entry = handlerList[1];
985
+ RunTargetedWithoutTargetingPostProcessing(
986
+ ref target,
987
+ ref typedMessage,
988
+ entry.Key,
989
+ entry.Value
990
+ );
991
+ break;
992
+ }
993
+ case 3:
994
+ {
995
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
996
+ RunTargetedWithoutTargetingPostProcessing(
997
+ ref target,
998
+ ref typedMessage,
999
+ entry.Key,
1000
+ entry.Value
1001
+ );
1002
+ entry = handlerList[1];
1003
+ RunTargetedWithoutTargetingPostProcessing(
1004
+ ref target,
1005
+ ref typedMessage,
1006
+ entry.Key,
1007
+ entry.Value
1008
+ );
1009
+ entry = handlerList[2];
1010
+ RunTargetedWithoutTargetingPostProcessing(
1011
+ ref target,
1012
+ ref typedMessage,
1013
+ entry.Key,
1014
+ entry.Value
1015
+ );
1016
+ break;
1017
+ }
1018
+ case 4:
1019
+ {
1020
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1021
+ RunTargetedWithoutTargetingPostProcessing(
1022
+ ref target,
1023
+ ref typedMessage,
1024
+ entry.Key,
1025
+ entry.Value
1026
+ );
1027
+ entry = handlerList[1];
1028
+ RunTargetedWithoutTargetingPostProcessing(
1029
+ ref target,
1030
+ ref typedMessage,
1031
+ entry.Key,
1032
+ entry.Value
1033
+ );
1034
+ entry = handlerList[2];
1035
+ RunTargetedWithoutTargetingPostProcessing(
1036
+ ref target,
1037
+ ref typedMessage,
1038
+ entry.Key,
1039
+ entry.Value
1040
+ );
1041
+ entry = handlerList[3];
1042
+ RunTargetedWithoutTargetingPostProcessing(
1043
+ ref target,
1044
+ ref typedMessage,
1045
+ entry.Key,
1046
+ entry.Value
1047
+ );
1048
+ break;
1049
+ }
1050
+ case 5:
1051
+ {
1052
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1053
+ RunTargetedWithoutTargetingPostProcessing(
1054
+ ref target,
1055
+ ref typedMessage,
1056
+ entry.Key,
1057
+ entry.Value
1058
+ );
1059
+ entry = handlerList[1];
1060
+ RunTargetedWithoutTargetingPostProcessing(
1061
+ ref target,
1062
+ ref typedMessage,
1063
+ entry.Key,
1064
+ entry.Value
1065
+ );
1066
+ entry = handlerList[2];
1067
+ RunTargetedWithoutTargetingPostProcessing(
1068
+ ref target,
1069
+ ref typedMessage,
1070
+ entry.Key,
1071
+ entry.Value
1072
+ );
1073
+ entry = handlerList[3];
1074
+ RunTargetedWithoutTargetingPostProcessing(
1075
+ ref target,
1076
+ ref typedMessage,
1077
+ entry.Key,
1078
+ entry.Value
1079
+ );
1080
+ entry = handlerList[4];
1081
+ RunTargetedWithoutTargetingPostProcessing(
1082
+ ref target,
1083
+ ref typedMessage,
1084
+ entry.Key,
1085
+ entry.Value
1086
+ );
1087
+ break;
1088
+ }
1089
+ default:
1090
+ {
1091
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
756
1092
  {
757
1093
  RunTargetedWithoutTargetingPostProcessing(
758
1094
  ref target,
@@ -761,10 +1097,8 @@
761
1097
  entry.Value
762
1098
  );
763
1099
  }
764
- }
765
- finally
766
- {
767
- _sortedHandlers.Push(handlerList);
1100
+
1101
+ break;
768
1102
  }
769
1103
  }
770
1104
  }
@@ -784,146 +1118,287 @@
784
1118
  ref InstanceId target,
785
1119
  ref TMessage typedMessage,
786
1120
  int priority,
787
- SortedList<MessageHandler, int> handlers
1121
+ HandlerCache cache
788
1122
  )
789
1123
  where TMessage : ITargetedMessage
790
1124
  {
791
- switch (handlers.Count)
1125
+ if (cache.handlers.Count == 0)
1126
+ {
1127
+ return;
1128
+ }
1129
+
1130
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
1131
+ switch (messageHandlers.Count)
792
1132
  {
793
- case <= 0:
1133
+ case 1:
794
1134
  {
1135
+ messageHandlers[0]
1136
+ .HandleTargetedWithoutTargetingPostProcessing(
1137
+ ref target,
1138
+ ref typedMessage,
1139
+ this,
1140
+ priority
1141
+ );
795
1142
  return;
796
1143
  }
797
- case 1:
1144
+ case 2:
798
1145
  {
799
- MessageHandler handler = handlers.Keys[0];
800
- handler.HandleTargetedWithoutTargetingPostProcessing(
801
- ref target,
802
- ref typedMessage,
803
- this,
804
- priority
805
- );
1146
+ messageHandlers[0]
1147
+ .HandleTargetedWithoutTargetingPostProcessing(
1148
+ ref target,
1149
+ ref typedMessage,
1150
+ this,
1151
+ priority
1152
+ );
1153
+ messageHandlers[1]
1154
+ .HandleTargetedWithoutTargetingPostProcessing(
1155
+ ref target,
1156
+ ref typedMessage,
1157
+ this,
1158
+ priority
1159
+ );
806
1160
  return;
807
1161
  }
808
- default:
1162
+ case 3:
809
1163
  {
810
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
811
- handlers.Keys
812
- );
813
- try
814
- {
815
- foreach (MessageHandler handler in messageHandlers)
816
- {
817
- handler.HandleTargetedWithoutTargetingPostProcessing(
818
- ref target,
819
- ref typedMessage,
820
- this,
821
- priority
822
- );
823
- }
824
- }
825
- finally
826
- {
827
- _messageHandlers.Push(messageHandlers);
828
- }
829
-
830
- break;
1164
+ messageHandlers[0]
1165
+ .HandleTargetedWithoutTargetingPostProcessing(
1166
+ ref target,
1167
+ ref typedMessage,
1168
+ this,
1169
+ priority
1170
+ );
1171
+ messageHandlers[1]
1172
+ .HandleTargetedWithoutTargetingPostProcessing(
1173
+ ref target,
1174
+ ref typedMessage,
1175
+ this,
1176
+ priority
1177
+ );
1178
+ messageHandlers[2]
1179
+ .HandleTargetedWithoutTargetingPostProcessing(
1180
+ ref target,
1181
+ ref typedMessage,
1182
+ this,
1183
+ priority
1184
+ );
1185
+ return;
1186
+ }
1187
+ case 4:
1188
+ {
1189
+ messageHandlers[0]
1190
+ .HandleTargetedWithoutTargetingPostProcessing(
1191
+ ref target,
1192
+ ref typedMessage,
1193
+ this,
1194
+ priority
1195
+ );
1196
+ messageHandlers[1]
1197
+ .HandleTargetedWithoutTargetingPostProcessing(
1198
+ ref target,
1199
+ ref typedMessage,
1200
+ this,
1201
+ priority
1202
+ );
1203
+ messageHandlers[2]
1204
+ .HandleTargetedWithoutTargetingPostProcessing(
1205
+ ref target,
1206
+ ref typedMessage,
1207
+ this,
1208
+ priority
1209
+ );
1210
+ messageHandlers[3]
1211
+ .HandleTargetedWithoutTargetingPostProcessing(
1212
+ ref target,
1213
+ ref typedMessage,
1214
+ this,
1215
+ priority
1216
+ );
1217
+ return;
1218
+ }
1219
+ case 5:
1220
+ {
1221
+ messageHandlers[0]
1222
+ .HandleTargetedWithoutTargetingPostProcessing(
1223
+ ref target,
1224
+ ref typedMessage,
1225
+ this,
1226
+ priority
1227
+ );
1228
+ messageHandlers[1]
1229
+ .HandleTargetedWithoutTargetingPostProcessing(
1230
+ ref target,
1231
+ ref typedMessage,
1232
+ this,
1233
+ priority
1234
+ );
1235
+ messageHandlers[2]
1236
+ .HandleTargetedWithoutTargetingPostProcessing(
1237
+ ref target,
1238
+ ref typedMessage,
1239
+ this,
1240
+ priority
1241
+ );
1242
+ messageHandlers[3]
1243
+ .HandleTargetedWithoutTargetingPostProcessing(
1244
+ ref target,
1245
+ ref typedMessage,
1246
+ this,
1247
+ priority
1248
+ );
1249
+ messageHandlers[4]
1250
+ .HandleTargetedWithoutTargetingPostProcessing(
1251
+ ref target,
1252
+ ref typedMessage,
1253
+ this,
1254
+ priority
1255
+ );
1256
+ return;
831
1257
  }
832
1258
  }
1259
+
1260
+ foreach (MessageHandler handler in messageHandlers)
1261
+ {
1262
+ handler.HandleTargetedWithoutTargetingPostProcessing(
1263
+ ref target,
1264
+ ref typedMessage,
1265
+ this,
1266
+ priority
1267
+ );
1268
+ }
833
1269
  }
834
1270
 
835
1271
  private void RunTargetedPostProcessing<TMessage>(
836
1272
  ref InstanceId target,
837
1273
  ref TMessage typedMessage,
838
1274
  int priority,
839
- SortedList<MessageHandler, int> handlers
1275
+ HandlerCache cache
840
1276
  )
841
1277
  where TMessage : ITargetedMessage
842
1278
  {
843
- switch (handlers.Count)
1279
+ if (cache.handlers.Count == 0)
1280
+ {
1281
+ return;
1282
+ }
1283
+
1284
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
1285
+ switch (messageHandlers.Count)
844
1286
  {
845
- case <= 0:
1287
+ case 1:
846
1288
  {
1289
+ messageHandlers[0]
1290
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
847
1291
  return;
848
1292
  }
849
- case 1:
1293
+ case 2:
850
1294
  {
851
- MessageHandler handler = handlers.Keys[0];
852
- handler.HandleTargetedPostProcessing(
853
- ref target,
854
- ref typedMessage,
855
- this,
856
- priority
857
- );
1295
+ messageHandlers[0]
1296
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1297
+ messageHandlers[1]
1298
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
858
1299
  return;
859
1300
  }
860
- default:
1301
+ case 3:
861
1302
  {
862
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
863
- handlers.Keys
864
- );
865
- try
866
- {
867
- foreach (MessageHandler handler in messageHandlers)
868
- {
869
- handler.HandleTargetedPostProcessing(
870
- ref target,
871
- ref typedMessage,
872
- this,
873
- priority
874
- );
875
- }
876
- }
877
- finally
878
- {
879
- _messageHandlers.Push(messageHandlers);
880
- }
881
-
882
- break;
1303
+ messageHandlers[0]
1304
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1305
+ messageHandlers[1]
1306
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1307
+ messageHandlers[2]
1308
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1309
+ return;
1310
+ }
1311
+ case 4:
1312
+ {
1313
+ messageHandlers[0]
1314
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1315
+ messageHandlers[1]
1316
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1317
+ messageHandlers[2]
1318
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1319
+ messageHandlers[3]
1320
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1321
+ return;
1322
+ }
1323
+ case 5:
1324
+ {
1325
+ messageHandlers[0]
1326
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1327
+ messageHandlers[1]
1328
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1329
+ messageHandlers[2]
1330
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1331
+ messageHandlers[3]
1332
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1333
+ messageHandlers[4]
1334
+ .HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1335
+ return;
883
1336
  }
884
1337
  }
1338
+
1339
+ foreach (MessageHandler handler in messageHandlers)
1340
+ {
1341
+ handler.HandleTargetedPostProcessing(ref target, ref typedMessage, this, priority);
1342
+ }
885
1343
  }
886
1344
 
887
1345
  private void RunTargetedBroadcast<TMessage>(
888
1346
  ref InstanceId target,
889
1347
  ref TMessage typedMessage,
890
1348
  int priority,
891
- SortedList<MessageHandler, int> handlers
1349
+ HandlerCache cache
892
1350
  )
893
1351
  where TMessage : ITargetedMessage
894
1352
  {
895
- switch (handlers.Count)
1353
+ if (cache.handlers.Count == 0)
1354
+ {
1355
+ return;
1356
+ }
1357
+
1358
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
1359
+ switch (messageHandlers.Count)
896
1360
  {
897
- case <= 0:
1361
+ case 1:
898
1362
  {
1363
+ messageHandlers[0].HandleTargeted(ref target, ref typedMessage, this, priority);
899
1364
  return;
900
1365
  }
901
- case 1:
1366
+ case 2:
902
1367
  {
903
- MessageHandler handler = handlers.Keys[0];
904
- handler.HandleTargeted(ref target, ref typedMessage, this, priority);
1368
+ messageHandlers[0].HandleTargeted(ref target, ref typedMessage, this, priority);
1369
+ messageHandlers[1].HandleTargeted(ref target, ref typedMessage, this, priority);
905
1370
  return;
906
1371
  }
907
- default:
1372
+ case 3:
908
1373
  {
909
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
910
- handlers.Keys
911
- );
912
- try
913
- {
914
- foreach (MessageHandler handler in messageHandlers)
915
- {
916
- handler.HandleTargeted(ref target, ref typedMessage, this, priority);
917
- }
918
- }
919
- finally
920
- {
921
- _messageHandlers.Push(messageHandlers);
922
- }
923
-
924
- break;
1374
+ messageHandlers[0].HandleTargeted(ref target, ref typedMessage, this, priority);
1375
+ messageHandlers[1].HandleTargeted(ref target, ref typedMessage, this, priority);
1376
+ messageHandlers[2].HandleTargeted(ref target, ref typedMessage, this, priority);
1377
+ return;
1378
+ }
1379
+ case 4:
1380
+ {
1381
+ messageHandlers[0].HandleTargeted(ref target, ref typedMessage, this, priority);
1382
+ messageHandlers[1].HandleTargeted(ref target, ref typedMessage, this, priority);
1383
+ messageHandlers[2].HandleTargeted(ref target, ref typedMessage, this, priority);
1384
+ messageHandlers[3].HandleTargeted(ref target, ref typedMessage, this, priority);
1385
+ return;
1386
+ }
1387
+ case 5:
1388
+ {
1389
+ messageHandlers[0].HandleTargeted(ref target, ref typedMessage, this, priority);
1390
+ messageHandlers[1].HandleTargeted(ref target, ref typedMessage, this, priority);
1391
+ messageHandlers[2].HandleTargeted(ref target, ref typedMessage, this, priority);
1392
+ messageHandlers[3].HandleTargeted(ref target, ref typedMessage, this, priority);
1393
+ messageHandlers[4].HandleTargeted(ref target, ref typedMessage, this, priority);
1394
+ return;
925
1395
  }
926
1396
  }
1397
+
1398
+ foreach (MessageHandler handler in messageHandlers)
1399
+ {
1400
+ handler.HandleTargeted(ref target, ref typedMessage, this, priority);
1401
+ }
927
1402
  }
928
1403
 
929
1404
  public void UntypedSourcedBroadcast(InstanceId source, IBroadcastMessage typedMessage)
@@ -966,7 +1441,7 @@
966
1441
  return;
967
1442
  }
968
1443
 
969
- if (0 < _globalSinks.Count)
1444
+ if (0 < _globalSinks.handlers.Count)
970
1445
  {
971
1446
  IBroadcastMessage broadcastMessage = typedMessage;
972
1447
  BroadcastGlobalSourcedBroadcast(ref source, ref broadcastMessage);
@@ -976,44 +1451,79 @@
976
1451
  if (
977
1452
  _broadcastSinks.TryGetValue(
978
1453
  type,
979
- out Dictionary<
980
- InstanceId,
981
- SortedList<int, SortedList<MessageHandler, int>>
982
- > broadcastHandlers
1454
+ out Dictionary<InstanceId, HandlerCache<int, HandlerCache>> broadcastHandlers
983
1455
  )
984
1456
  && broadcastHandlers.TryGetValue(
985
1457
  source,
986
- out SortedList<int, SortedList<MessageHandler, int>> sortedHandlers
1458
+ out HandlerCache<int, HandlerCache> sortedHandlers
987
1459
  )
988
- && 0 < sortedHandlers.Count
1460
+ && 0 < sortedHandlers.handlers.Count
989
1461
  )
990
1462
  {
991
1463
  foundAnyHandlers = true;
992
- if (sortedHandlers.Count == 1)
993
- {
994
- RunBroadcast(
995
- ref source,
996
- ref typedMessage,
997
- sortedHandlers.Keys[0],
998
- sortedHandlers.Values[0]
999
- );
1000
- }
1001
- else
1464
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
1465
+ sortedHandlers
1466
+ );
1467
+ switch (handlerList.Count)
1002
1468
  {
1003
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
1004
- GetOrAddMessageHandlerStack(sortedHandlers);
1005
- try
1469
+ case 1:
1006
1470
  {
1007
- foreach (
1008
- KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList
1009
- )
1471
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1472
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1473
+ break;
1474
+ }
1475
+ case 2:
1476
+ {
1477
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1478
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1479
+ entry = handlerList[1];
1480
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1481
+ break;
1482
+ }
1483
+ case 3:
1484
+ {
1485
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1486
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1487
+ entry = handlerList[1];
1488
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1489
+ entry = handlerList[2];
1490
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1491
+ break;
1492
+ }
1493
+ case 4:
1494
+ {
1495
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1496
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1497
+ entry = handlerList[1];
1498
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1499
+ entry = handlerList[2];
1500
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1501
+ entry = handlerList[3];
1502
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1503
+ break;
1504
+ }
1505
+ case 5:
1506
+ {
1507
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1508
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1509
+ entry = handlerList[1];
1510
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1511
+ entry = handlerList[2];
1512
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1513
+ entry = handlerList[3];
1514
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1515
+ entry = handlerList[4];
1516
+ RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1517
+ break;
1518
+ }
1519
+ default:
1520
+ {
1521
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
1010
1522
  {
1011
1523
  RunBroadcast(ref source, ref typedMessage, entry.Key, entry.Value);
1012
1524
  }
1013
- }
1014
- finally
1015
- {
1016
- _sortedHandlers.Push(handlerList);
1525
+
1526
+ break;
1017
1527
  }
1018
1528
  }
1019
1529
  }
@@ -1023,28 +1533,143 @@
1023
1533
  if (
1024
1534
  _postProcessingBroadcastSinks.TryGetValue(type, out broadcastHandlers)
1025
1535
  && broadcastHandlers.TryGetValue(source, out sortedHandlers)
1026
- && 0 < sortedHandlers.Count
1536
+ && 0 < sortedHandlers.handlers.Count
1027
1537
  )
1028
1538
  {
1029
1539
  foundAnyHandlers = true;
1030
- if (sortedHandlers.Count == 1)
1031
- {
1032
- RunBroadcastPostProcessing(
1033
- ref source,
1034
- ref typedMessage,
1035
- sortedHandlers.Keys[0],
1036
- sortedHandlers.Values[0]
1037
- );
1038
- }
1039
- else
1540
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
1541
+ sortedHandlers
1542
+ );
1543
+ switch (handlerList.Count)
1040
1544
  {
1041
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
1042
- GetOrAddMessageHandlerStack(sortedHandlers);
1043
- try
1545
+ case 1:
1044
1546
  {
1045
- foreach (
1046
- KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList
1047
- )
1547
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1548
+ RunBroadcastPostProcessing(
1549
+ ref source,
1550
+ ref typedMessage,
1551
+ entry.Key,
1552
+ entry.Value
1553
+ );
1554
+ break;
1555
+ }
1556
+ case 2:
1557
+ {
1558
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1559
+ RunBroadcastPostProcessing(
1560
+ ref source,
1561
+ ref typedMessage,
1562
+ entry.Key,
1563
+ entry.Value
1564
+ );
1565
+ entry = handlerList[1];
1566
+ RunBroadcastPostProcessing(
1567
+ ref source,
1568
+ ref typedMessage,
1569
+ entry.Key,
1570
+ entry.Value
1571
+ );
1572
+ break;
1573
+ }
1574
+ case 3:
1575
+ {
1576
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1577
+ RunBroadcastPostProcessing(
1578
+ ref source,
1579
+ ref typedMessage,
1580
+ entry.Key,
1581
+ entry.Value
1582
+ );
1583
+ entry = handlerList[1];
1584
+ RunBroadcastPostProcessing(
1585
+ ref source,
1586
+ ref typedMessage,
1587
+ entry.Key,
1588
+ entry.Value
1589
+ );
1590
+ entry = handlerList[2];
1591
+ RunBroadcastPostProcessing(
1592
+ ref source,
1593
+ ref typedMessage,
1594
+ entry.Key,
1595
+ entry.Value
1596
+ );
1597
+ break;
1598
+ }
1599
+ case 4:
1600
+ {
1601
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1602
+ RunBroadcastPostProcessing(
1603
+ ref source,
1604
+ ref typedMessage,
1605
+ entry.Key,
1606
+ entry.Value
1607
+ );
1608
+ entry = handlerList[1];
1609
+ RunBroadcastPostProcessing(
1610
+ ref source,
1611
+ ref typedMessage,
1612
+ entry.Key,
1613
+ entry.Value
1614
+ );
1615
+ entry = handlerList[2];
1616
+ RunBroadcastPostProcessing(
1617
+ ref source,
1618
+ ref typedMessage,
1619
+ entry.Key,
1620
+ entry.Value
1621
+ );
1622
+ entry = handlerList[3];
1623
+ RunBroadcastPostProcessing(
1624
+ ref source,
1625
+ ref typedMessage,
1626
+ entry.Key,
1627
+ entry.Value
1628
+ );
1629
+ break;
1630
+ }
1631
+ case 5:
1632
+ {
1633
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
1634
+ RunBroadcastPostProcessing(
1635
+ ref source,
1636
+ ref typedMessage,
1637
+ entry.Key,
1638
+ entry.Value
1639
+ );
1640
+ entry = handlerList[1];
1641
+ RunBroadcastPostProcessing(
1642
+ ref source,
1643
+ ref typedMessage,
1644
+ entry.Key,
1645
+ entry.Value
1646
+ );
1647
+ entry = handlerList[2];
1648
+ RunBroadcastPostProcessing(
1649
+ ref source,
1650
+ ref typedMessage,
1651
+ entry.Key,
1652
+ entry.Value
1653
+ );
1654
+ entry = handlerList[3];
1655
+ RunBroadcastPostProcessing(
1656
+ ref source,
1657
+ ref typedMessage,
1658
+ entry.Key,
1659
+ entry.Value
1660
+ );
1661
+ entry = handlerList[4];
1662
+ RunBroadcastPostProcessing(
1663
+ ref source,
1664
+ ref typedMessage,
1665
+ entry.Key,
1666
+ entry.Value
1667
+ );
1668
+ break;
1669
+ }
1670
+ default:
1671
+ {
1672
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
1048
1673
  {
1049
1674
  RunBroadcastPostProcessing(
1050
1675
  ref source,
@@ -1053,51 +1678,29 @@
1053
1678
  entry.Value
1054
1679
  );
1055
1680
  }
1056
- }
1057
- finally
1058
- {
1059
- _sortedHandlers.Push(handlerList);
1681
+
1682
+ break;
1060
1683
  }
1061
1684
  }
1062
1685
  }
1063
1686
 
1064
1687
  if (
1065
1688
  _postProcessingBroadcastWithoutSourceSinks.TryGetValue(type, out sortedHandlers)
1066
- && 0 < sortedHandlers.Count
1689
+ && 0 < sortedHandlers.handlers.Count
1067
1690
  )
1068
1691
  {
1069
- if (sortedHandlers.Count == 1)
1692
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
1693
+ sortedHandlers
1694
+ );
1695
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
1070
1696
  {
1071
1697
  RunBroadcastWithoutSourcePostProcessing(
1072
1698
  ref source,
1073
1699
  ref typedMessage,
1074
- sortedHandlers.Keys[0],
1075
- sortedHandlers.Values[0]
1700
+ entry.Key,
1701
+ entry.Value
1076
1702
  );
1077
1703
  }
1078
- else
1079
- {
1080
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
1081
- GetOrAddMessageHandlerStack(sortedHandlers);
1082
- try
1083
- {
1084
- foreach (
1085
- KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList
1086
- )
1087
- {
1088
- RunBroadcastWithoutSourcePostProcessing(
1089
- ref source,
1090
- ref typedMessage,
1091
- entry.Key,
1092
- entry.Value
1093
- );
1094
- }
1095
- }
1096
- finally
1097
- {
1098
- _sortedHandlers.Push(handlerList);
1099
- }
1100
- }
1101
1704
  }
1102
1705
 
1103
1706
  if (!foundAnyHandlers && MessagingDebug.enabled)
@@ -1115,51 +1718,19 @@
1115
1718
  ref InstanceId source,
1116
1719
  ref TMessage typedMessage,
1117
1720
  int priority,
1118
- SortedList<MessageHandler, int> handlers
1721
+ HandlerCache cache
1119
1722
  )
1120
1723
  where TMessage : IBroadcastMessage
1121
1724
  {
1122
- switch (handlers.Count)
1725
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
1726
+ foreach (MessageHandler handler in messageHandlers)
1123
1727
  {
1124
- case <= 0:
1125
- {
1126
- return;
1127
- }
1128
- case 1:
1129
- {
1130
- MessageHandler handler = handlers.Keys[0];
1131
- handler.HandleSourcedBroadcastWithoutSourcePostProcessing(
1132
- ref source,
1133
- ref typedMessage,
1134
- this,
1135
- priority
1136
- );
1137
- return;
1138
- }
1139
- default:
1140
- {
1141
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1142
- handlers.Keys
1143
- );
1144
- try
1145
- {
1146
- foreach (MessageHandler handler in messageHandlers)
1147
- {
1148
- handler.HandleSourcedBroadcastWithoutSourcePostProcessing(
1149
- ref source,
1150
- ref typedMessage,
1151
- this,
1152
- priority
1153
- );
1154
- }
1155
- }
1156
- finally
1157
- {
1158
- _messageHandlers.Push(messageHandlers);
1159
- }
1160
-
1161
- break;
1162
- }
1728
+ handler.HandleSourcedBroadcastWithoutSourcePostProcessing(
1729
+ ref source,
1730
+ ref typedMessage,
1731
+ this,
1732
+ priority
1733
+ );
1163
1734
  }
1164
1735
  }
1165
1736
 
@@ -1167,171 +1738,333 @@
1167
1738
  ref InstanceId source,
1168
1739
  ref TMessage typedMessage,
1169
1740
  int priority,
1170
- SortedList<MessageHandler, int> handlers
1741
+ HandlerCache cache
1171
1742
  )
1172
1743
  where TMessage : IBroadcastMessage
1173
1744
  {
1174
- switch (handlers.Count)
1745
+ if (cache.handlers.Count == 0)
1746
+ {
1747
+ return;
1748
+ }
1749
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
1750
+ switch (messageHandlers.Count)
1175
1751
  {
1176
- case <= 0:
1752
+ case 1:
1177
1753
  {
1754
+ messageHandlers[0]
1755
+ .HandleSourcedBroadcastPostProcessing(
1756
+ ref source,
1757
+ ref typedMessage,
1758
+ this,
1759
+ priority
1760
+ );
1178
1761
  return;
1179
1762
  }
1180
- case 1:
1763
+ case 2:
1181
1764
  {
1182
- MessageHandler handler = handlers.Keys[0];
1183
- handler.HandleSourcedBroadcastPostProcessing(
1184
- ref source,
1185
- ref typedMessage,
1186
- this,
1187
- priority
1188
- );
1765
+ messageHandlers[0]
1766
+ .HandleSourcedBroadcastPostProcessing(
1767
+ ref source,
1768
+ ref typedMessage,
1769
+ this,
1770
+ priority
1771
+ );
1772
+ messageHandlers[1]
1773
+ .HandleSourcedBroadcastPostProcessing(
1774
+ ref source,
1775
+ ref typedMessage,
1776
+ this,
1777
+ priority
1778
+ );
1189
1779
  return;
1190
1780
  }
1191
- default:
1781
+ case 3:
1192
1782
  {
1193
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1194
- handlers.Keys
1195
- );
1196
- try
1197
- {
1198
- foreach (MessageHandler handler in messageHandlers)
1199
- {
1200
- handler.HandleSourcedBroadcastPostProcessing(
1201
- ref source,
1202
- ref typedMessage,
1203
- this,
1204
- priority
1205
- );
1206
- }
1207
- }
1208
- finally
1209
- {
1210
- _messageHandlers.Push(messageHandlers);
1211
- }
1212
-
1213
- break;
1783
+ messageHandlers[0]
1784
+ .HandleSourcedBroadcastPostProcessing(
1785
+ ref source,
1786
+ ref typedMessage,
1787
+ this,
1788
+ priority
1789
+ );
1790
+ messageHandlers[1]
1791
+ .HandleSourcedBroadcastPostProcessing(
1792
+ ref source,
1793
+ ref typedMessage,
1794
+ this,
1795
+ priority
1796
+ );
1797
+ messageHandlers[2]
1798
+ .HandleSourcedBroadcastPostProcessing(
1799
+ ref source,
1800
+ ref typedMessage,
1801
+ this,
1802
+ priority
1803
+ );
1804
+ return;
1805
+ }
1806
+ case 4:
1807
+ {
1808
+ messageHandlers[0]
1809
+ .HandleSourcedBroadcastPostProcessing(
1810
+ ref source,
1811
+ ref typedMessage,
1812
+ this,
1813
+ priority
1814
+ );
1815
+ messageHandlers[1]
1816
+ .HandleSourcedBroadcastPostProcessing(
1817
+ ref source,
1818
+ ref typedMessage,
1819
+ this,
1820
+ priority
1821
+ );
1822
+ messageHandlers[2]
1823
+ .HandleSourcedBroadcastPostProcessing(
1824
+ ref source,
1825
+ ref typedMessage,
1826
+ this,
1827
+ priority
1828
+ );
1829
+ messageHandlers[3]
1830
+ .HandleSourcedBroadcastPostProcessing(
1831
+ ref source,
1832
+ ref typedMessage,
1833
+ this,
1834
+ priority
1835
+ );
1836
+ return;
1837
+ }
1838
+ case 5:
1839
+ {
1840
+ messageHandlers[0]
1841
+ .HandleSourcedBroadcastPostProcessing(
1842
+ ref source,
1843
+ ref typedMessage,
1844
+ this,
1845
+ priority
1846
+ );
1847
+ messageHandlers[1]
1848
+ .HandleSourcedBroadcastPostProcessing(
1849
+ ref source,
1850
+ ref typedMessage,
1851
+ this,
1852
+ priority
1853
+ );
1854
+ messageHandlers[2]
1855
+ .HandleSourcedBroadcastPostProcessing(
1856
+ ref source,
1857
+ ref typedMessage,
1858
+ this,
1859
+ priority
1860
+ );
1861
+ messageHandlers[3]
1862
+ .HandleSourcedBroadcastPostProcessing(
1863
+ ref source,
1864
+ ref typedMessage,
1865
+ this,
1866
+ priority
1867
+ );
1868
+ messageHandlers[4]
1869
+ .HandleSourcedBroadcastPostProcessing(
1870
+ ref source,
1871
+ ref typedMessage,
1872
+ this,
1873
+ priority
1874
+ );
1875
+ return;
1214
1876
  }
1215
1877
  }
1878
+
1879
+ foreach (MessageHandler handler in messageHandlers)
1880
+ {
1881
+ handler.HandleSourcedBroadcastPostProcessing(
1882
+ ref source,
1883
+ ref typedMessage,
1884
+ this,
1885
+ priority
1886
+ );
1887
+ }
1216
1888
  }
1217
1889
 
1218
1890
  private void RunBroadcast<TMessage>(
1219
1891
  ref InstanceId source,
1220
1892
  ref TMessage typedMessage,
1221
1893
  int priority,
1222
- SortedList<MessageHandler, int> handlers
1894
+ HandlerCache cache
1223
1895
  )
1224
1896
  where TMessage : IBroadcastMessage
1225
1897
  {
1226
- switch (handlers.Count)
1898
+ if (cache.handlers.Count == 0)
1227
1899
  {
1228
- case <= 0:
1900
+ return;
1901
+ }
1902
+
1903
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
1904
+ switch (messageHandlers.Count)
1905
+ {
1906
+ case 1:
1229
1907
  {
1908
+ messageHandlers[0]
1909
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1230
1910
  return;
1231
1911
  }
1232
- case 1:
1912
+ case 2:
1233
1913
  {
1234
- MessageHandler handler = handlers.Keys[0];
1235
- handler.HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1914
+ messageHandlers[0]
1915
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1916
+ messageHandlers[1]
1917
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1236
1918
  return;
1237
1919
  }
1238
- default:
1920
+ case 3:
1239
1921
  {
1240
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1241
- handlers.Keys
1242
- );
1243
- try
1244
- {
1245
- foreach (MessageHandler handler in messageHandlers)
1246
- {
1247
- handler.HandleSourcedBroadcast(
1248
- ref source,
1249
- ref typedMessage,
1250
- this,
1251
- priority
1252
- );
1253
- }
1254
- }
1255
- finally
1256
- {
1257
- _messageHandlers.Push(messageHandlers);
1258
- }
1259
-
1260
- break;
1922
+ messageHandlers[0]
1923
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1924
+ messageHandlers[1]
1925
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1926
+ messageHandlers[2]
1927
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1928
+ return;
1929
+ }
1930
+ case 4:
1931
+ {
1932
+ messageHandlers[0]
1933
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1934
+ messageHandlers[1]
1935
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1936
+ messageHandlers[2]
1937
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1938
+ messageHandlers[3]
1939
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1940
+ return;
1941
+ }
1942
+ case 5:
1943
+ {
1944
+ messageHandlers[0]
1945
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1946
+ messageHandlers[1]
1947
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1948
+ messageHandlers[2]
1949
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1950
+ messageHandlers[3]
1951
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1952
+ messageHandlers[4]
1953
+ .HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1954
+ return;
1261
1955
  }
1262
1956
  }
1957
+
1958
+ foreach (MessageHandler handler in messageHandlers)
1959
+ {
1960
+ handler.HandleSourcedBroadcast(ref source, ref typedMessage, this, priority);
1961
+ }
1263
1962
  }
1264
1963
 
1265
1964
  private void BroadcastGlobalUntargeted(ref IUntargetedMessage message)
1266
1965
  {
1267
- switch (_globalSinks.Count)
1966
+ if (_globalSinks.handlers.Count == 0)
1967
+ {
1968
+ return;
1969
+ }
1970
+
1971
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(_globalSinks);
1972
+ switch (messageHandlers.Count)
1268
1973
  {
1269
- case <= 0:
1974
+ case 1:
1270
1975
  {
1976
+ messageHandlers[0].HandleGlobalUntargetedMessage(ref message, this);
1271
1977
  return;
1272
1978
  }
1273
- case 1:
1979
+ case 2:
1274
1980
  {
1275
- MessageHandler handler = _globalSinks.Keys[0];
1276
- handler.HandleGlobalUntargetedMessage(ref message, this);
1981
+ messageHandlers[0].HandleGlobalUntargetedMessage(ref message, this);
1982
+ messageHandlers[1].HandleGlobalUntargetedMessage(ref message, this);
1277
1983
  return;
1278
1984
  }
1279
- default:
1985
+ case 3:
1280
1986
  {
1281
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1282
- _globalSinks.Keys
1283
- );
1284
- try
1285
- {
1286
- foreach (MessageHandler handler in messageHandlers)
1287
- {
1288
- handler.HandleGlobalUntargetedMessage(ref message, this);
1289
- }
1290
- }
1291
- finally
1292
- {
1293
- _messageHandlers.Push(messageHandlers);
1294
- }
1295
-
1296
- break;
1987
+ messageHandlers[0].HandleGlobalUntargetedMessage(ref message, this);
1988
+ messageHandlers[1].HandleGlobalUntargetedMessage(ref message, this);
1989
+ messageHandlers[2].HandleGlobalUntargetedMessage(ref message, this);
1990
+ return;
1991
+ }
1992
+ case 4:
1993
+ {
1994
+ messageHandlers[0].HandleGlobalUntargetedMessage(ref message, this);
1995
+ messageHandlers[1].HandleGlobalUntargetedMessage(ref message, this);
1996
+ messageHandlers[2].HandleGlobalUntargetedMessage(ref message, this);
1997
+ messageHandlers[3].HandleGlobalUntargetedMessage(ref message, this);
1998
+ return;
1999
+ }
2000
+ case 5:
2001
+ {
2002
+ messageHandlers[0].HandleGlobalUntargetedMessage(ref message, this);
2003
+ messageHandlers[1].HandleGlobalUntargetedMessage(ref message, this);
2004
+ messageHandlers[2].HandleGlobalUntargetedMessage(ref message, this);
2005
+ messageHandlers[3].HandleGlobalUntargetedMessage(ref message, this);
2006
+ messageHandlers[4].HandleGlobalUntargetedMessage(ref message, this);
2007
+ return;
1297
2008
  }
1298
2009
  }
2010
+
2011
+ foreach (MessageHandler handler in messageHandlers)
2012
+ {
2013
+ handler.HandleGlobalUntargetedMessage(ref message, this);
2014
+ }
1299
2015
  }
1300
2016
 
1301
2017
  private void BroadcastGlobalTargeted(ref InstanceId target, ref ITargetedMessage message)
1302
2018
  {
1303
- switch (_globalSinks.Count)
2019
+ if (_globalSinks.handlers.Count == 0)
1304
2020
  {
1305
- case <= 0:
2021
+ return;
2022
+ }
2023
+
2024
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(_globalSinks);
2025
+ switch (messageHandlers.Count)
2026
+ {
2027
+ case 1:
1306
2028
  {
2029
+ messageHandlers[0].HandleGlobalTargetedMessage(ref target, ref message, this);
1307
2030
  return;
1308
2031
  }
1309
- case 1:
2032
+ case 2:
1310
2033
  {
1311
- MessageHandler handler = _globalSinks.Keys[0];
1312
- handler.HandleGlobalTargetedMessage(ref target, ref message, this);
2034
+ messageHandlers[0].HandleGlobalTargetedMessage(ref target, ref message, this);
2035
+ messageHandlers[1].HandleGlobalTargetedMessage(ref target, ref message, this);
1313
2036
  return;
1314
2037
  }
1315
- default:
2038
+ case 3:
1316
2039
  {
1317
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1318
- _globalSinks.Keys
1319
- );
1320
- try
1321
- {
1322
- foreach (MessageHandler handler in messageHandlers)
1323
- {
1324
- handler.HandleGlobalTargetedMessage(ref target, ref message, this);
1325
- }
1326
- }
1327
- finally
1328
- {
1329
- _messageHandlers.Push(messageHandlers);
1330
- }
1331
-
1332
- break;
2040
+ messageHandlers[0].HandleGlobalTargetedMessage(ref target, ref message, this);
2041
+ messageHandlers[1].HandleGlobalTargetedMessage(ref target, ref message, this);
2042
+ messageHandlers[2].HandleGlobalTargetedMessage(ref target, ref message, this);
2043
+ return;
2044
+ }
2045
+ case 4:
2046
+ {
2047
+ messageHandlers[0].HandleGlobalTargetedMessage(ref target, ref message, this);
2048
+ messageHandlers[1].HandleGlobalTargetedMessage(ref target, ref message, this);
2049
+ messageHandlers[2].HandleGlobalTargetedMessage(ref target, ref message, this);
2050
+ messageHandlers[3].HandleGlobalTargetedMessage(ref target, ref message, this);
2051
+ return;
2052
+ }
2053
+ case 5:
2054
+ {
2055
+ messageHandlers[0].HandleGlobalTargetedMessage(ref target, ref message, this);
2056
+ messageHandlers[1].HandleGlobalTargetedMessage(ref target, ref message, this);
2057
+ messageHandlers[2].HandleGlobalTargetedMessage(ref target, ref message, this);
2058
+ messageHandlers[3].HandleGlobalTargetedMessage(ref target, ref message, this);
2059
+ messageHandlers[4].HandleGlobalTargetedMessage(ref target, ref message, this);
2060
+ return;
1333
2061
  }
1334
2062
  }
2063
+
2064
+ foreach (MessageHandler handler in messageHandlers)
2065
+ {
2066
+ handler.HandleGlobalTargetedMessage(ref target, ref message, this);
2067
+ }
1335
2068
  }
1336
2069
 
1337
2070
  private void BroadcastGlobalSourcedBroadcast(
@@ -1339,100 +2072,103 @@
1339
2072
  ref IBroadcastMessage message
1340
2073
  )
1341
2074
  {
1342
- switch (_globalSinks.Count)
2075
+ if (_globalSinks.handlers.Count == 0)
2076
+ {
2077
+ return;
2078
+ }
2079
+
2080
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(_globalSinks);
2081
+ switch (messageHandlers.Count)
1343
2082
  {
1344
- case <= 0:
2083
+ case 1:
1345
2084
  {
2085
+ messageHandlers[0]
2086
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
1346
2087
  return;
1347
2088
  }
1348
- case 1:
2089
+ case 2:
1349
2090
  {
1350
- MessageHandler handler = _globalSinks.Keys[0];
1351
- handler.HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2091
+ messageHandlers[0]
2092
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2093
+ messageHandlers[1]
2094
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
1352
2095
  return;
1353
2096
  }
1354
- default:
2097
+ case 3:
1355
2098
  {
1356
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1357
- _globalSinks.Keys
1358
- );
1359
- try
1360
- {
1361
- foreach (MessageHandler handler in messageHandlers)
1362
- {
1363
- handler.HandleGlobalSourcedBroadcastMessage(
1364
- ref source,
1365
- ref message,
1366
- this
1367
- );
1368
- }
1369
- }
1370
- finally
1371
- {
1372
- _messageHandlers.Push(messageHandlers);
1373
- }
1374
-
1375
- break;
2099
+ messageHandlers[0]
2100
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2101
+ messageHandlers[1]
2102
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2103
+ messageHandlers[2]
2104
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2105
+ return;
2106
+ }
2107
+ case 4:
2108
+ {
2109
+ messageHandlers[0]
2110
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2111
+ messageHandlers[1]
2112
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2113
+ messageHandlers[2]
2114
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2115
+ messageHandlers[3]
2116
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2117
+ return;
2118
+ }
2119
+ case 5:
2120
+ {
2121
+ messageHandlers[0]
2122
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2123
+ messageHandlers[1]
2124
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2125
+ messageHandlers[2]
2126
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2127
+ messageHandlers[3]
2128
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2129
+ messageHandlers[4]
2130
+ .HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2131
+ return;
1376
2132
  }
1377
2133
  }
2134
+
2135
+ foreach (MessageHandler handler in messageHandlers)
2136
+ {
2137
+ handler.HandleGlobalSourcedBroadcastMessage(ref source, ref message, this);
2138
+ }
1378
2139
  }
1379
2140
 
1380
2141
  private bool TryGetInterceptorCaches(
1381
2142
  Type type,
1382
- out List<List<object>> interceptorStack,
2143
+ out List<KeyValuePair<int, List<object>>> interceptorStack,
1383
2144
  out List<object> interceptorObjects
1384
2145
  )
1385
2146
  {
1386
2147
  if (
1387
- !_interceptsByType.TryGetValue(type, out SortedList<int, List<object>> interceptors)
1388
- || interceptors.Count <= 0
1389
- )
1390
- {
1391
- interceptorStack = default;
1392
- interceptorObjects = default;
1393
- return false;
1394
- }
1395
-
1396
- if (!_interceptors.TryPop(out interceptorStack))
1397
- {
1398
- interceptorStack = new List<List<object>>(interceptors.Values);
1399
- }
1400
- else
1401
- {
1402
- interceptorStack.Clear();
1403
- switch (interceptors.Values)
1404
- {
1405
- case List<List<object>> list:
1406
- {
1407
- foreach (List<object> interceptor in list)
1408
- {
1409
- interceptorStack.Add(interceptor);
1410
- }
1411
-
1412
- break;
1413
- }
1414
- case List<object>[] array:
1415
- {
1416
- foreach (List<object> interceptor in array)
1417
- {
1418
- interceptorStack.Add(interceptor);
1419
- }
1420
-
1421
- break;
1422
- }
1423
- default:
1424
- {
1425
- // ReSharper disable once ForCanBeConvertedToForeach
1426
- // ReSharper disable once LoopCanBeConvertedToQuery
1427
- for (int i = 0; i < interceptors.Values.Count; i++)
1428
- {
1429
- List<object> interceptor = interceptors.Values[i];
1430
- interceptorStack.Add(interceptor);
1431
- }
2148
+ !_interceptsByType.TryGetValue(
2149
+ type,
2150
+ out HandlerCache<int, List<object>> interceptors
2151
+ )
2152
+ || interceptors.handlers.Count == 0
2153
+ )
2154
+ {
2155
+ interceptorStack = default;
2156
+ interceptorObjects = default;
2157
+ return false;
2158
+ }
1432
2159
 
1433
- break;
1434
- }
2160
+ interceptorStack = interceptors.cache;
2161
+ if (interceptors.version != interceptors.lastSeenVersion)
2162
+ {
2163
+ interceptorStack.Clear();
2164
+ IList<int> keys = interceptors.handlers.Keys;
2165
+ IList<List<object>> values = interceptors.handlers.Values;
2166
+ for (int i = 0; i < interceptors.handlers.Count; ++i)
2167
+ {
2168
+ interceptorStack.Add(new KeyValuePair<int, List<object>>(keys[i], values[i]));
1435
2169
  }
2170
+
2171
+ interceptors.lastSeenVersion = interceptors.version;
1436
2172
  }
1437
2173
 
1438
2174
  if (!_innerInterceptorsStack.TryPop(out interceptorObjects))
@@ -1449,7 +2185,7 @@
1449
2185
  if (
1450
2186
  !TryGetInterceptorCaches(
1451
2187
  type,
1452
- out List<List<object>> interceptorStack,
2188
+ out List<KeyValuePair<int, List<object>>> interceptorStack,
1453
2189
  out List<object> interceptorObjects
1454
2190
  )
1455
2191
  )
@@ -1459,10 +2195,10 @@
1459
2195
 
1460
2196
  try
1461
2197
  {
1462
- foreach (List<object> stack in interceptorStack)
2198
+ foreach (KeyValuePair<int, List<object>> entry in interceptorStack)
1463
2199
  {
1464
2200
  interceptorObjects.Clear();
1465
- foreach (object interceptor in stack)
2201
+ foreach (object interceptor in entry.Value)
1466
2202
  {
1467
2203
  interceptorObjects.Add(interceptor);
1468
2204
  }
@@ -1483,7 +2219,6 @@
1483
2219
  }
1484
2220
  finally
1485
2221
  {
1486
- _interceptors.Push(interceptorStack);
1487
2222
  _innerInterceptorsStack.Push(interceptorObjects);
1488
2223
  }
1489
2224
 
@@ -1496,7 +2231,7 @@
1496
2231
  if (
1497
2232
  !TryGetInterceptorCaches(
1498
2233
  type,
1499
- out List<List<object>> interceptorStack,
2234
+ out List<KeyValuePair<int, List<object>>> interceptorStack,
1500
2235
  out List<object> interceptorObjects
1501
2236
  )
1502
2237
  )
@@ -1506,10 +2241,10 @@
1506
2241
 
1507
2242
  try
1508
2243
  {
1509
- foreach (List<object> stack in interceptorStack)
2244
+ foreach (KeyValuePair<int, List<object>> entry in interceptorStack)
1510
2245
  {
1511
2246
  interceptorObjects.Clear();
1512
- foreach (object interceptor in stack)
2247
+ foreach (object interceptor in entry.Value)
1513
2248
  {
1514
2249
  interceptorObjects.Add(interceptor);
1515
2250
  }
@@ -1530,7 +2265,6 @@
1530
2265
  }
1531
2266
  finally
1532
2267
  {
1533
- _interceptors.Push(interceptorStack);
1534
2268
  _innerInterceptorsStack.Push(interceptorObjects);
1535
2269
  }
1536
2270
 
@@ -1543,7 +2277,7 @@
1543
2277
  if (
1544
2278
  !TryGetInterceptorCaches(
1545
2279
  type,
1546
- out List<List<object>> interceptorStack,
2280
+ out List<KeyValuePair<int, List<object>>> interceptorStack,
1547
2281
  out List<object> interceptorObjects
1548
2282
  )
1549
2283
  )
@@ -1553,10 +2287,10 @@
1553
2287
 
1554
2288
  try
1555
2289
  {
1556
- foreach (List<object> stack in interceptorStack)
2290
+ foreach (KeyValuePair<int, List<object>> entry in interceptorStack)
1557
2291
  {
1558
2292
  interceptorObjects.Clear();
1559
- foreach (object interceptor in stack)
2293
+ foreach (object interceptor in entry.Value)
1560
2294
  {
1561
2295
  interceptorObjects.Add(interceptor);
1562
2296
  }
@@ -1577,7 +2311,6 @@
1577
2311
  }
1578
2312
  finally
1579
2313
  {
1580
- _interceptors.Push(interceptorStack);
1581
2314
  _innerInterceptorsStack.Push(interceptorObjects);
1582
2315
  }
1583
2316
 
@@ -1588,82 +2321,133 @@
1588
2321
  where TMessage : IMessage
1589
2322
  {
1590
2323
  if (
1591
- !_sinks.TryGetValue(
1592
- type,
1593
- out SortedList<int, SortedList<MessageHandler, int>> sortedHandlers
1594
- )
1595
- || sortedHandlers.Count <= 0
2324
+ !_sinks.TryGetValue(type, out HandlerCache<int, HandlerCache> sortedHandlers)
2325
+ || sortedHandlers.handlers.Count == 0
1596
2326
  )
1597
2327
  {
1598
2328
  return false;
1599
2329
  }
1600
2330
 
1601
- if (sortedHandlers.Count == 1)
1602
- {
1603
- RunUntargetedBroadcast(
1604
- ref message,
1605
- sortedHandlers.Keys[0],
1606
- sortedHandlers.Values[0]
1607
- );
1608
- return true;
1609
- }
2331
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
2332
+ sortedHandlers
2333
+ );
1610
2334
 
1611
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
1612
- GetOrAddMessageHandlerStack(sortedHandlers);
1613
- try
2335
+ switch (handlerList.Count)
1614
2336
  {
1615
- foreach (KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList)
2337
+ case 1:
2338
+ {
2339
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2340
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2341
+ return true;
2342
+ }
2343
+ case 2:
2344
+ {
2345
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2346
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2347
+ entry = handlerList[1];
2348
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2349
+ return true;
2350
+ }
2351
+ case 3:
2352
+ {
2353
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2354
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2355
+ entry = handlerList[1];
2356
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2357
+ entry = handlerList[2];
2358
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2359
+ return true;
2360
+ }
2361
+ case 4:
2362
+ {
2363
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2364
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2365
+ entry = handlerList[1];
2366
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2367
+ entry = handlerList[2];
2368
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2369
+ entry = handlerList[3];
2370
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2371
+ return true;
2372
+ }
2373
+ case 5:
1616
2374
  {
2375
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2376
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2377
+ entry = handlerList[1];
2378
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2379
+ entry = handlerList[2];
2380
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2381
+ entry = handlerList[3];
1617
2382
  RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2383
+ entry = handlerList[4];
2384
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
2385
+ return true;
1618
2386
  }
1619
2387
  }
1620
- finally
2388
+
2389
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
1621
2390
  {
1622
- _sortedHandlers.Push(handlerList);
2391
+ RunUntargetedBroadcast(ref message, entry.Key, entry.Value);
1623
2392
  }
1624
-
1625
2393
  return true;
1626
2394
  }
1627
2395
 
1628
2396
  private void RunUntargetedBroadcast<TMessage>(
1629
2397
  ref TMessage message,
1630
2398
  int priority,
1631
- SortedList<MessageHandler, int> handlers
2399
+ HandlerCache cache
1632
2400
  )
1633
2401
  where TMessage : IMessage
1634
2402
  {
1635
- switch (handlers.Count)
2403
+ if (cache.handlers.Count == 0)
1636
2404
  {
1637
- case <= 0:
2405
+ return;
2406
+ }
2407
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
2408
+ switch (messageHandlers.Count)
2409
+ {
2410
+ case 1:
1638
2411
  {
2412
+ messageHandlers[0].HandleUntargetedMessage(ref message, this, priority);
1639
2413
  return;
1640
2414
  }
1641
- case 1:
2415
+ case 2:
1642
2416
  {
1643
- MessageHandler handler = handlers.Keys[0];
1644
- handler.HandleUntargetedMessage(ref message, this, priority);
2417
+ messageHandlers[0].HandleUntargetedMessage(ref message, this, priority);
2418
+ messageHandlers[1].HandleUntargetedMessage(ref message, this, priority);
1645
2419
  return;
1646
2420
  }
1647
- default:
2421
+ case 3:
1648
2422
  {
1649
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1650
- handlers.Keys
1651
- );
1652
- try
1653
- {
1654
- foreach (MessageHandler handler in messageHandlers)
1655
- {
1656
- handler.HandleUntargetedMessage(ref message, this, priority);
1657
- }
1658
- }
1659
- finally
1660
- {
1661
- _messageHandlers.Push(messageHandlers);
1662
- }
1663
-
1664
- break;
2423
+ messageHandlers[0].HandleUntargetedMessage(ref message, this, priority);
2424
+ messageHandlers[1].HandleUntargetedMessage(ref message, this, priority);
2425
+ messageHandlers[2].HandleUntargetedMessage(ref message, this, priority);
2426
+ return;
2427
+ }
2428
+ case 4:
2429
+ {
2430
+ messageHandlers[0].HandleUntargetedMessage(ref message, this, priority);
2431
+ messageHandlers[1].HandleUntargetedMessage(ref message, this, priority);
2432
+ messageHandlers[2].HandleUntargetedMessage(ref message, this, priority);
2433
+ messageHandlers[3].HandleUntargetedMessage(ref message, this, priority);
2434
+ return;
2435
+ }
2436
+ case 5:
2437
+ {
2438
+ messageHandlers[0].HandleUntargetedMessage(ref message, this, priority);
2439
+ messageHandlers[1].HandleUntargetedMessage(ref message, this, priority);
2440
+ messageHandlers[2].HandleUntargetedMessage(ref message, this, priority);
2441
+ messageHandlers[3].HandleUntargetedMessage(ref message, this, priority);
2442
+ messageHandlers[4].HandleUntargetedMessage(ref message, this, priority);
2443
+ return;
1665
2444
  }
1666
2445
  }
2446
+
2447
+ foreach (MessageHandler handler in messageHandlers)
2448
+ {
2449
+ handler.HandleUntargetedMessage(ref message, this, priority);
2450
+ }
1667
2451
  }
1668
2452
 
1669
2453
  private bool InternalTargetedWithoutTargetingBroadcast<TMessage>(
@@ -1674,39 +2458,74 @@
1674
2458
  where TMessage : ITargetedMessage
1675
2459
  {
1676
2460
  if (
1677
- !_sinks.TryGetValue(
1678
- type,
1679
- out SortedList<int, SortedList<MessageHandler, int>> sortedHandlers
1680
- )
1681
- || sortedHandlers.Count <= 0
2461
+ !_sinks.TryGetValue(type, out HandlerCache<int, HandlerCache> sortedHandlers)
2462
+ || sortedHandlers.handlers.Count == 0
1682
2463
  )
1683
2464
  {
1684
2465
  return false;
1685
2466
  }
1686
2467
 
1687
- if (sortedHandlers.Count == 1)
1688
- {
1689
- RunTargetedWithoutTargeting(
1690
- ref target,
1691
- ref message,
1692
- sortedHandlers.Keys[0],
1693
- sortedHandlers.Values[0]
1694
- );
1695
- return true;
1696
- }
2468
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
2469
+ sortedHandlers
2470
+ );
1697
2471
 
1698
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
1699
- GetOrAddMessageHandlerStack(sortedHandlers);
1700
- try
2472
+ switch (handlerList.Count)
1701
2473
  {
1702
- foreach (KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList)
2474
+ case 1:
2475
+ {
2476
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2477
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2478
+ return true;
2479
+ }
2480
+ case 2:
2481
+ {
2482
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2483
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2484
+ entry = handlerList[1];
2485
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2486
+ return true;
2487
+ }
2488
+ case 3:
2489
+ {
2490
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2491
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2492
+ entry = handlerList[1];
2493
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2494
+ entry = handlerList[2];
2495
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2496
+ return true;
2497
+ }
2498
+ case 4:
2499
+ {
2500
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2501
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2502
+ entry = handlerList[1];
2503
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2504
+ entry = handlerList[2];
2505
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2506
+ entry = handlerList[3];
2507
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2508
+ return true;
2509
+ }
2510
+ case 5:
1703
2511
  {
2512
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2513
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2514
+ entry = handlerList[1];
2515
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2516
+ entry = handlerList[2];
2517
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2518
+ entry = handlerList[3];
2519
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2520
+ entry = handlerList[4];
1704
2521
  RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
2522
+ return true;
1705
2523
  }
1706
2524
  }
1707
- finally
2525
+
2526
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
1708
2527
  {
1709
- _sortedHandlers.Push(handlerList);
2528
+ RunTargetedWithoutTargeting(ref target, ref message, entry.Key, entry.Value);
1710
2529
  }
1711
2530
 
1712
2531
  return true;
@@ -1716,47 +2535,74 @@
1716
2535
  ref InstanceId target,
1717
2536
  ref TMessage message,
1718
2537
  int priority,
1719
- SortedList<MessageHandler, int> handlers
2538
+ HandlerCache cache
1720
2539
  )
1721
2540
  where TMessage : ITargetedMessage
1722
2541
  {
1723
- switch (handlers.Count)
2542
+ if (cache.handlers.Count == 0)
2543
+ {
2544
+ return;
2545
+ }
2546
+
2547
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
2548
+ switch (messageHandlers.Count)
1724
2549
  {
1725
- case <= 0:
2550
+ case 1:
1726
2551
  {
2552
+ messageHandlers[0]
2553
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
1727
2554
  return;
1728
2555
  }
1729
- case 1:
2556
+ case 2:
1730
2557
  {
1731
- MessageHandler handler = handlers.Keys[0];
1732
- handler.HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2558
+ messageHandlers[0]
2559
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2560
+ messageHandlers[1]
2561
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
1733
2562
  return;
1734
2563
  }
1735
- default:
2564
+ case 3:
1736
2565
  {
1737
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1738
- handlers.Keys
1739
- );
1740
- try
1741
- {
1742
- foreach (MessageHandler handler in messageHandlers)
1743
- {
1744
- handler.HandleTargetedWithoutTargeting(
1745
- ref target,
1746
- ref message,
1747
- this,
1748
- priority
1749
- );
1750
- }
1751
- }
1752
- finally
1753
- {
1754
- _messageHandlers.Push(messageHandlers);
1755
- }
1756
-
1757
- break;
2566
+ messageHandlers[0]
2567
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2568
+ messageHandlers[1]
2569
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2570
+ messageHandlers[2]
2571
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2572
+ return;
2573
+ }
2574
+ case 4:
2575
+ {
2576
+ messageHandlers[0]
2577
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2578
+ messageHandlers[1]
2579
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2580
+ messageHandlers[2]
2581
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2582
+ messageHandlers[3]
2583
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2584
+ return;
2585
+ }
2586
+ case 5:
2587
+ {
2588
+ messageHandlers[0]
2589
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2590
+ messageHandlers[1]
2591
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2592
+ messageHandlers[2]
2593
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2594
+ messageHandlers[3]
2595
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2596
+ messageHandlers[4]
2597
+ .HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2598
+ return;
1758
2599
  }
1759
2600
  }
2601
+
2602
+ foreach (MessageHandler handler in messageHandlers)
2603
+ {
2604
+ handler.HandleTargetedWithoutTargeting(ref target, ref message, this, priority);
2605
+ }
1760
2606
  }
1761
2607
 
1762
2608
  private bool InternalBroadcastWithoutSource<TMessage>(
@@ -1767,39 +2613,73 @@
1767
2613
  where TMessage : IBroadcastMessage
1768
2614
  {
1769
2615
  if (
1770
- !_sinks.TryGetValue(
1771
- type,
1772
- out SortedList<int, SortedList<MessageHandler, int>> sortedHandlers
1773
- )
1774
- || sortedHandlers.Count <= 0
2616
+ !_sinks.TryGetValue(type, out HandlerCache<int, HandlerCache> sortedHandlers)
2617
+ || sortedHandlers.handlers.Count == 0
1775
2618
  )
1776
2619
  {
1777
2620
  return false;
1778
2621
  }
1779
2622
 
1780
- if (sortedHandlers.Count == 1)
1781
- {
1782
- RunBroadcastWithoutSource(
1783
- ref source,
1784
- ref message,
1785
- sortedHandlers.Keys[0],
1786
- sortedHandlers.Values[0]
1787
- );
1788
- return true;
1789
- }
1790
-
1791
- List<KeyValuePair<int, SortedList<MessageHandler, int>>> handlerList =
1792
- GetOrAddMessageHandlerStack(sortedHandlers);
1793
- try
2623
+ List<KeyValuePair<int, HandlerCache>> handlerList = GetOrAddMessageHandlerStack(
2624
+ sortedHandlers
2625
+ );
2626
+ switch (handlerList.Count)
1794
2627
  {
1795
- foreach (KeyValuePair<int, SortedList<MessageHandler, int>> entry in handlerList)
2628
+ case 1:
2629
+ {
2630
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2631
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2632
+ return true;
2633
+ }
2634
+ case 2:
2635
+ {
2636
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2637
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2638
+ entry = handlerList[1];
2639
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2640
+ return true;
2641
+ }
2642
+ case 3:
2643
+ {
2644
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2645
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2646
+ entry = handlerList[1];
2647
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2648
+ entry = handlerList[2];
2649
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2650
+ return true;
2651
+ }
2652
+ case 4:
2653
+ {
2654
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2655
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2656
+ entry = handlerList[1];
2657
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2658
+ entry = handlerList[2];
2659
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2660
+ entry = handlerList[3];
2661
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2662
+ return true;
2663
+ }
2664
+ case 5:
1796
2665
  {
2666
+ KeyValuePair<int, HandlerCache> entry = handlerList[0];
2667
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2668
+ entry = handlerList[1];
2669
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2670
+ entry = handlerList[2];
2671
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2672
+ entry = handlerList[3];
1797
2673
  RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2674
+ entry = handlerList[4];
2675
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
2676
+ return true;
1798
2677
  }
1799
2678
  }
1800
- finally
2679
+
2680
+ foreach (KeyValuePair<int, HandlerCache> entry in handlerList)
1801
2681
  {
1802
- _sortedHandlers.Push(handlerList);
2682
+ RunBroadcastWithoutSource(ref source, ref message, entry.Key, entry.Value);
1803
2683
  }
1804
2684
 
1805
2685
  return true;
@@ -1809,57 +2689,159 @@
1809
2689
  ref InstanceId source,
1810
2690
  ref TMessage message,
1811
2691
  int priority,
1812
- SortedList<MessageHandler, int> handlers
2692
+ HandlerCache cache
1813
2693
  )
1814
2694
  where TMessage : IBroadcastMessage
1815
2695
  {
1816
- switch (handlers.Count)
2696
+ if (cache.handlers.Count == 0)
2697
+ {
2698
+ return;
2699
+ }
2700
+
2701
+ List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(cache);
2702
+ switch (messageHandlers.Count)
1817
2703
  {
1818
- case <= 0:
2704
+ case 1:
1819
2705
  {
2706
+ messageHandlers[0]
2707
+ .HandleSourcedBroadcastWithoutSource(
2708
+ ref source,
2709
+ ref message,
2710
+ this,
2711
+ priority
2712
+ );
1820
2713
  return;
1821
2714
  }
1822
- case 1:
2715
+ case 2:
1823
2716
  {
1824
- MessageHandler handler = handlers.Keys[0];
1825
- handler.HandleSourcedBroadcastWithoutSource(
1826
- ref source,
1827
- ref message,
1828
- this,
1829
- priority
1830
- );
2717
+ messageHandlers[0]
2718
+ .HandleSourcedBroadcastWithoutSource(
2719
+ ref source,
2720
+ ref message,
2721
+ this,
2722
+ priority
2723
+ );
2724
+ messageHandlers[1]
2725
+ .HandleSourcedBroadcastWithoutSource(
2726
+ ref source,
2727
+ ref message,
2728
+ this,
2729
+ priority
2730
+ );
1831
2731
  return;
1832
2732
  }
1833
- default:
2733
+ case 3:
1834
2734
  {
1835
- List<MessageHandler> messageHandlers = GetOrAddMessageHandlerStack(
1836
- handlers.Keys
1837
- );
1838
- try
1839
- {
1840
- foreach (MessageHandler handler in messageHandlers)
1841
- {
1842
- handler.HandleSourcedBroadcastWithoutSource(
1843
- ref source,
1844
- ref message,
1845
- this,
1846
- priority
1847
- );
1848
- }
1849
- }
1850
- finally
1851
- {
1852
- _messageHandlers.Push(messageHandlers);
1853
- }
1854
-
1855
- break;
2735
+ messageHandlers[0]
2736
+ .HandleSourcedBroadcastWithoutSource(
2737
+ ref source,
2738
+ ref message,
2739
+ this,
2740
+ priority
2741
+ );
2742
+ messageHandlers[1]
2743
+ .HandleSourcedBroadcastWithoutSource(
2744
+ ref source,
2745
+ ref message,
2746
+ this,
2747
+ priority
2748
+ );
2749
+ messageHandlers[2]
2750
+ .HandleSourcedBroadcastWithoutSource(
2751
+ ref source,
2752
+ ref message,
2753
+ this,
2754
+ priority
2755
+ );
2756
+ return;
1856
2757
  }
2758
+ case 4:
2759
+ {
2760
+ messageHandlers[0]
2761
+ .HandleSourcedBroadcastWithoutSource(
2762
+ ref source,
2763
+ ref message,
2764
+ this,
2765
+ priority
2766
+ );
2767
+ messageHandlers[1]
2768
+ .HandleSourcedBroadcastWithoutSource(
2769
+ ref source,
2770
+ ref message,
2771
+ this,
2772
+ priority
2773
+ );
2774
+ messageHandlers[2]
2775
+ .HandleSourcedBroadcastWithoutSource(
2776
+ ref source,
2777
+ ref message,
2778
+ this,
2779
+ priority
2780
+ );
2781
+ messageHandlers[3]
2782
+ .HandleSourcedBroadcastWithoutSource(
2783
+ ref source,
2784
+ ref message,
2785
+ this,
2786
+ priority
2787
+ );
2788
+ return;
2789
+ }
2790
+ case 5:
2791
+ {
2792
+ messageHandlers[0]
2793
+ .HandleSourcedBroadcastWithoutSource(
2794
+ ref source,
2795
+ ref message,
2796
+ this,
2797
+ priority
2798
+ );
2799
+ messageHandlers[1]
2800
+ .HandleSourcedBroadcastWithoutSource(
2801
+ ref source,
2802
+ ref message,
2803
+ this,
2804
+ priority
2805
+ );
2806
+ messageHandlers[2]
2807
+ .HandleSourcedBroadcastWithoutSource(
2808
+ ref source,
2809
+ ref message,
2810
+ this,
2811
+ priority
2812
+ );
2813
+ messageHandlers[3]
2814
+ .HandleSourcedBroadcastWithoutSource(
2815
+ ref source,
2816
+ ref message,
2817
+ this,
2818
+ priority
2819
+ );
2820
+ messageHandlers[4]
2821
+ .HandleSourcedBroadcastWithoutSource(
2822
+ ref source,
2823
+ ref message,
2824
+ this,
2825
+ priority
2826
+ );
2827
+ return;
2828
+ }
2829
+ }
2830
+
2831
+ foreach (MessageHandler handler in messageHandlers)
2832
+ {
2833
+ handler.HandleSourcedBroadcastWithoutSource(
2834
+ ref source,
2835
+ ref message,
2836
+ this,
2837
+ priority
2838
+ );
1857
2839
  }
1858
2840
  }
1859
2841
 
1860
2842
  private Action InternalRegisterUntargeted<T>(
1861
2843
  MessageHandler messageHandler,
1862
- Dictionary<Type, SortedList<int, SortedList<MessageHandler, int>>> sinks,
2844
+ Dictionary<Type, HandlerCache<int, HandlerCache>> sinks,
1863
2845
  RegistrationMethod registrationMethod,
1864
2846
  int priority
1865
2847
  )
@@ -1873,23 +2855,21 @@
1873
2855
  InstanceId handlerOwnerId = messageHandler.owner;
1874
2856
  Type type = typeof(T);
1875
2857
 
1876
- if (
1877
- !sinks.TryGetValue(
1878
- type,
1879
- out SortedList<int, SortedList<MessageHandler, int>> handlers
1880
- )
1881
- )
2858
+ if (!sinks.TryGetValue(type, out HandlerCache<int, HandlerCache> handlers))
1882
2859
  {
1883
- handlers = new SortedList<int, SortedList<MessageHandler, int>>();
2860
+ handlers = new HandlerCache<int, HandlerCache>();
1884
2861
  sinks[type] = handlers;
1885
2862
  }
1886
2863
 
1887
- if (!handlers.TryGetValue(priority, out SortedList<MessageHandler, int> handler))
2864
+ if (!handlers.handlers.TryGetValue(priority, out HandlerCache cache))
1888
2865
  {
1889
- handler = new SortedList<MessageHandler, int>();
1890
- handlers[priority] = handler;
2866
+ handlers.version++;
2867
+ cache = new HandlerCache();
2868
+ handlers.handlers[priority] = cache;
1891
2869
  }
1892
2870
 
2871
+ Dictionary<MessageHandler, int> handler = cache.handlers;
2872
+ cache.version++;
1893
2873
  int count = handler.GetValueOrDefault(messageHandler, 0);
1894
2874
 
1895
2875
  handler[messageHandler] = count + 1;
@@ -1904,6 +2884,7 @@
1904
2884
 
1905
2885
  return () =>
1906
2886
  {
2887
+ cache.version++;
1907
2888
  _log.Log(
1908
2889
  new MessagingRegistration(
1909
2890
  handlerOwnerId,
@@ -1914,8 +2895,8 @@
1914
2895
  );
1915
2896
  if (
1916
2897
  !sinks.TryGetValue(type, out handlers)
1917
- || !handlers.TryGetValue(priority, out handler)
1918
- || !handler.TryGetValue(messageHandler, out count)
2898
+ || !handlers.handlers.TryGetValue(priority, out cache)
2899
+ || !cache.handlers.TryGetValue(messageHandler, out count)
1919
2900
  )
1920
2901
  {
1921
2902
  if (MessagingDebug.enabled)
@@ -1931,16 +2912,18 @@
1931
2912
  return;
1932
2913
  }
1933
2914
 
2915
+ handlers.version++;
2916
+ handler = cache.handlers;
1934
2917
  if (count <= 1)
1935
2918
  {
1936
2919
  bool complete = handler.Remove(messageHandler);
1937
2920
 
1938
- if (handler.Count <= 0)
2921
+ if (handler.Count == 0)
1939
2922
  {
1940
- _ = handlers.Remove(priority);
2923
+ _ = handlers.handlers.Remove(priority);
1941
2924
  }
1942
2925
 
1943
- if (handlers.Count <= 0)
2926
+ if (handlers.handlers.Count == 0)
1944
2927
  {
1945
2928
  _ = sinks.Remove(type);
1946
2929
  }
@@ -1965,10 +2948,7 @@
1965
2948
  private Action InternalRegisterWithContext<T>(
1966
2949
  InstanceId context,
1967
2950
  MessageHandler messageHandler,
1968
- Dictionary<
1969
- Type,
1970
- Dictionary<InstanceId, SortedList<int, SortedList<MessageHandler, int>>>
1971
- > sinks,
2951
+ Dictionary<Type, Dictionary<InstanceId, HandlerCache<int, HandlerCache>>> sinks,
1972
2952
  RegistrationMethod registrationMethod,
1973
2953
  int priority
1974
2954
  )
@@ -1982,35 +2962,34 @@
1982
2962
  if (
1983
2963
  !sinks.TryGetValue(
1984
2964
  type,
1985
- out Dictionary<
1986
- InstanceId,
1987
- SortedList<int, SortedList<MessageHandler, int>>
1988
- > broadcastHandlers
2965
+ out Dictionary<InstanceId, HandlerCache<int, HandlerCache>> broadcastHandlers
1989
2966
  )
1990
2967
  )
1991
2968
  {
1992
- broadcastHandlers =
1993
- new Dictionary<InstanceId, SortedList<int, SortedList<MessageHandler, int>>>();
2969
+ broadcastHandlers = new Dictionary<InstanceId, HandlerCache<int, HandlerCache>>();
1994
2970
  sinks[type] = broadcastHandlers;
1995
2971
  }
1996
2972
 
1997
2973
  if (
1998
2974
  !broadcastHandlers.TryGetValue(
1999
2975
  context,
2000
- out SortedList<int, SortedList<MessageHandler, int>> handlers
2976
+ out HandlerCache<int, HandlerCache> handlers
2001
2977
  )
2002
2978
  )
2003
2979
  {
2004
- handlers = new SortedList<int, SortedList<MessageHandler, int>>();
2980
+ handlers = new HandlerCache<int, HandlerCache>();
2005
2981
  broadcastHandlers[context] = handlers;
2006
2982
  }
2007
2983
 
2008
- if (!handlers.TryGetValue(priority, out SortedList<MessageHandler, int> handler))
2984
+ if (!handlers.handlers.TryGetValue(priority, out HandlerCache cache))
2009
2985
  {
2010
- handler = new SortedList<MessageHandler, int>();
2011
- handlers[priority] = handler;
2986
+ handlers.version++;
2987
+ cache = new HandlerCache();
2988
+ handlers.handlers[priority] = cache;
2012
2989
  }
2013
2990
 
2991
+ cache.version++;
2992
+ Dictionary<MessageHandler, int> handler = cache.handlers;
2014
2993
  int count = handler.GetValueOrDefault(messageHandler, 0);
2015
2994
 
2016
2995
  handler[messageHandler] = count + 1;
@@ -2025,6 +3004,7 @@
2025
3004
 
2026
3005
  return () =>
2027
3006
  {
3007
+ cache.version++;
2028
3008
  _log.Log(
2029
3009
  new MessagingRegistration(
2030
3010
  context,
@@ -2036,8 +3016,8 @@
2036
3016
  if (
2037
3017
  !sinks.TryGetValue(type, out broadcastHandlers)
2038
3018
  || !broadcastHandlers.TryGetValue(context, out handlers)
2039
- || !handlers.TryGetValue(priority, out handler)
2040
- || !handler.TryGetValue(messageHandler, out count)
3019
+ || !handlers.handlers.TryGetValue(priority, out cache)
3020
+ || !cache.handlers.TryGetValue(messageHandler, out count)
2041
3021
  )
2042
3022
  {
2043
3023
  if (MessagingDebug.enabled)
@@ -2053,20 +3033,22 @@
2053
3033
  return;
2054
3034
  }
2055
3035
 
3036
+ handler = cache.handlers;
2056
3037
  if (count <= 1)
2057
3038
  {
2058
3039
  bool complete = handler.Remove(messageHandler);
2059
- if (handler.Count <= 0)
3040
+ if (handler.Count == 0)
2060
3041
  {
2061
- _ = handlers.Remove(priority);
3042
+ handlers.version++;
3043
+ _ = handlers.handlers.Remove(priority);
2062
3044
  }
2063
3045
 
2064
- if (handlers.Count <= 0)
3046
+ if (handlers.handlers.Count == 0)
2065
3047
  {
2066
3048
  _ = broadcastHandlers.Remove(context);
2067
3049
  }
2068
3050
 
2069
- if (broadcastHandlers.Count <= 0)
3051
+ if (broadcastHandlers.Count == 0)
2070
3052
  {
2071
3053
  _ = sinks.Remove(type);
2072
3054
  }
@@ -2088,104 +3070,45 @@
2088
3070
  };
2089
3071
  }
2090
3072
 
2091
- private List<
2092
- KeyValuePair<int, SortedList<MessageHandler, int>>
2093
- > GetOrAddMessageHandlerStack(
2094
- IEnumerable<KeyValuePair<int, SortedList<MessageHandler, int>>> handlers
3073
+ private static List<KeyValuePair<int, HandlerCache>> GetOrAddMessageHandlerStack(
3074
+ HandlerCache<int, HandlerCache> cache
2095
3075
  )
2096
3076
  {
2097
- if (
2098
- !_sortedHandlers.TryPop(
2099
- out List<KeyValuePair<int, SortedList<MessageHandler, int>>> messageHandlers
2100
- )
2101
- )
3077
+ if (cache.version == cache.lastSeenVersion)
2102
3078
  {
2103
- return new List<KeyValuePair<int, SortedList<MessageHandler, int>>>(handlers);
3079
+ return cache.cache;
2104
3080
  }
2105
3081
 
2106
- messageHandlers.Clear();
2107
- if (handlers is SortedList<int, SortedList<MessageHandler, int>> sortedList)
2108
- {
2109
- for (int i = 0; i < sortedList.Count; ++i)
2110
- {
2111
- messageHandlers.Add(
2112
- new KeyValuePair<int, SortedList<MessageHandler, int>>(
2113
- sortedList.Keys[i],
2114
- sortedList.Values[i]
2115
- )
2116
- );
2117
- }
2118
- }
2119
- else
3082
+ List<KeyValuePair<int, HandlerCache>> list = cache.cache;
3083
+ list.Clear();
3084
+ SortedList<int, HandlerCache> handlers = cache.handlers;
3085
+ IList<int> keys = handlers.Keys;
3086
+ IList<HandlerCache> values = handlers.Values;
3087
+ for (int i = 0; i < handlers.Count; i++)
2120
3088
  {
2121
- foreach (KeyValuePair<int, SortedList<MessageHandler, int>> handler in handlers)
2122
- {
2123
- messageHandlers.Add(handler);
2124
- }
3089
+ list.Add(new KeyValuePair<int, HandlerCache>(keys[i], values[i]));
2125
3090
  }
2126
- return messageHandlers;
3091
+
3092
+ cache.lastSeenVersion = cache.version;
3093
+ return list;
2127
3094
  }
2128
3095
 
2129
- private List<MessageHandler> GetOrAddMessageHandlerStack(
2130
- IEnumerable<MessageHandler> handlers
2131
- )
3096
+ private static List<MessageHandler> GetOrAddMessageHandlerStack(HandlerCache cache)
2132
3097
  {
2133
- if (!_messageHandlers.TryPop(out List<MessageHandler> messageHandlers))
3098
+ if (cache.version == cache.lastSeenVersion)
2134
3099
  {
2135
- return new List<MessageHandler>(handlers);
3100
+ return cache.cache;
2136
3101
  }
2137
3102
 
2138
- messageHandlers.Clear();
2139
- // Try to avoid allocations if at all possible
2140
- switch (handlers)
3103
+ List<MessageHandler> list = cache.cache;
3104
+ list.Clear();
3105
+ Dictionary<MessageHandler, int>.KeyCollection keys = cache.handlers.Keys;
3106
+ foreach (MessageHandler key in keys)
2141
3107
  {
2142
- case List<MessageHandler> list:
2143
- {
2144
- foreach (MessageHandler handler in list)
2145
- {
2146
- messageHandlers.Add(handler);
2147
- }
2148
-
2149
- break;
2150
- }
2151
- case MessageHandler[] array:
2152
- {
2153
- foreach (MessageHandler handler in array)
2154
- {
2155
- messageHandlers.Add(handler);
2156
- }
2157
-
2158
- break;
2159
- }
2160
- case IList<MessageHandler> interfaceList:
2161
- {
2162
- for (int i = 0; i < interfaceList.Count; ++i)
2163
- {
2164
- messageHandlers.Add(interfaceList[i]);
2165
- }
2166
-
2167
- break;
2168
- }
2169
- case HashSet<MessageHandler> set:
2170
- {
2171
- foreach (MessageHandler handler in set)
2172
- {
2173
- messageHandlers.Add(handler);
2174
- }
2175
-
2176
- break;
2177
- }
2178
- default:
2179
- {
2180
- foreach (MessageHandler handler in handlers)
2181
- {
2182
- messageHandlers.Add(handler);
2183
- }
2184
- break;
2185
- }
3108
+ list.Add(key);
2186
3109
  }
2187
-
2188
- return messageHandlers;
3110
+ cache.lastSeenVersion = cache.version;
3111
+ return list;
2189
3112
  }
2190
3113
 
2191
3114
  // https://blogs.msmvps.com/jonskeet/2008/08/09/making-reflection-fly-and-exploring-delegates/