com.wallstop-studios.dxmessaging 2.0.0-rc21 → 2.0.0-rc23
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.
- package/.github/workflows/npm-publish.yml +9 -0
- package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
- package/README.md +12 -7
- package/Runtime/Core/Extensions/EnumExtensions.cs +37 -0
- package/Runtime/Core/Extensions/EnumExtensions.cs.meta +3 -0
- package/Runtime/Core/Helper/DxMessagingRuntime.cs +201 -0
- package/Runtime/Core/Helper/DxMessagingRuntime.cs.meta +3 -0
- package/Runtime/Core/Helper/MessageCache.cs +105 -0
- package/Runtime/Core/Helper/MessageCache.cs.meta +3 -0
- package/Runtime/Core/Helper/MessageHelperIndexer.cs +9 -0
- package/Runtime/Core/Helper/MessageHelperIndexer.cs.meta +3 -0
- package/Runtime/Core/Helper.meta +3 -0
- package/Runtime/Core/IMessage.cs +0 -13
- package/Runtime/Core/InstanceId.cs +0 -2
- package/Runtime/Core/MessageBus/IMessageBus.cs +10 -3
- package/Runtime/Core/MessageBus/MessageBus.cs +400 -98
- package/Runtime/Core/MessageHandler.cs +51 -119
- package/Runtime/Core/Messages/DxReflexiveMessage.cs +132 -0
- package/Runtime/Core/Messages/DxReflexiveMessage.cs.meta +3 -0
- package/Runtime/Core/MessagingDebug.cs +1 -1
- package/Runtime/Unity/MessageAwareComponent.cs +34 -13
- package/Runtime/Unity/Messages/GlobalStringMessage.cs +15 -0
- package/Runtime/Unity/Messages/GlobalStringMessage.cs.meta +3 -0
- package/Runtime/Unity/Messages/StringMessage.cs +15 -0
- package/Runtime/Unity/Messages/StringMessage.cs.meta +3 -0
- package/Runtime/Unity/Messages.meta +3 -0
- package/Runtime/WallstopStudios.DxMessaging.asmdef +1 -1
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +255 -394
- package/Tests/Runtime/Benchmarks/PerformanceTests.cs +141 -1
- package/Tests/Runtime/Core/MessagingTestBase.cs +3 -11
- package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs +12 -0
- package/package.json +1 -1
|
@@ -2,9 +2,16 @@
|
|
|
2
2
|
{
|
|
3
3
|
using System;
|
|
4
4
|
using System.Collections.Generic;
|
|
5
|
+
using System.Linq.Expressions;
|
|
5
6
|
using System.Reflection;
|
|
7
|
+
using System.Runtime.CompilerServices;
|
|
8
|
+
using Extensions;
|
|
9
|
+
using Helper;
|
|
6
10
|
using Messages;
|
|
7
11
|
using static IMessageBus;
|
|
12
|
+
#if UNITY_2017_1_OR_NEWER
|
|
13
|
+
using UnityEngine;
|
|
14
|
+
#endif
|
|
8
15
|
|
|
9
16
|
/// <summary>
|
|
10
17
|
/// Instanced MessageBus for use cases where you want distinct islands of MessageBuses.
|
|
@@ -34,13 +41,15 @@
|
|
|
34
41
|
int count = 0;
|
|
35
42
|
foreach (var entry in _targetedSinks)
|
|
36
43
|
{
|
|
37
|
-
count += entry.
|
|
44
|
+
count += entry.Count;
|
|
38
45
|
}
|
|
39
46
|
|
|
40
47
|
return count;
|
|
41
48
|
}
|
|
42
49
|
}
|
|
43
50
|
|
|
51
|
+
public int RegisteredGlobalSequentialIndex { get; } = GenerateNewGlobalSequentialIndex();
|
|
52
|
+
|
|
44
53
|
public int RegisteredBroadcast
|
|
45
54
|
{
|
|
46
55
|
get
|
|
@@ -48,7 +57,7 @@
|
|
|
48
57
|
int count = 0;
|
|
49
58
|
foreach (var entry in _broadcastSinks)
|
|
50
59
|
{
|
|
51
|
-
count += entry.
|
|
60
|
+
count += entry.Count;
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
return count;
|
|
@@ -62,7 +71,7 @@
|
|
|
62
71
|
int count = 0;
|
|
63
72
|
foreach (var entry in _sinks)
|
|
64
73
|
{
|
|
65
|
-
count += entry.
|
|
74
|
+
count += entry.handlers.Count;
|
|
66
75
|
}
|
|
67
76
|
|
|
68
77
|
return count;
|
|
@@ -73,9 +82,12 @@
|
|
|
73
82
|
|
|
74
83
|
// For use with re-broadcasting to generic methods
|
|
75
84
|
private static readonly object[] ReflectionMethodArgumentsCache = new object[2];
|
|
85
|
+
private static readonly List<Expression> ArgumentExpressionsCache = new();
|
|
76
86
|
|
|
77
87
|
private const BindingFlags ReflectionHelperBindingFlags =
|
|
78
88
|
BindingFlags.Static | BindingFlags.NonPublic;
|
|
89
|
+
private const BindingFlags ReflexiveMethodBindingFlags =
|
|
90
|
+
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
|
79
91
|
|
|
80
92
|
private delegate void FastUntargetedBroadcast<T>(ref T message)
|
|
81
93
|
where T : IUntargetedMessage;
|
|
@@ -86,44 +98,54 @@
|
|
|
86
98
|
|
|
87
99
|
public RegistrationLog Log => _log;
|
|
88
100
|
|
|
89
|
-
private readonly
|
|
90
|
-
private readonly
|
|
91
|
-
Type,
|
|
101
|
+
private readonly MessageCache<HandlerCache<int, HandlerCache>> _sinks = new();
|
|
102
|
+
private readonly MessageCache<
|
|
92
103
|
Dictionary<InstanceId, HandlerCache<int, HandlerCache>>
|
|
93
104
|
> _targetedSinks = new();
|
|
94
|
-
private readonly
|
|
95
|
-
Type,
|
|
105
|
+
private readonly MessageCache<
|
|
96
106
|
Dictionary<InstanceId, HandlerCache<int, HandlerCache>>
|
|
97
107
|
> _broadcastSinks = new();
|
|
98
|
-
private readonly
|
|
99
|
-
|
|
100
|
-
private readonly Dictionary<
|
|
101
|
-
Type,
|
|
108
|
+
private readonly MessageCache<HandlerCache<int, HandlerCache>> _postProcessingSinks = new();
|
|
109
|
+
private readonly MessageCache<
|
|
102
110
|
Dictionary<InstanceId, HandlerCache<int, HandlerCache>>
|
|
103
111
|
> _postProcessingTargetedSinks = new();
|
|
104
|
-
private readonly
|
|
105
|
-
Type,
|
|
112
|
+
private readonly MessageCache<
|
|
106
113
|
Dictionary<InstanceId, HandlerCache<int, HandlerCache>>
|
|
107
114
|
> _postProcessingBroadcastSinks = new();
|
|
108
|
-
private readonly
|
|
109
|
-
Type,
|
|
115
|
+
private readonly MessageCache<
|
|
110
116
|
HandlerCache<int, HandlerCache>
|
|
111
117
|
> _postProcessingTargetedWithoutTargetingSinks = new();
|
|
112
|
-
private readonly
|
|
113
|
-
Type,
|
|
118
|
+
private readonly MessageCache<
|
|
114
119
|
HandlerCache<int, HandlerCache>
|
|
115
120
|
> _postProcessingBroadcastWithoutSourceSinks = new();
|
|
116
121
|
private readonly HandlerCache _globalSinks = new();
|
|
117
|
-
private readonly
|
|
118
|
-
new();
|
|
122
|
+
private readonly MessageCache<HandlerCache<int, List<object>>> _interceptsByType = new();
|
|
119
123
|
private readonly Dictionary<object, Dictionary<int, int>> _uniqueInterceptorsAndPriorities =
|
|
120
124
|
new();
|
|
121
125
|
|
|
122
126
|
private readonly Dictionary<Type, object> _broadcastMethodsByType = new();
|
|
123
127
|
private readonly Stack<List<object>> _innerInterceptorsStack = new();
|
|
124
128
|
|
|
129
|
+
private readonly Dictionary<
|
|
130
|
+
Type,
|
|
131
|
+
Dictionary<MethodSignatureKey, Action<MonoBehaviour, object[]>>
|
|
132
|
+
> _methodCache = new();
|
|
133
|
+
|
|
134
|
+
#if UNITY_2017_1_OR_NEWER
|
|
135
|
+
private readonly HashSet<MonoBehaviour> _recipientCache = new();
|
|
136
|
+
private readonly List<MonoBehaviour> _componentCache = new();
|
|
137
|
+
#endif
|
|
138
|
+
|
|
125
139
|
private readonly RegistrationLog _log = new();
|
|
126
140
|
|
|
141
|
+
static MessageBus()
|
|
142
|
+
{
|
|
143
|
+
if (!DxMessagingRuntime.Initialized)
|
|
144
|
+
{
|
|
145
|
+
DxMessagingRuntime.Initialize();
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
127
149
|
public Action RegisterUntargeted<T>(MessageHandler messageHandler, int priority = 0)
|
|
128
150
|
where T : IUntargetedMessage
|
|
129
151
|
{
|
|
@@ -352,16 +374,8 @@
|
|
|
352
374
|
where T : IMessage
|
|
353
375
|
{
|
|
354
376
|
Type type = typeof(T);
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
type,
|
|
358
|
-
out HandlerCache<int, List<object>> prioritizedInterceptors
|
|
359
|
-
)
|
|
360
|
-
)
|
|
361
|
-
{
|
|
362
|
-
prioritizedInterceptors = new HandlerCache<int, List<object>>();
|
|
363
|
-
_interceptsByType[type] = prioritizedInterceptors;
|
|
364
|
-
}
|
|
377
|
+
HandlerCache<int, List<object>> prioritizedInterceptors =
|
|
378
|
+
_interceptsByType.GetOrAdd<T>();
|
|
365
379
|
|
|
366
380
|
if (
|
|
367
381
|
!prioritizedInterceptors.handlers.TryGetValue(
|
|
@@ -446,7 +460,7 @@
|
|
|
446
460
|
bool complete = false;
|
|
447
461
|
if (removed)
|
|
448
462
|
{
|
|
449
|
-
if (_interceptsByType.TryGetValue(
|
|
463
|
+
if (_interceptsByType.TryGetValue<T>(out prioritizedInterceptors))
|
|
450
464
|
{
|
|
451
465
|
prioritizedInterceptors.version++;
|
|
452
466
|
if (
|
|
@@ -499,8 +513,7 @@
|
|
|
499
513
|
public void UntargetedBroadcast<TMessage>(ref TMessage typedMessage)
|
|
500
514
|
where TMessage : IUntargetedMessage
|
|
501
515
|
{
|
|
502
|
-
|
|
503
|
-
if (!RunUntargetedInterceptors(type, ref typedMessage))
|
|
516
|
+
if (!RunUntargetedInterceptors(ref typedMessage))
|
|
504
517
|
{
|
|
505
518
|
return;
|
|
506
519
|
}
|
|
@@ -511,11 +524,10 @@
|
|
|
511
524
|
BroadcastGlobalUntargeted(ref untargetedMessage);
|
|
512
525
|
}
|
|
513
526
|
|
|
514
|
-
bool foundAnyHandlers = InternalUntargetedBroadcast(ref typedMessage
|
|
527
|
+
bool foundAnyHandlers = InternalUntargetedBroadcast(ref typedMessage);
|
|
515
528
|
|
|
516
529
|
if (
|
|
517
|
-
_postProcessingSinks.TryGetValue(
|
|
518
|
-
type,
|
|
530
|
+
_postProcessingSinks.TryGetValue<TMessage>(
|
|
519
531
|
out HandlerCache<int, HandlerCache> sortedHandlers
|
|
520
532
|
)
|
|
521
533
|
&& 0 < sortedHandlers.handlers.Count
|
|
@@ -697,8 +709,7 @@
|
|
|
697
709
|
public void TargetedBroadcast<TMessage>(ref InstanceId target, ref TMessage typedMessage)
|
|
698
710
|
where TMessage : ITargetedMessage
|
|
699
711
|
{
|
|
700
|
-
|
|
701
|
-
if (!RunTargetedInterceptors(type, ref typedMessage, ref target))
|
|
712
|
+
if (!RunTargetedInterceptors(ref typedMessage, ref target))
|
|
702
713
|
{
|
|
703
714
|
return;
|
|
704
715
|
}
|
|
@@ -710,15 +721,191 @@
|
|
|
710
721
|
}
|
|
711
722
|
|
|
712
723
|
bool foundAnyHandlers = false;
|
|
724
|
+
Dictionary<InstanceId, HandlerCache<int, HandlerCache>> targetedHandlers;
|
|
725
|
+
HandlerCache<int, HandlerCache> sortedHandlers;
|
|
726
|
+
|
|
727
|
+
if (typeof(TMessage) == typeof(DxReflexiveMessage))
|
|
728
|
+
{
|
|
729
|
+
#if UNITY_2017_1_OR_NEWER
|
|
730
|
+
ref DxReflexiveMessage reflexiveMessage = ref Unsafe.As<
|
|
731
|
+
TMessage,
|
|
732
|
+
DxReflexiveMessage
|
|
733
|
+
>(ref typedMessage);
|
|
734
|
+
|
|
735
|
+
GameObject go;
|
|
736
|
+
bool found;
|
|
737
|
+
UnityEngine.Object targetObject = target.Object;
|
|
738
|
+
switch (targetObject)
|
|
739
|
+
{
|
|
740
|
+
case GameObject gameObject:
|
|
741
|
+
{
|
|
742
|
+
found = true;
|
|
743
|
+
go = gameObject;
|
|
744
|
+
break;
|
|
745
|
+
}
|
|
746
|
+
case Component component:
|
|
747
|
+
{
|
|
748
|
+
found = true;
|
|
749
|
+
go = component.gameObject;
|
|
750
|
+
break;
|
|
751
|
+
}
|
|
752
|
+
default:
|
|
753
|
+
{
|
|
754
|
+
go = null;
|
|
755
|
+
found = false;
|
|
756
|
+
break;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
if (found)
|
|
761
|
+
{
|
|
762
|
+
_recipientCache.Clear();
|
|
763
|
+
bool sentInADirection = false;
|
|
764
|
+
if (reflexiveMessage.sendMode.HasFlagNoAlloc(ReflexiveSendMode.Upwards))
|
|
765
|
+
{
|
|
766
|
+
sentInADirection = true;
|
|
767
|
+
if (
|
|
768
|
+
!reflexiveMessage.sendMode.HasFlagNoAlloc(ReflexiveSendMode.Downwards)
|
|
769
|
+
&& !reflexiveMessage.sendMode.HasFlagNoAlloc(ReflexiveSendMode.Flat)
|
|
770
|
+
)
|
|
771
|
+
{
|
|
772
|
+
switch (reflexiveMessage.parameters.Length)
|
|
773
|
+
{
|
|
774
|
+
case 0:
|
|
775
|
+
{
|
|
776
|
+
go.SendMessageUpwards(reflexiveMessage.method);
|
|
777
|
+
break;
|
|
778
|
+
}
|
|
779
|
+
case 1:
|
|
780
|
+
{
|
|
781
|
+
go.SendMessageUpwards(
|
|
782
|
+
reflexiveMessage.method,
|
|
783
|
+
reflexiveMessage.parameters[0]
|
|
784
|
+
);
|
|
785
|
+
break;
|
|
786
|
+
}
|
|
787
|
+
default:
|
|
788
|
+
{
|
|
789
|
+
Component[] parentComponents = go.GetComponentsInParent(
|
|
790
|
+
typeof(MonoBehaviour),
|
|
791
|
+
true
|
|
792
|
+
);
|
|
793
|
+
foreach (Component component in parentComponents)
|
|
794
|
+
{
|
|
795
|
+
if (component is MonoBehaviour script)
|
|
796
|
+
{
|
|
797
|
+
SendMessage(script, ref reflexiveMessage);
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
break;
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
else
|
|
806
|
+
{
|
|
807
|
+
Component[] parentComponents = go.GetComponentsInParent(
|
|
808
|
+
typeof(MonoBehaviour)
|
|
809
|
+
);
|
|
810
|
+
foreach (Component component in parentComponents)
|
|
811
|
+
{
|
|
812
|
+
if (component is MonoBehaviour script)
|
|
813
|
+
{
|
|
814
|
+
SendMessage(script, ref reflexiveMessage);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
if (reflexiveMessage.sendMode.HasFlagNoAlloc(ReflexiveSendMode.Downwards))
|
|
820
|
+
{
|
|
821
|
+
sentInADirection = true;
|
|
822
|
+
if (
|
|
823
|
+
!reflexiveMessage.sendMode.HasFlagNoAlloc(ReflexiveSendMode.Upwards)
|
|
824
|
+
&& !reflexiveMessage.sendMode.HasFlagNoAlloc(ReflexiveSendMode.Flat)
|
|
825
|
+
)
|
|
826
|
+
{
|
|
827
|
+
switch (reflexiveMessage.parameters.Length)
|
|
828
|
+
{
|
|
829
|
+
case 0:
|
|
830
|
+
{
|
|
831
|
+
go.BroadcastMessage(reflexiveMessage.method);
|
|
832
|
+
break;
|
|
833
|
+
}
|
|
834
|
+
case 1:
|
|
835
|
+
{
|
|
836
|
+
go.BroadcastMessage(
|
|
837
|
+
reflexiveMessage.method,
|
|
838
|
+
reflexiveMessage.parameters[0]
|
|
839
|
+
);
|
|
840
|
+
break;
|
|
841
|
+
}
|
|
842
|
+
default:
|
|
843
|
+
{
|
|
844
|
+
_componentCache.Clear();
|
|
845
|
+
go.GetComponentsInChildren(true, _componentCache);
|
|
846
|
+
foreach (MonoBehaviour parentComponent in _componentCache)
|
|
847
|
+
{
|
|
848
|
+
SendMessage(parentComponent, ref reflexiveMessage);
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
break;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
else
|
|
856
|
+
{
|
|
857
|
+
_componentCache.Clear();
|
|
858
|
+
go.GetComponentsInChildren(_componentCache);
|
|
859
|
+
foreach (MonoBehaviour parentComponent in _componentCache)
|
|
860
|
+
{
|
|
861
|
+
SendMessage(parentComponent, ref reflexiveMessage);
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
else if (
|
|
866
|
+
!sentInADirection
|
|
867
|
+
&& reflexiveMessage.sendMode.HasFlagNoAlloc(ReflexiveSendMode.Flat)
|
|
868
|
+
)
|
|
869
|
+
{
|
|
870
|
+
switch (reflexiveMessage.parameters.Length)
|
|
871
|
+
{
|
|
872
|
+
case 0:
|
|
873
|
+
{
|
|
874
|
+
go.SendMessage(reflexiveMessage.method);
|
|
875
|
+
break;
|
|
876
|
+
}
|
|
877
|
+
case 1:
|
|
878
|
+
{
|
|
879
|
+
go.SendMessage(
|
|
880
|
+
reflexiveMessage.method,
|
|
881
|
+
reflexiveMessage.parameters[0]
|
|
882
|
+
);
|
|
883
|
+
break;
|
|
884
|
+
}
|
|
885
|
+
default:
|
|
886
|
+
{
|
|
887
|
+
_componentCache.Clear();
|
|
888
|
+
go.GetComponents(_componentCache);
|
|
889
|
+
foreach (MonoBehaviour component in _componentCache)
|
|
890
|
+
{
|
|
891
|
+
SendMessage(component, ref reflexiveMessage);
|
|
892
|
+
}
|
|
893
|
+
break;
|
|
894
|
+
}
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
}
|
|
898
|
+
#else
|
|
899
|
+
MessagingDebug.Log(
|
|
900
|
+
LogLevel.Error,
|
|
901
|
+
"Reflexive messages are not supported in this build."
|
|
902
|
+
);
|
|
903
|
+
#endif
|
|
904
|
+
}
|
|
905
|
+
|
|
713
906
|
if (
|
|
714
|
-
_targetedSinks.TryGetValue(
|
|
715
|
-
|
|
716
|
-
out Dictionary<InstanceId, HandlerCache<int, HandlerCache>> targetedHandlers
|
|
717
|
-
)
|
|
718
|
-
&& targetedHandlers.TryGetValue(
|
|
719
|
-
target,
|
|
720
|
-
out HandlerCache<int, HandlerCache> sortedHandlers
|
|
721
|
-
)
|
|
907
|
+
_targetedSinks.TryGetValue<TMessage>(out targetedHandlers)
|
|
908
|
+
&& targetedHandlers.TryGetValue(target, out sortedHandlers)
|
|
722
909
|
&& 0 < sortedHandlers.handlers.Count
|
|
723
910
|
)
|
|
724
911
|
{
|
|
@@ -795,10 +982,10 @@
|
|
|
795
982
|
}
|
|
796
983
|
}
|
|
797
984
|
|
|
798
|
-
_ = InternalTargetedWithoutTargetingBroadcast(ref target, ref typedMessage
|
|
985
|
+
_ = InternalTargetedWithoutTargetingBroadcast(ref target, ref typedMessage);
|
|
799
986
|
|
|
800
987
|
if (
|
|
801
|
-
_postProcessingTargetedSinks.TryGetValue(
|
|
988
|
+
_postProcessingTargetedSinks.TryGetValue<TMessage>(out targetedHandlers)
|
|
802
989
|
&& targetedHandlers.TryGetValue(target, out sortedHandlers)
|
|
803
990
|
&& 0 < sortedHandlers.handlers.Count
|
|
804
991
|
)
|
|
@@ -952,7 +1139,9 @@
|
|
|
952
1139
|
}
|
|
953
1140
|
|
|
954
1141
|
if (
|
|
955
|
-
_postProcessingTargetedWithoutTargetingSinks.TryGetValue(
|
|
1142
|
+
_postProcessingTargetedWithoutTargetingSinks.TryGetValue<TMessage>(
|
|
1143
|
+
out sortedHandlers
|
|
1144
|
+
)
|
|
956
1145
|
&& 0 < sortedHandlers.handlers.Count
|
|
957
1146
|
)
|
|
958
1147
|
{
|
|
@@ -1435,8 +1624,7 @@
|
|
|
1435
1624
|
public void SourcedBroadcast<TMessage>(ref InstanceId source, ref TMessage typedMessage)
|
|
1436
1625
|
where TMessage : IBroadcastMessage
|
|
1437
1626
|
{
|
|
1438
|
-
|
|
1439
|
-
if (!RunBroadcastInterceptors(type, ref typedMessage, ref source))
|
|
1627
|
+
if (!RunBroadcastInterceptors(ref typedMessage, ref source))
|
|
1440
1628
|
{
|
|
1441
1629
|
return;
|
|
1442
1630
|
}
|
|
@@ -1449,8 +1637,7 @@
|
|
|
1449
1637
|
|
|
1450
1638
|
bool foundAnyHandlers = false;
|
|
1451
1639
|
if (
|
|
1452
|
-
_broadcastSinks.TryGetValue(
|
|
1453
|
-
type,
|
|
1640
|
+
_broadcastSinks.TryGetValue<TMessage>(
|
|
1454
1641
|
out Dictionary<InstanceId, HandlerCache<int, HandlerCache>> broadcastHandlers
|
|
1455
1642
|
)
|
|
1456
1643
|
&& broadcastHandlers.TryGetValue(
|
|
@@ -1528,10 +1715,10 @@
|
|
|
1528
1715
|
}
|
|
1529
1716
|
}
|
|
1530
1717
|
|
|
1531
|
-
_ = InternalBroadcastWithoutSource(ref source, ref typedMessage
|
|
1718
|
+
_ = InternalBroadcastWithoutSource(ref source, ref typedMessage);
|
|
1532
1719
|
|
|
1533
1720
|
if (
|
|
1534
|
-
_postProcessingBroadcastSinks.TryGetValue(
|
|
1721
|
+
_postProcessingBroadcastSinks.TryGetValue<TMessage>(out broadcastHandlers)
|
|
1535
1722
|
&& broadcastHandlers.TryGetValue(source, out sortedHandlers)
|
|
1536
1723
|
&& 0 < sortedHandlers.handlers.Count
|
|
1537
1724
|
)
|
|
@@ -1685,7 +1872,7 @@
|
|
|
1685
1872
|
}
|
|
1686
1873
|
|
|
1687
1874
|
if (
|
|
1688
|
-
_postProcessingBroadcastWithoutSourceSinks.TryGetValue(
|
|
1875
|
+
_postProcessingBroadcastWithoutSourceSinks.TryGetValue<TMessage>(out sortedHandlers)
|
|
1689
1876
|
&& 0 < sortedHandlers.handlers.Count
|
|
1690
1877
|
)
|
|
1691
1878
|
{
|
|
@@ -2138,15 +2325,14 @@
|
|
|
2138
2325
|
}
|
|
2139
2326
|
}
|
|
2140
2327
|
|
|
2141
|
-
private bool TryGetInterceptorCaches(
|
|
2142
|
-
Type type,
|
|
2328
|
+
private bool TryGetInterceptorCaches<TMessage>(
|
|
2143
2329
|
out List<KeyValuePair<int, List<object>>> interceptorStack,
|
|
2144
2330
|
out List<object> interceptorObjects
|
|
2145
2331
|
)
|
|
2332
|
+
where TMessage : IMessage
|
|
2146
2333
|
{
|
|
2147
2334
|
if (
|
|
2148
|
-
!_interceptsByType.TryGetValue(
|
|
2149
|
-
type,
|
|
2335
|
+
!_interceptsByType.TryGetValue<TMessage>(
|
|
2150
2336
|
out HandlerCache<int, List<object>> interceptors
|
|
2151
2337
|
)
|
|
2152
2338
|
|| interceptors.handlers.Count == 0
|
|
@@ -2179,12 +2365,11 @@
|
|
|
2179
2365
|
return true;
|
|
2180
2366
|
}
|
|
2181
2367
|
|
|
2182
|
-
private bool RunUntargetedInterceptors<T>(
|
|
2368
|
+
private bool RunUntargetedInterceptors<T>(ref T message)
|
|
2183
2369
|
where T : IUntargetedMessage
|
|
2184
2370
|
{
|
|
2185
2371
|
if (
|
|
2186
|
-
!TryGetInterceptorCaches(
|
|
2187
|
-
type,
|
|
2372
|
+
!TryGetInterceptorCaches<T>(
|
|
2188
2373
|
out List<KeyValuePair<int, List<object>>> interceptorStack,
|
|
2189
2374
|
out List<object> interceptorObjects
|
|
2190
2375
|
)
|
|
@@ -2225,12 +2410,11 @@
|
|
|
2225
2410
|
return true;
|
|
2226
2411
|
}
|
|
2227
2412
|
|
|
2228
|
-
private bool RunTargetedInterceptors<T>(
|
|
2413
|
+
private bool RunTargetedInterceptors<T>(ref T message, ref InstanceId target)
|
|
2229
2414
|
where T : ITargetedMessage
|
|
2230
2415
|
{
|
|
2231
2416
|
if (
|
|
2232
|
-
!TryGetInterceptorCaches(
|
|
2233
|
-
type,
|
|
2417
|
+
!TryGetInterceptorCaches<T>(
|
|
2234
2418
|
out List<KeyValuePair<int, List<object>>> interceptorStack,
|
|
2235
2419
|
out List<object> interceptorObjects
|
|
2236
2420
|
)
|
|
@@ -2271,12 +2455,11 @@
|
|
|
2271
2455
|
return true;
|
|
2272
2456
|
}
|
|
2273
2457
|
|
|
2274
|
-
private bool RunBroadcastInterceptors<T>(
|
|
2458
|
+
private bool RunBroadcastInterceptors<T>(ref T message, ref InstanceId source)
|
|
2275
2459
|
where T : IBroadcastMessage
|
|
2276
2460
|
{
|
|
2277
2461
|
if (
|
|
2278
|
-
!TryGetInterceptorCaches(
|
|
2279
|
-
type,
|
|
2462
|
+
!TryGetInterceptorCaches<T>(
|
|
2280
2463
|
out List<KeyValuePair<int, List<object>>> interceptorStack,
|
|
2281
2464
|
out List<object> interceptorObjects
|
|
2282
2465
|
)
|
|
@@ -2317,11 +2500,11 @@
|
|
|
2317
2500
|
return true;
|
|
2318
2501
|
}
|
|
2319
2502
|
|
|
2320
|
-
private bool InternalUntargetedBroadcast<TMessage>(ref TMessage message
|
|
2503
|
+
private bool InternalUntargetedBroadcast<TMessage>(ref TMessage message)
|
|
2321
2504
|
where TMessage : IMessage
|
|
2322
2505
|
{
|
|
2323
2506
|
if (
|
|
2324
|
-
!_sinks.TryGetValue(
|
|
2507
|
+
!_sinks.TryGetValue<TMessage>(out HandlerCache<int, HandlerCache> sortedHandlers)
|
|
2325
2508
|
|| sortedHandlers.handlers.Count == 0
|
|
2326
2509
|
)
|
|
2327
2510
|
{
|
|
@@ -2452,13 +2635,12 @@
|
|
|
2452
2635
|
|
|
2453
2636
|
private bool InternalTargetedWithoutTargetingBroadcast<TMessage>(
|
|
2454
2637
|
ref InstanceId target,
|
|
2455
|
-
ref TMessage message
|
|
2456
|
-
Type type
|
|
2638
|
+
ref TMessage message
|
|
2457
2639
|
)
|
|
2458
2640
|
where TMessage : ITargetedMessage
|
|
2459
2641
|
{
|
|
2460
2642
|
if (
|
|
2461
|
-
!_sinks.TryGetValue(
|
|
2643
|
+
!_sinks.TryGetValue<TMessage>(out HandlerCache<int, HandlerCache> sortedHandlers)
|
|
2462
2644
|
|| sortedHandlers.handlers.Count == 0
|
|
2463
2645
|
)
|
|
2464
2646
|
{
|
|
@@ -2607,13 +2789,12 @@
|
|
|
2607
2789
|
|
|
2608
2790
|
private bool InternalBroadcastWithoutSource<TMessage>(
|
|
2609
2791
|
ref InstanceId source,
|
|
2610
|
-
ref TMessage message
|
|
2611
|
-
Type type
|
|
2792
|
+
ref TMessage message
|
|
2612
2793
|
)
|
|
2613
2794
|
where TMessage : IBroadcastMessage
|
|
2614
2795
|
{
|
|
2615
2796
|
if (
|
|
2616
|
-
!_sinks.TryGetValue(
|
|
2797
|
+
!_sinks.TryGetValue<TMessage>(out HandlerCache<int, HandlerCache> sortedHandlers)
|
|
2617
2798
|
|| sortedHandlers.handlers.Count == 0
|
|
2618
2799
|
)
|
|
2619
2800
|
{
|
|
@@ -2841,7 +3022,7 @@
|
|
|
2841
3022
|
|
|
2842
3023
|
private Action InternalRegisterUntargeted<T>(
|
|
2843
3024
|
MessageHandler messageHandler,
|
|
2844
|
-
|
|
3025
|
+
MessageCache<HandlerCache<int, HandlerCache>> sinks,
|
|
2845
3026
|
RegistrationMethod registrationMethod,
|
|
2846
3027
|
int priority
|
|
2847
3028
|
)
|
|
@@ -2855,11 +3036,7 @@
|
|
|
2855
3036
|
InstanceId handlerOwnerId = messageHandler.owner;
|
|
2856
3037
|
Type type = typeof(T);
|
|
2857
3038
|
|
|
2858
|
-
|
|
2859
|
-
{
|
|
2860
|
-
handlers = new HandlerCache<int, HandlerCache>();
|
|
2861
|
-
sinks[type] = handlers;
|
|
2862
|
-
}
|
|
3039
|
+
HandlerCache<int, HandlerCache> handlers = sinks.GetOrAdd<T>();
|
|
2863
3040
|
|
|
2864
3041
|
if (!handlers.handlers.TryGetValue(priority, out HandlerCache cache))
|
|
2865
3042
|
{
|
|
@@ -2894,7 +3071,7 @@
|
|
|
2894
3071
|
)
|
|
2895
3072
|
);
|
|
2896
3073
|
if (
|
|
2897
|
-
!sinks.TryGetValue(
|
|
3074
|
+
!sinks.TryGetValue<T>(out handlers)
|
|
2898
3075
|
|| !handlers.handlers.TryGetValue(priority, out cache)
|
|
2899
3076
|
|| !cache.handlers.TryGetValue(messageHandler, out count)
|
|
2900
3077
|
)
|
|
@@ -2925,7 +3102,7 @@
|
|
|
2925
3102
|
|
|
2926
3103
|
if (handlers.handlers.Count == 0)
|
|
2927
3104
|
{
|
|
2928
|
-
|
|
3105
|
+
sinks.Remove<T>();
|
|
2929
3106
|
}
|
|
2930
3107
|
|
|
2931
3108
|
if (!complete && MessagingDebug.enabled)
|
|
@@ -2948,10 +3125,11 @@
|
|
|
2948
3125
|
private Action InternalRegisterWithContext<T>(
|
|
2949
3126
|
InstanceId context,
|
|
2950
3127
|
MessageHandler messageHandler,
|
|
2951
|
-
|
|
3128
|
+
MessageCache<Dictionary<InstanceId, HandlerCache<int, HandlerCache>>> sinks,
|
|
2952
3129
|
RegistrationMethod registrationMethod,
|
|
2953
3130
|
int priority
|
|
2954
3131
|
)
|
|
3132
|
+
where T : IMessage
|
|
2955
3133
|
{
|
|
2956
3134
|
if (messageHandler == null)
|
|
2957
3135
|
{
|
|
@@ -2959,16 +3137,8 @@
|
|
|
2959
3137
|
}
|
|
2960
3138
|
|
|
2961
3139
|
Type type = typeof(T);
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
type,
|
|
2965
|
-
out Dictionary<InstanceId, HandlerCache<int, HandlerCache>> broadcastHandlers
|
|
2966
|
-
)
|
|
2967
|
-
)
|
|
2968
|
-
{
|
|
2969
|
-
broadcastHandlers = new Dictionary<InstanceId, HandlerCache<int, HandlerCache>>();
|
|
2970
|
-
sinks[type] = broadcastHandlers;
|
|
2971
|
-
}
|
|
3140
|
+
Dictionary<InstanceId, HandlerCache<int, HandlerCache>> broadcastHandlers =
|
|
3141
|
+
sinks.GetOrAdd<T>();
|
|
2972
3142
|
|
|
2973
3143
|
if (
|
|
2974
3144
|
!broadcastHandlers.TryGetValue(
|
|
@@ -3014,7 +3184,7 @@
|
|
|
3014
3184
|
)
|
|
3015
3185
|
);
|
|
3016
3186
|
if (
|
|
3017
|
-
!sinks.TryGetValue(
|
|
3187
|
+
!sinks.TryGetValue<T>(out broadcastHandlers)
|
|
3018
3188
|
|| !broadcastHandlers.TryGetValue(context, out handlers)
|
|
3019
3189
|
|| !handlers.handlers.TryGetValue(priority, out cache)
|
|
3020
3190
|
|| !cache.handlers.TryGetValue(messageHandler, out count)
|
|
@@ -3050,7 +3220,7 @@
|
|
|
3050
3220
|
|
|
3051
3221
|
if (broadcastHandlers.Count == 0)
|
|
3052
3222
|
{
|
|
3053
|
-
|
|
3223
|
+
sinks.Remove<T>();
|
|
3054
3224
|
}
|
|
3055
3225
|
|
|
3056
3226
|
if (!complete && MessagingDebug.enabled)
|
|
@@ -3180,5 +3350,137 @@
|
|
|
3180
3350
|
sourcedBroadcast(ref target, ref typedMessage);
|
|
3181
3351
|
}
|
|
3182
3352
|
}
|
|
3353
|
+
|
|
3354
|
+
#if UNITY_2017_1_OR_NEWER
|
|
3355
|
+
private static Action<MonoBehaviour, object[]> CompileMethodAction(MethodInfo methodInfo)
|
|
3356
|
+
{
|
|
3357
|
+
ParameterExpression componentParameter = Expression.Parameter(
|
|
3358
|
+
typeof(MonoBehaviour),
|
|
3359
|
+
"targetComponent"
|
|
3360
|
+
);
|
|
3361
|
+
ParameterExpression argsParameter = Expression.Parameter(typeof(object[]), "args");
|
|
3362
|
+
ParameterInfo[] methodParams = methodInfo.GetParameters();
|
|
3363
|
+
|
|
3364
|
+
ArgumentExpressionsCache.Clear();
|
|
3365
|
+
for (int i = 0; i < methodParams.Length; ++i)
|
|
3366
|
+
{
|
|
3367
|
+
Expression indexAccess = Expression.ArrayIndex(
|
|
3368
|
+
argsParameter,
|
|
3369
|
+
Expression.Constant(i)
|
|
3370
|
+
);
|
|
3371
|
+
Expression convertedArg = Expression.Convert(
|
|
3372
|
+
indexAccess,
|
|
3373
|
+
methodParams[i].ParameterType
|
|
3374
|
+
);
|
|
3375
|
+
ArgumentExpressionsCache.Add(convertedArg);
|
|
3376
|
+
}
|
|
3377
|
+
|
|
3378
|
+
// ReSharper disable once AssignNullToNotNullAttribute
|
|
3379
|
+
Expression instanceExpression = methodInfo.IsStatic
|
|
3380
|
+
? null
|
|
3381
|
+
: Expression.Convert(componentParameter, methodInfo.DeclaringType);
|
|
3382
|
+
MethodCallExpression callExpression = Expression.Call(
|
|
3383
|
+
instanceExpression,
|
|
3384
|
+
methodInfo,
|
|
3385
|
+
ArgumentExpressionsCache
|
|
3386
|
+
);
|
|
3387
|
+
Expression<Action<MonoBehaviour, object[]>> lambda = Expression.Lambda<
|
|
3388
|
+
Action<MonoBehaviour, object[]>
|
|
3389
|
+
>(callExpression, componentParameter, argsParameter);
|
|
3390
|
+
|
|
3391
|
+
return lambda.Compile();
|
|
3392
|
+
}
|
|
3393
|
+
#endif
|
|
3394
|
+
|
|
3395
|
+
private void SendMessage(MonoBehaviour recipient, ref DxReflexiveMessage message)
|
|
3396
|
+
{
|
|
3397
|
+
if (!_recipientCache.Add(recipient))
|
|
3398
|
+
{
|
|
3399
|
+
return;
|
|
3400
|
+
}
|
|
3401
|
+
|
|
3402
|
+
Type componentType = recipient.GetType();
|
|
3403
|
+
if (
|
|
3404
|
+
!_methodCache.TryGetValue(
|
|
3405
|
+
componentType,
|
|
3406
|
+
out Dictionary<MethodSignatureKey, Action<MonoBehaviour, object[]>> methodCache
|
|
3407
|
+
)
|
|
3408
|
+
)
|
|
3409
|
+
{
|
|
3410
|
+
_methodCache[componentType] = methodCache =
|
|
3411
|
+
new Dictionary<MethodSignatureKey, Action<MonoBehaviour, object[]>>();
|
|
3412
|
+
}
|
|
3413
|
+
|
|
3414
|
+
MethodSignatureKey lookupKey = message.signatureKey;
|
|
3415
|
+
if (!methodCache.TryGetValue(lookupKey, out Action<MonoBehaviour, object[]> method))
|
|
3416
|
+
{
|
|
3417
|
+
MethodInfo methodInfo = null;
|
|
3418
|
+
try
|
|
3419
|
+
{
|
|
3420
|
+
methodInfo = componentType.GetMethod(
|
|
3421
|
+
message.method,
|
|
3422
|
+
ReflexiveMethodBindingFlags,
|
|
3423
|
+
null,
|
|
3424
|
+
message.parameterTypes,
|
|
3425
|
+
null
|
|
3426
|
+
);
|
|
3427
|
+
}
|
|
3428
|
+
catch (AmbiguousMatchException)
|
|
3429
|
+
{
|
|
3430
|
+
MethodInfo[] matchingMethods = componentType.GetMethods(
|
|
3431
|
+
ReflexiveMethodBindingFlags
|
|
3432
|
+
);
|
|
3433
|
+
foreach (MethodInfo matchingMethod in matchingMethods)
|
|
3434
|
+
{
|
|
3435
|
+
if (
|
|
3436
|
+
!string.Equals(
|
|
3437
|
+
matchingMethod.Name,
|
|
3438
|
+
message.method,
|
|
3439
|
+
StringComparison.Ordinal
|
|
3440
|
+
)
|
|
3441
|
+
|| !ParameterTypesMatch(
|
|
3442
|
+
matchingMethod.GetParameters(),
|
|
3443
|
+
message.parameterTypes
|
|
3444
|
+
)
|
|
3445
|
+
)
|
|
3446
|
+
{
|
|
3447
|
+
continue;
|
|
3448
|
+
}
|
|
3449
|
+
|
|
3450
|
+
methodInfo = matchingMethod;
|
|
3451
|
+
break;
|
|
3452
|
+
}
|
|
3453
|
+
}
|
|
3454
|
+
catch
|
|
3455
|
+
{
|
|
3456
|
+
methodInfo = null;
|
|
3457
|
+
}
|
|
3458
|
+
|
|
3459
|
+
if (methodInfo != null)
|
|
3460
|
+
{
|
|
3461
|
+
method = CompileMethodAction(methodInfo);
|
|
3462
|
+
}
|
|
3463
|
+
methodCache[lookupKey] = method;
|
|
3464
|
+
}
|
|
3465
|
+
|
|
3466
|
+
method?.Invoke(recipient, message.parameters);
|
|
3467
|
+
}
|
|
3468
|
+
|
|
3469
|
+
private static bool ParameterTypesMatch(ParameterInfo[] methodParams, Type[] expectedTypes)
|
|
3470
|
+
{
|
|
3471
|
+
if (methodParams.Length != expectedTypes.Length)
|
|
3472
|
+
{
|
|
3473
|
+
return false;
|
|
3474
|
+
}
|
|
3475
|
+
|
|
3476
|
+
for (int i = 0; i < methodParams.Length; ++i)
|
|
3477
|
+
{
|
|
3478
|
+
if (methodParams[i].ParameterType != expectedTypes[i])
|
|
3479
|
+
{
|
|
3480
|
+
return false;
|
|
3481
|
+
}
|
|
3482
|
+
}
|
|
3483
|
+
return true;
|
|
3484
|
+
}
|
|
3183
3485
|
}
|
|
3184
3486
|
}
|