com.wallstop-studios.dxmessaging 2.0.0-rc06 → 2.0.0-rc08
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Runtime/Core/InstanceId.cs +41 -14
- package/Runtime/Core/MessageBus/IMessageBus.cs +84 -24
- package/Runtime/Core/MessageBus/MessageBus.cs +915 -251
- package/Runtime/Core/MessageHandler.cs +1455 -328
- package/Runtime/Core/MessageRegistrationHandle.cs +71 -16
- package/Runtime/Core/MessageRegistrationToken.cs +534 -185
- package/Runtime/Unity/MessagingComponent.cs +33 -18
- package/Tests/Runtime/Benchmarks/PerformanceTests.cs +139 -25
- package/Tests/Runtime/Core/BroadcastTests.cs +350 -51
- package/Tests/Runtime/Core/TargetedTests.cs +345 -53
- package/Tests/Runtime/Core/UntargetedTests.cs +130 -7
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.asmdef +2 -1
- package/package.json +2 -2
- package/Tests/Editor.meta +0 -8
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
namespace DxMessaging.Unity
|
|
2
2
|
{
|
|
3
|
-
using Core;
|
|
4
3
|
using System;
|
|
5
4
|
using System.Collections.Generic;
|
|
5
|
+
using Core;
|
|
6
6
|
using UnityEngine;
|
|
7
|
+
using UnityEngine.Serialization;
|
|
7
8
|
|
|
8
9
|
[DisallowMultipleComponent]
|
|
9
10
|
public sealed class MessagingComponent : MonoBehaviour
|
|
10
11
|
{
|
|
11
|
-
[
|
|
12
|
-
|
|
12
|
+
[FormerlySerializedAs("_emitMessagesWhenDisabled")]
|
|
13
|
+
public bool emitMessagesWhenDisabled;
|
|
13
14
|
|
|
14
15
|
private MessageHandler _messageHandler;
|
|
15
16
|
|
|
16
17
|
private readonly Dictionary<MonoBehaviour, MessageRegistrationToken> _registeredListeners =
|
|
17
|
-
new
|
|
18
|
+
new();
|
|
18
19
|
|
|
19
20
|
public MessageRegistrationToken Create(MonoBehaviour listener)
|
|
20
21
|
{
|
|
@@ -25,32 +26,46 @@
|
|
|
25
26
|
|
|
26
27
|
if (gameObject.GetInstanceID() != listener.gameObject.GetInstanceID())
|
|
27
28
|
{
|
|
28
|
-
throw new ArgumentException(
|
|
29
|
+
throw new ArgumentException(
|
|
30
|
+
$"Cannot create a RegistrationToken without an valid owner. {listener.gameObject.GetInstanceID()}."
|
|
31
|
+
);
|
|
29
32
|
}
|
|
30
33
|
|
|
31
|
-
if (
|
|
34
|
+
if (
|
|
35
|
+
_registeredListeners.TryGetValue(
|
|
36
|
+
listener,
|
|
37
|
+
out MessageRegistrationToken createdToken
|
|
38
|
+
)
|
|
39
|
+
)
|
|
32
40
|
{
|
|
33
|
-
MessagingDebug.Log(
|
|
41
|
+
MessagingDebug.Log(
|
|
42
|
+
LogLevel.Warn,
|
|
43
|
+
"Ignoring double RegistrationToken request for {0}.",
|
|
44
|
+
listener
|
|
45
|
+
);
|
|
34
46
|
return createdToken;
|
|
35
47
|
}
|
|
36
48
|
|
|
37
49
|
if (_messageHandler == null)
|
|
38
50
|
{
|
|
39
|
-
_messageHandler = new MessageHandler(gameObject)
|
|
40
|
-
{
|
|
41
|
-
active = true
|
|
42
|
-
};
|
|
51
|
+
_messageHandler = new MessageHandler(gameObject) { active = true };
|
|
43
52
|
MessagingDebug.Log(
|
|
44
53
|
LogLevel.Debug,
|
|
45
54
|
"Creating MessageHandler for componentType {0}, GameObject name: {1}, InstanceId: {2}.",
|
|
46
|
-
listener.GetType(),
|
|
55
|
+
listener.GetType(),
|
|
56
|
+
listener.gameObject.name,
|
|
57
|
+
(InstanceId)gameObject
|
|
58
|
+
);
|
|
47
59
|
}
|
|
48
60
|
else
|
|
49
61
|
{
|
|
50
62
|
MessagingDebug.Log(
|
|
51
63
|
LogLevel.Debug,
|
|
52
64
|
"Using existing MessageHandler for componentType {0}, GameObject name: {1}, InstanceId: {2}.",
|
|
53
|
-
listener.GetType(),
|
|
65
|
+
listener.GetType(),
|
|
66
|
+
listener.gameObject.name,
|
|
67
|
+
(InstanceId)gameObject
|
|
68
|
+
);
|
|
54
69
|
}
|
|
55
70
|
|
|
56
71
|
createdToken = MessageRegistrationToken.Create(_messageHandler);
|
|
@@ -58,19 +73,19 @@
|
|
|
58
73
|
return createdToken;
|
|
59
74
|
}
|
|
60
75
|
|
|
61
|
-
|
|
76
|
+
public void OnEnable()
|
|
62
77
|
{
|
|
63
78
|
ToggleMessageHandler(true);
|
|
64
79
|
}
|
|
65
80
|
|
|
66
|
-
|
|
81
|
+
public void OnDisable()
|
|
67
82
|
{
|
|
68
83
|
ToggleMessageHandler(false);
|
|
69
84
|
}
|
|
70
85
|
|
|
71
|
-
|
|
86
|
+
public void ToggleMessageHandler(bool newActive)
|
|
72
87
|
{
|
|
73
|
-
if (!newActive &&
|
|
88
|
+
if (!newActive && emitMessagesWhenDisabled)
|
|
74
89
|
{
|
|
75
90
|
return;
|
|
76
91
|
}
|
|
@@ -81,4 +96,4 @@
|
|
|
81
96
|
}
|
|
82
97
|
}
|
|
83
98
|
}
|
|
84
|
-
}
|
|
99
|
+
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
using Core;
|
|
7
7
|
using DxMessaging.Core;
|
|
8
8
|
using DxMessaging.Core.Extensions;
|
|
9
|
+
using global::Unity.PerformanceTesting;
|
|
9
10
|
using NUnit.Framework;
|
|
10
11
|
using Scripts.Components;
|
|
11
12
|
using Scripts.Messages;
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
public override void Setup()
|
|
21
22
|
{
|
|
22
23
|
base.Setup();
|
|
23
|
-
MessagingDebug.LogFunction = (
|
|
24
|
+
MessagingDebug.LogFunction = (_, _) => { };
|
|
24
25
|
}
|
|
25
26
|
|
|
26
27
|
[UnityTest]
|
|
@@ -39,23 +40,109 @@
|
|
|
39
40
|
RunTest(component => NormalComponent(timer, timeout, component, message));
|
|
40
41
|
RunTest(component => NoCopyGameObject(timer, timeout, component, message));
|
|
41
42
|
RunTest(component => NoCopyComponent(timer, timeout, component, message));
|
|
42
|
-
|
|
43
|
+
|
|
43
44
|
SimpleUntargetedMessage untargetedMessage = new();
|
|
44
45
|
RunTest(component => NoCopyUntargeted(timer, timeout, component, untargetedMessage));
|
|
45
46
|
yield break;
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
[UnityTest]
|
|
50
|
+
[Performance]
|
|
51
|
+
public IEnumerator BenchmarkBroadcast()
|
|
52
|
+
{
|
|
53
|
+
GameObject go = CreateGameObject();
|
|
54
|
+
MessageRegistrationToken token = GetToken(
|
|
55
|
+
go.GetComponent<EmptyMessageAwareComponent>()
|
|
56
|
+
);
|
|
57
|
+
int count = 0;
|
|
58
|
+
token.RegisterGameObjectBroadcast<SimpleBroadcastMessage>(go, Handle);
|
|
59
|
+
|
|
60
|
+
SimpleBroadcastMessage message = new();
|
|
61
|
+
|
|
62
|
+
Measure
|
|
63
|
+
.Method(() => message.EmitGameObjectBroadcast(go))
|
|
64
|
+
.WarmupCount(10)
|
|
65
|
+
.IterationsPerMeasurement(10)
|
|
66
|
+
.MeasurementCount(1_000)
|
|
67
|
+
.Run();
|
|
68
|
+
yield break;
|
|
69
|
+
|
|
70
|
+
void Handle(SimpleBroadcastMessage _)
|
|
71
|
+
{
|
|
72
|
+
++count;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
[UnityTest]
|
|
77
|
+
[Performance]
|
|
78
|
+
public IEnumerator BenchmarkTargeted()
|
|
79
|
+
{
|
|
80
|
+
GameObject go = CreateGameObject();
|
|
81
|
+
MessageRegistrationToken token = GetToken(
|
|
82
|
+
go.GetComponent<EmptyMessageAwareComponent>()
|
|
83
|
+
);
|
|
84
|
+
int count = 0;
|
|
85
|
+
token.RegisterGameObjectTargeted<SimpleTargetedMessage>(go, Handle);
|
|
86
|
+
|
|
87
|
+
SimpleTargetedMessage message = new();
|
|
88
|
+
|
|
89
|
+
Measure
|
|
90
|
+
.Method(() => message.EmitGameObjectTargeted(go))
|
|
91
|
+
.WarmupCount(10)
|
|
92
|
+
.IterationsPerMeasurement(10)
|
|
93
|
+
.MeasurementCount(1_000)
|
|
94
|
+
.Run();
|
|
95
|
+
yield break;
|
|
96
|
+
|
|
97
|
+
void Handle(SimpleTargetedMessage _)
|
|
98
|
+
{
|
|
99
|
+
++count;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
[UnityTest]
|
|
104
|
+
[Performance]
|
|
105
|
+
public IEnumerator BenchmarkUntargeted()
|
|
106
|
+
{
|
|
107
|
+
GameObject go = CreateGameObject();
|
|
108
|
+
MessageRegistrationToken token = GetToken(
|
|
109
|
+
go.GetComponent<EmptyMessageAwareComponent>()
|
|
110
|
+
);
|
|
111
|
+
int count = 0;
|
|
112
|
+
token.RegisterUntargeted<SimpleUntargetedMessage>(Handle);
|
|
113
|
+
|
|
114
|
+
SimpleUntargetedMessage message = new();
|
|
115
|
+
|
|
116
|
+
Measure
|
|
117
|
+
.Method(() => message.EmitUntargeted())
|
|
118
|
+
.WarmupCount(10)
|
|
119
|
+
.IterationsPerMeasurement(10)
|
|
120
|
+
.MeasurementCount(1_000)
|
|
121
|
+
.Run();
|
|
122
|
+
yield break;
|
|
123
|
+
|
|
124
|
+
void Handle(SimpleUntargetedMessage _)
|
|
125
|
+
{
|
|
126
|
+
++count;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
48
130
|
private GameObject CreateGameObject()
|
|
49
131
|
{
|
|
50
132
|
GameObject target = new(
|
|
51
|
-
nameof(Benchmark),
|
|
52
|
-
typeof(
|
|
133
|
+
nameof(Benchmark),
|
|
134
|
+
typeof(EmptyMessageAwareComponent),
|
|
135
|
+
typeof(SpriteRenderer),
|
|
136
|
+
typeof(Rigidbody2D),
|
|
137
|
+
typeof(CircleCollider2D),
|
|
138
|
+
typeof(LineRenderer)
|
|
139
|
+
);
|
|
53
140
|
_spawned.Add(target);
|
|
54
141
|
|
|
55
142
|
return target;
|
|
56
143
|
}
|
|
57
144
|
|
|
58
|
-
private void DisplayCount(string testName, int count, TimeSpan timeout)
|
|
145
|
+
private static void DisplayCount(string testName, int count, TimeSpan timeout)
|
|
59
146
|
{
|
|
60
147
|
Debug.Log($"| {testName} | {Math.Floor(count / timeout.TotalSeconds):N0} |");
|
|
61
148
|
}
|
|
@@ -74,7 +161,12 @@
|
|
|
74
161
|
}
|
|
75
162
|
}
|
|
76
163
|
|
|
77
|
-
private void Unity(
|
|
164
|
+
private static void Unity(
|
|
165
|
+
Stopwatch timer,
|
|
166
|
+
TimeSpan timeout,
|
|
167
|
+
GameObject target,
|
|
168
|
+
ComplexTargetedMessage message
|
|
169
|
+
)
|
|
78
170
|
{
|
|
79
171
|
int count = 0;
|
|
80
172
|
var component = target.AddComponent<SimpleMessageAwareComponent>();
|
|
@@ -82,13 +174,20 @@
|
|
|
82
174
|
timer.Restart();
|
|
83
175
|
do
|
|
84
176
|
{
|
|
85
|
-
target.SendMessage(
|
|
86
|
-
|
|
87
|
-
|
|
177
|
+
target.SendMessage(
|
|
178
|
+
nameof(SimpleMessageAwareComponent.HandleSlowComplexTargetedMessage),
|
|
179
|
+
message
|
|
180
|
+
);
|
|
181
|
+
} while (timer.Elapsed < timeout);
|
|
88
182
|
DisplayCount("Unity", count, timeout);
|
|
89
183
|
}
|
|
90
184
|
|
|
91
|
-
private void NormalGameObject(
|
|
185
|
+
private void NormalGameObject(
|
|
186
|
+
Stopwatch timer,
|
|
187
|
+
TimeSpan timeout,
|
|
188
|
+
EmptyMessageAwareComponent component,
|
|
189
|
+
ComplexTargetedMessage message
|
|
190
|
+
)
|
|
92
191
|
{
|
|
93
192
|
int count = 0;
|
|
94
193
|
var token = GetToken(component);
|
|
@@ -104,12 +203,16 @@
|
|
|
104
203
|
do
|
|
105
204
|
{
|
|
106
205
|
message.EmitGameObjectTargeted(go);
|
|
107
|
-
}
|
|
108
|
-
while (timer.Elapsed < timeout);
|
|
206
|
+
} while (timer.Elapsed < timeout);
|
|
109
207
|
DisplayCount("DxMessaging (GameObject) - Normal", count, timeout);
|
|
110
208
|
}
|
|
111
209
|
|
|
112
|
-
private void NormalComponent(
|
|
210
|
+
private void NormalComponent(
|
|
211
|
+
Stopwatch timer,
|
|
212
|
+
TimeSpan timeout,
|
|
213
|
+
EmptyMessageAwareComponent component,
|
|
214
|
+
ComplexTargetedMessage message
|
|
215
|
+
)
|
|
113
216
|
{
|
|
114
217
|
int count = 0;
|
|
115
218
|
var token = GetToken(component);
|
|
@@ -124,12 +227,16 @@
|
|
|
124
227
|
do
|
|
125
228
|
{
|
|
126
229
|
message.EmitComponentTargeted(component);
|
|
127
|
-
}
|
|
128
|
-
while (timer.Elapsed < timeout);
|
|
230
|
+
} while (timer.Elapsed < timeout);
|
|
129
231
|
DisplayCount("DxMessaging (Component) - Normal", count, timeout);
|
|
130
232
|
}
|
|
131
233
|
|
|
132
|
-
private void NoCopyGameObject(
|
|
234
|
+
private void NoCopyGameObject(
|
|
235
|
+
Stopwatch timer,
|
|
236
|
+
TimeSpan timeout,
|
|
237
|
+
EmptyMessageAwareComponent component,
|
|
238
|
+
ComplexTargetedMessage message
|
|
239
|
+
)
|
|
133
240
|
{
|
|
134
241
|
int count = 0;
|
|
135
242
|
var token = GetToken(component);
|
|
@@ -146,12 +253,16 @@
|
|
|
146
253
|
do
|
|
147
254
|
{
|
|
148
255
|
message.EmitGameObjectTargeted(component.gameObject);
|
|
149
|
-
}
|
|
150
|
-
while (timer.Elapsed < timeout);
|
|
256
|
+
} while (timer.Elapsed < timeout);
|
|
151
257
|
DisplayCount("DxMessaging (GameObject) - No-Copy", count, timeout);
|
|
152
258
|
}
|
|
153
259
|
|
|
154
|
-
private void NoCopyComponent(
|
|
260
|
+
private void NoCopyComponent(
|
|
261
|
+
Stopwatch timer,
|
|
262
|
+
TimeSpan timeout,
|
|
263
|
+
EmptyMessageAwareComponent component,
|
|
264
|
+
ComplexTargetedMessage message
|
|
265
|
+
)
|
|
155
266
|
{
|
|
156
267
|
int count = 0;
|
|
157
268
|
var token = GetToken(component);
|
|
@@ -167,12 +278,16 @@
|
|
|
167
278
|
do
|
|
168
279
|
{
|
|
169
280
|
message.EmitComponentTargeted(component);
|
|
170
|
-
}
|
|
171
|
-
while (timer.Elapsed < timeout);
|
|
281
|
+
} while (timer.Elapsed < timeout);
|
|
172
282
|
DisplayCount("DxMessaging (Component) - No-Copy", count, timeout);
|
|
173
283
|
}
|
|
174
284
|
|
|
175
|
-
private void NoCopyUntargeted(
|
|
285
|
+
private void NoCopyUntargeted(
|
|
286
|
+
Stopwatch timer,
|
|
287
|
+
TimeSpan timeout,
|
|
288
|
+
EmptyMessageAwareComponent component,
|
|
289
|
+
SimpleUntargetedMessage message
|
|
290
|
+
)
|
|
176
291
|
{
|
|
177
292
|
int count = 0;
|
|
178
293
|
var token = GetToken(component);
|
|
@@ -188,9 +303,8 @@
|
|
|
188
303
|
do
|
|
189
304
|
{
|
|
190
305
|
message.EmitUntargeted();
|
|
191
|
-
}
|
|
192
|
-
while (timer.Elapsed < timeout);
|
|
306
|
+
} while (timer.Elapsed < timeout);
|
|
193
307
|
DisplayCount("DxMessaging (Untargeted) - No-Copy", count, timeout);
|
|
194
308
|
}
|
|
195
309
|
}
|
|
196
|
-
}
|
|
310
|
+
}
|