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.
Files changed (32) hide show
  1. package/.github/workflows/npm-publish.yml +9 -0
  2. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
  3. package/README.md +12 -7
  4. package/Runtime/Core/Extensions/EnumExtensions.cs +37 -0
  5. package/Runtime/Core/Extensions/EnumExtensions.cs.meta +3 -0
  6. package/Runtime/Core/Helper/DxMessagingRuntime.cs +201 -0
  7. package/Runtime/Core/Helper/DxMessagingRuntime.cs.meta +3 -0
  8. package/Runtime/Core/Helper/MessageCache.cs +105 -0
  9. package/Runtime/Core/Helper/MessageCache.cs.meta +3 -0
  10. package/Runtime/Core/Helper/MessageHelperIndexer.cs +9 -0
  11. package/Runtime/Core/Helper/MessageHelperIndexer.cs.meta +3 -0
  12. package/Runtime/Core/Helper.meta +3 -0
  13. package/Runtime/Core/IMessage.cs +0 -13
  14. package/Runtime/Core/InstanceId.cs +0 -2
  15. package/Runtime/Core/MessageBus/IMessageBus.cs +10 -3
  16. package/Runtime/Core/MessageBus/MessageBus.cs +400 -98
  17. package/Runtime/Core/MessageHandler.cs +51 -119
  18. package/Runtime/Core/Messages/DxReflexiveMessage.cs +132 -0
  19. package/Runtime/Core/Messages/DxReflexiveMessage.cs.meta +3 -0
  20. package/Runtime/Core/MessagingDebug.cs +1 -1
  21. package/Runtime/Unity/MessageAwareComponent.cs +34 -13
  22. package/Runtime/Unity/Messages/GlobalStringMessage.cs +15 -0
  23. package/Runtime/Unity/Messages/GlobalStringMessage.cs.meta +3 -0
  24. package/Runtime/Unity/Messages/StringMessage.cs +15 -0
  25. package/Runtime/Unity/Messages/StringMessage.cs.meta +3 -0
  26. package/Runtime/Unity/Messages.meta +3 -0
  27. package/Runtime/WallstopStudios.DxMessaging.asmdef +1 -1
  28. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxMessageIdGenerator.cs +255 -394
  29. package/Tests/Runtime/Benchmarks/PerformanceTests.cs +141 -1
  30. package/Tests/Runtime/Core/MessagingTestBase.cs +3 -11
  31. package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs +12 -0
  32. package/package.json +1 -1
@@ -5,6 +5,7 @@
5
5
  using Core;
6
6
  using DxMessaging.Core;
7
7
  using DxMessaging.Core.Extensions;
8
+ using DxMessaging.Core.Messages;
8
9
  using global::Unity.PerformanceTesting;
9
10
  using NUnit.Framework;
10
11
  using Scripts.Components;
@@ -30,9 +31,16 @@
30
31
  Debug.Log("| ------------ | ------------------- | ------------ | ");
31
32
 
32
33
  ComplexTargetedMessage message = new(Guid.NewGuid());
34
+ DxReflexiveMessage reflexiveMessage = new(
35
+ nameof(SimpleMessageAwareComponent.HandleSlowComplexTargetedMessage),
36
+ ReflexiveSendMode.Flat,
37
+ message
38
+ );
39
+
33
40
  Stopwatch timer = Stopwatch.StartNew();
34
41
 
35
42
  RunTest(component => Unity(timer, timeout, component.gameObject, message));
43
+
36
44
  RunTest(component => NormalGameObject(timer, timeout, component, message));
37
45
  RunTest(component => NormalComponent(timer, timeout, component, message));
38
46
  RunTest(component => NoCopyGameObject(timer, timeout, component, message));
@@ -40,6 +48,11 @@
40
48
 
41
49
  SimpleUntargetedMessage untargetedMessage = new();
42
50
  RunTest(component => NoCopyUntargeted(timer, timeout, component, untargetedMessage));
51
+ RunTest(component =>
52
+ ReflexiveOneArgument(timer, timeout, component.gameObject, reflexiveMessage)
53
+ );
54
+ RunTest(component => ReflexiveTwoArguments(timer, timeout, component.gameObject));
55
+ RunTest(component => ReflexiveThreeArguments(timer, timeout, component.gameObject));
43
56
  }
44
57
 
45
58
  [Test]
@@ -181,7 +194,10 @@
181
194
  )
182
195
  {
183
196
  int count = 0;
184
- var component = target.AddComponent<SimpleMessageAwareComponent>();
197
+ if (!target.TryGetComponent(out SimpleMessageAwareComponent component))
198
+ {
199
+ component = target.AddComponent<SimpleMessageAwareComponent>();
200
+ }
185
201
  component.slowComplexTargetedHandler = () => ++count;
186
202
  // Pre-warm
187
203
  target.SendMessage(
@@ -221,6 +237,130 @@
221
237
  DisplayCount("Unity", count, timeout, allocating);
222
238
  }
223
239
 
240
+ private static void ReflexiveThreeArguments(
241
+ Stopwatch timer,
242
+ TimeSpan timeout,
243
+ GameObject go
244
+ )
245
+ {
246
+ int count = 0;
247
+ if (!go.TryGetComponent(out SimpleMessageAwareComponent component))
248
+ {
249
+ component = go.AddComponent<SimpleMessageAwareComponent>();
250
+ }
251
+ component.reflexiveThreeArgumentHandler = () => ++count;
252
+ DxReflexiveMessage message = new(
253
+ nameof(SimpleMessageAwareComponent.HandleReflexiveMessageThreeArguments),
254
+ ReflexiveSendMode.Flat,
255
+ 1,
256
+ 2,
257
+ 3
258
+ );
259
+ InstanceId target = go;
260
+ // Pre-warm
261
+ message.EmitTargeted(target);
262
+
263
+ timer.Restart();
264
+ do
265
+ {
266
+ for (int i = 0; i < NumInvocationsPerIteration; ++i)
267
+ {
268
+ message.EmitTargeted(target);
269
+ }
270
+ } while (timer.Elapsed < timeout);
271
+ bool allocating;
272
+ try
273
+ {
274
+ Assert.That(() => message.EmitTargeted(target), Is.Not.AllocatingGCMemory());
275
+ allocating = false;
276
+ }
277
+ catch
278
+ {
279
+ allocating = true;
280
+ }
281
+
282
+ DisplayCount("Reflexive (Three Arguments)", count, timeout, allocating);
283
+ }
284
+
285
+ private static void ReflexiveTwoArguments(Stopwatch timer, TimeSpan timeout, GameObject go)
286
+ {
287
+ int count = 0;
288
+ if (!go.TryGetComponent(out SimpleMessageAwareComponent component))
289
+ {
290
+ component = go.AddComponent<SimpleMessageAwareComponent>();
291
+ }
292
+ component.reflexiveTwoArgumentHandler = () => ++count;
293
+ DxReflexiveMessage message = new(
294
+ nameof(SimpleMessageAwareComponent.HandleReflexiveMessageTwoArguments),
295
+ ReflexiveSendMode.Flat,
296
+ 1,
297
+ 2
298
+ );
299
+ InstanceId target = go;
300
+ // Pre-warm
301
+ message.EmitTargeted(target);
302
+
303
+ timer.Restart();
304
+ do
305
+ {
306
+ for (int i = 0; i < NumInvocationsPerIteration; ++i)
307
+ {
308
+ message.EmitTargeted(target);
309
+ }
310
+ } while (timer.Elapsed < timeout);
311
+ bool allocating;
312
+ try
313
+ {
314
+ Assert.That(() => message.EmitTargeted(target), Is.Not.AllocatingGCMemory());
315
+ allocating = false;
316
+ }
317
+ catch
318
+ {
319
+ allocating = true;
320
+ }
321
+
322
+ DisplayCount("Reflexive (Two Arguments)", count, timeout, allocating);
323
+ }
324
+
325
+ private static void ReflexiveOneArgument(
326
+ Stopwatch timer,
327
+ TimeSpan timeout,
328
+ GameObject go,
329
+ DxReflexiveMessage message
330
+ )
331
+ {
332
+ int count = 0;
333
+ if (!go.TryGetComponent(out SimpleMessageAwareComponent component))
334
+ {
335
+ component = go.AddComponent<SimpleMessageAwareComponent>();
336
+ }
337
+ component.slowComplexTargetedHandler = () => ++count;
338
+ InstanceId target = go;
339
+ // Pre-warm
340
+ message.EmitTargeted(target);
341
+
342
+ timer.Restart();
343
+ do
344
+ {
345
+ for (int i = 0; i < NumInvocationsPerIteration; ++i)
346
+ {
347
+ message.EmitTargeted(target);
348
+ }
349
+ } while (timer.Elapsed < timeout);
350
+ bool allocating;
351
+ try
352
+ {
353
+ Assert.That(() => message.EmitTargeted(target), Is.Not.AllocatingGCMemory());
354
+ allocating = false;
355
+ }
356
+ catch
357
+ {
358
+ allocating = true;
359
+ }
360
+
361
+ DisplayCount("Reflexive (One Argument)", count, timeout, allocating);
362
+ }
363
+
224
364
  private void NormalGameObject(
225
365
  Stopwatch timer,
226
366
  TimeSpan timeout,
@@ -154,20 +154,12 @@
154
154
  }
155
155
  }
156
156
 
157
- protected MessageRegistrationToken GetToken(MessageAwareComponent component)
157
+ protected static MessageRegistrationToken GetToken(MessageAwareComponent component)
158
158
  {
159
- // Reach inside and grab the token
160
- FieldInfo field = typeof(MessageAwareComponent).GetField(
161
- "_messageRegistrationToken",
162
- BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
163
- );
164
- Assert.IsNotNull(field);
165
- MessageRegistrationToken token = field.GetValue(component) as MessageRegistrationToken;
166
- Assert.IsNotNull(token);
167
- return token;
159
+ return component.Token;
168
160
  }
169
161
 
170
- protected IEnumerator WaitUntilMessageHandlerIsFresh()
162
+ protected static IEnumerator WaitUntilMessageHandlerIsFresh()
171
163
  {
172
164
  MessageBus messageBus = MessageHandler.MessageBus;
173
165
  Assert.IsNotNull(messageBus);
@@ -37,6 +37,8 @@
37
37
  public Action componentTargetedHandler;
38
38
  public Action complexComponentTargetedHandler;
39
39
  public Action componentBroadcastHandler;
40
+ public Action reflexiveTwoArgumentHandler;
41
+ public Action reflexiveThreeArgumentHandler;
40
42
 
41
43
  private bool _slowComplexTargetingEnabled = true;
42
44
  private bool _fastComplexTargetingEnabled = true;
@@ -122,6 +124,16 @@
122
124
  }
123
125
  }
124
126
 
127
+ public void HandleReflexiveMessageTwoArguments(int a, int b)
128
+ {
129
+ reflexiveTwoArgumentHandler?.Invoke();
130
+ }
131
+
132
+ public void HandleReflexiveMessageThreeArguments(int a, int b, int c)
133
+ {
134
+ reflexiveThreeArgumentHandler?.Invoke();
135
+ }
136
+
125
137
  public void HandleSlowComplexTargetedMessage(ComplexTargetedMessage message)
126
138
  {
127
139
  slowComplexTargetedHandler?.Invoke();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.dxmessaging",
3
- "version": "2.0.0-rc21",
3
+ "version": "2.0.0-rc23",
4
4
  "displayName": "DxMessaging",
5
5
  "description": "Synchronous Event Bus for Unity",
6
6
  "unity": "2021.3",