com.wallstop-studios.dxmessaging 2.0.0-rc11 → 2.0.0-rc13

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 (107) hide show
  1. package/.gitattributes +63 -63
  2. package/.github/workflows/npm-publish.yml +66 -0
  3. package/CHANGELOG.md.meta +7 -7
  4. package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +33 -33
  5. package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +33 -33
  6. package/Editor/Analyzers/System.Reflection.Metadata.dll.meta +33 -33
  7. package/Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +71 -71
  8. package/Editor/Analyzers.meta +8 -8
  9. package/Editor/SetupCscRsp.cs +162 -146
  10. package/Editor/SetupCscRsp.cs.meta +2 -2
  11. package/Editor/WallstopStudios.DxMessaging.Editor.asmdef +17 -17
  12. package/Editor/WallstopStudios.DxMessaging.Editor.asmdef.meta +7 -7
  13. package/Editor.meta +8 -8
  14. package/LICENSE.md +6 -6
  15. package/LICENSE.md.meta +7 -7
  16. package/README.md +387 -363
  17. package/README.md.meta +7 -7
  18. package/Runtime/Core/Attributes/DxAutoMessageTypeAttribute.cs +7 -9
  19. package/Runtime/Core/Attributes/DxAutoMessageTypeAttribute.cs.meta +2 -2
  20. package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs +7 -10
  21. package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs.meta +2 -2
  22. package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs +7 -10
  23. package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs.meta +2 -2
  24. package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs +7 -10
  25. package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs.meta +2 -2
  26. package/Runtime/Core/Attributes.meta +2 -2
  27. package/Runtime/Core/Extensions/MessageExtensions.cs +342 -275
  28. package/Runtime/Core/Extensions/MessageExtensions.cs.meta +11 -11
  29. package/Runtime/Core/Extensions.meta +8 -8
  30. package/Runtime/Core/IMessage.cs +12 -12
  31. package/Runtime/Core/IMessage.cs.meta +11 -11
  32. package/Runtime/Core/InstanceId.cs +149 -149
  33. package/Runtime/Core/InstanceId.cs.meta +11 -11
  34. package/Runtime/Core/MessageBus/IMessageBus.cs +309 -309
  35. package/Runtime/Core/MessageBus/IMessageBus.cs.meta +11 -11
  36. package/Runtime/Core/MessageBus/MessageBus.cs +2243 -2084
  37. package/Runtime/Core/MessageBus/MessageBus.cs.meta +11 -11
  38. package/Runtime/Core/MessageBus/MessagingRegistration.cs +105 -100
  39. package/Runtime/Core/MessageBus/MessagingRegistration.cs.meta +11 -11
  40. package/Runtime/Core/MessageBus/RegistrationLog.cs +111 -111
  41. package/Runtime/Core/MessageBus/RegistrationLog.cs.meta +11 -11
  42. package/Runtime/Core/MessageBus.meta +8 -8
  43. package/Runtime/Core/MessageHandler.cs +2778 -2759
  44. package/Runtime/Core/MessageHandler.cs.meta +11 -11
  45. package/Runtime/Core/MessageRegistrationHandle.cs +110 -110
  46. package/Runtime/Core/MessageRegistrationHandle.cs.meta +11 -11
  47. package/Runtime/Core/MessageRegistrationToken.cs +1234 -1234
  48. package/Runtime/Core/MessageRegistrationToken.cs.meta +11 -11
  49. package/Runtime/Core/Messages/IBroadcastMessage.cs +27 -27
  50. package/Runtime/Core/Messages/IBroadcastMessage.cs.meta +11 -11
  51. package/Runtime/Core/Messages/ITargetedMessage.cs +27 -26
  52. package/Runtime/Core/Messages/ITargetedMessage.cs.meta +11 -11
  53. package/Runtime/Core/Messages/IUntargetedMessage.cs +27 -26
  54. package/Runtime/Core/Messages/IUntargetedMessage.cs.meta +11 -11
  55. package/Runtime/Core/Messages.meta +8 -8
  56. package/Runtime/Core/MessagingDebug.cs +70 -71
  57. package/Runtime/Core/MessagingDebug.cs.meta +11 -11
  58. package/Runtime/Core.meta +8 -8
  59. package/Runtime/Unity/MessageAwareComponent.cs +77 -77
  60. package/Runtime/Unity/MessageAwareComponent.cs.meta +11 -11
  61. package/Runtime/Unity/MessagingComponent.cs +99 -99
  62. package/Runtime/Unity/MessagingComponent.cs.meta +11 -11
  63. package/Runtime/Unity.meta +8 -8
  64. package/Runtime/WallstopStudios.DxMessaging.asmdef +15 -15
  65. package/Runtime.meta +8 -8
  66. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoMessageTypeGenerator.cs +92 -75
  67. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoMessageTypeGenerator.cs.meta +11 -11
  68. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxBroadcastMessageGenerator.cs +94 -77
  69. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxBroadcastMessageGenerator.cs.meta +2 -2
  70. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxTargetedMessageGenerator.cs +94 -77
  71. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxTargetedMessageGenerator.cs.meta +2 -2
  72. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxUntargetedMessageGenerator.cs +94 -78
  73. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxUntargetedMessageGenerator.cs.meta +2 -2
  74. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +21 -21
  75. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj.meta +7 -7
  76. package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.meta +8 -8
  77. package/SourceGenerators.meta +8 -8
  78. package/Tests/Runtime/Benchmarks/PerformanceTests.cs +373 -310
  79. package/Tests/Runtime/Benchmarks/PerformanceTests.cs.meta +11 -11
  80. package/Tests/Runtime/Benchmarks.meta +8 -8
  81. package/Tests/Runtime/Core/BroadcastTests.cs +899 -899
  82. package/Tests/Runtime/Core/GlobalAcceptAllTests.cs +190 -169
  83. package/Tests/Runtime/Core/GlobalAcceptAllTests.cs.meta +11 -11
  84. package/Tests/Runtime/Core/MessagingTestBase.cs +185 -164
  85. package/Tests/Runtime/Core/MessagingTestBase.cs.meta +11 -11
  86. package/Tests/Runtime/Core/NominalTests.cs +1740 -1518
  87. package/Tests/Runtime/Core/PostProcessorTests.cs +1236 -849
  88. package/Tests/Runtime/Core/PostProcessorTests.cs.meta +11 -11
  89. package/Tests/Runtime/Core/RegistrationTests.cs +1266 -995
  90. package/Tests/Runtime/Core/RegistrationTests.cs.meta +11 -11
  91. package/Tests/Runtime/Core/TargetedTests.cs +888 -888
  92. package/Tests/Runtime/Core/TargetedTests.cs.meta +11 -11
  93. package/Tests/Runtime/Core/UntargetedTests.cs +272 -272
  94. package/Tests/Runtime/Core/UntargetedTests.cs.meta +11 -11
  95. package/Tests/Runtime/Scripts/Components/EmptyMessageAwareComponent.cs +9 -9
  96. package/Tests/Runtime/Scripts/Components/EmptyMessageAwareComponent.cs.meta +11 -11
  97. package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs +186 -140
  98. package/Tests/Runtime/Scripts/Messages/ComplexTargetedMessage.cs +30 -30
  99. package/Tests/Runtime/Scripts/Messages/SimpleBroadcastMessage.cs +8 -8
  100. package/Tests/Runtime/Scripts/Messages/SimpleTargetedMessage.cs +8 -8
  101. package/Tests/Runtime/Scripts/Messages/SimpleUntargetedMessage.cs +8 -8
  102. package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.asmdef +22 -22
  103. package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.csproj.meta +7 -7
  104. package/Tests.meta +8 -8
  105. package/Third Party Notices.md.meta +7 -7
  106. package/package.json +36 -36
  107. package/package.json.meta +7 -7
@@ -1,310 +1,373 @@
1
- namespace DxMessaging.Tests.Runtime.Benchmarks
2
- {
3
- using System;
4
- using System.Collections;
5
- using System.Diagnostics;
6
- using Core;
7
- using DxMessaging.Core;
8
- using DxMessaging.Core.Extensions;
9
- using global::Unity.PerformanceTesting;
10
- using NUnit.Framework;
11
- using Scripts.Components;
12
- using Scripts.Messages;
13
- using UnityEngine;
14
- using UnityEngine.TestTools;
15
- using Debug = UnityEngine.Debug;
16
- using Object = UnityEngine.Object;
17
-
18
- public sealed class PerformanceTests : MessagingTestBase
19
- {
20
- [SetUp]
21
- public override void Setup()
22
- {
23
- base.Setup();
24
- MessagingDebug.LogFunction = (_, _) => { };
25
- }
26
-
27
- [UnityTest]
28
- public IEnumerator Benchmark()
29
- {
30
- TimeSpan timeout = TimeSpan.FromSeconds(1);
31
-
32
- Debug.Log("| Message Tech | Operations / Second |");
33
- Debug.Log("| ------------ | ------------------- |");
34
-
35
- ComplexTargetedMessage message = new(Guid.NewGuid());
36
- Stopwatch timer = Stopwatch.StartNew();
37
-
38
- RunTest(component => Unity(timer, timeout, component.gameObject, message));
39
- RunTest(component => NormalGameObject(timer, timeout, component, message));
40
- RunTest(component => NormalComponent(timer, timeout, component, message));
41
- RunTest(component => NoCopyGameObject(timer, timeout, component, message));
42
- RunTest(component => NoCopyComponent(timer, timeout, component, message));
43
-
44
- SimpleUntargetedMessage untargetedMessage = new();
45
- RunTest(component => NoCopyUntargeted(timer, timeout, component, untargetedMessage));
46
- yield break;
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
-
130
- private GameObject CreateGameObject()
131
- {
132
- GameObject target = new(
133
- nameof(Benchmark),
134
- typeof(EmptyMessageAwareComponent),
135
- typeof(SpriteRenderer),
136
- typeof(Rigidbody2D),
137
- typeof(CircleCollider2D),
138
- typeof(LineRenderer)
139
- );
140
- _spawned.Add(target);
141
-
142
- return target;
143
- }
144
-
145
- private static void DisplayCount(string testName, int count, TimeSpan timeout)
146
- {
147
- Debug.Log($"| {testName} | {Math.Floor(count / timeout.TotalSeconds):N0} |");
148
- }
149
-
150
- private void RunTest(Action<EmptyMessageAwareComponent> test)
151
- {
152
- GameObject go = CreateGameObject();
153
- try
154
- {
155
- test(go.GetComponent<EmptyMessageAwareComponent>());
156
- }
157
- finally
158
- {
159
- _spawned.Remove(go);
160
- Object.Destroy(go);
161
- }
162
- }
163
-
164
- private static void Unity(
165
- Stopwatch timer,
166
- TimeSpan timeout,
167
- GameObject target,
168
- ComplexTargetedMessage message
169
- )
170
- {
171
- int count = 0;
172
- var component = target.AddComponent<SimpleMessageAwareComponent>();
173
- component.slowComplexTargetedHandler = () => ++count;
174
- timer.Restart();
175
- do
176
- {
177
- target.SendMessage(
178
- nameof(SimpleMessageAwareComponent.HandleSlowComplexTargetedMessage),
179
- message
180
- );
181
- } while (timer.Elapsed < timeout);
182
- DisplayCount("Unity", count, timeout);
183
- }
184
-
185
- private void NormalGameObject(
186
- Stopwatch timer,
187
- TimeSpan timeout,
188
- EmptyMessageAwareComponent component,
189
- ComplexTargetedMessage message
190
- )
191
- {
192
- int count = 0;
193
- var token = GetToken(component);
194
-
195
- void Handle(ComplexTargetedMessage _)
196
- {
197
- ++count;
198
- }
199
-
200
- GameObject go = component.gameObject;
201
- token.RegisterGameObjectTargeted<ComplexTargetedMessage>(go, Handle);
202
- timer.Restart();
203
- do
204
- {
205
- message.EmitGameObjectTargeted(go);
206
- } while (timer.Elapsed < timeout);
207
- DisplayCount("DxMessaging (GameObject) - Normal", count, timeout);
208
- }
209
-
210
- private void NormalComponent(
211
- Stopwatch timer,
212
- TimeSpan timeout,
213
- EmptyMessageAwareComponent component,
214
- ComplexTargetedMessage message
215
- )
216
- {
217
- int count = 0;
218
- var token = GetToken(component);
219
-
220
- void Handle(ComplexTargetedMessage _)
221
- {
222
- ++count;
223
- }
224
-
225
- token.RegisterComponentTargeted<ComplexTargetedMessage>(component, Handle);
226
- timer.Restart();
227
- do
228
- {
229
- message.EmitComponentTargeted(component);
230
- } while (timer.Elapsed < timeout);
231
- DisplayCount("DxMessaging (Component) - Normal", count, timeout);
232
- }
233
-
234
- private void NoCopyGameObject(
235
- Stopwatch timer,
236
- TimeSpan timeout,
237
- EmptyMessageAwareComponent component,
238
- ComplexTargetedMessage message
239
- )
240
- {
241
- int count = 0;
242
- var token = GetToken(component);
243
-
244
- void Handle(ref ComplexTargetedMessage _)
245
- {
246
- ++count;
247
- }
248
-
249
- GameObject go = component.gameObject;
250
- token.RegisterGameObjectTargeted<ComplexTargetedMessage>(go, Handle);
251
-
252
- timer.Restart();
253
- do
254
- {
255
- message.EmitGameObjectTargeted(component.gameObject);
256
- } while (timer.Elapsed < timeout);
257
- DisplayCount("DxMessaging (GameObject) - No-Copy", count, timeout);
258
- }
259
-
260
- private void NoCopyComponent(
261
- Stopwatch timer,
262
- TimeSpan timeout,
263
- EmptyMessageAwareComponent component,
264
- ComplexTargetedMessage message
265
- )
266
- {
267
- int count = 0;
268
- var token = GetToken(component);
269
-
270
- void Handle(ref ComplexTargetedMessage _)
271
- {
272
- ++count;
273
- }
274
-
275
- token.RegisterComponentTargeted<ComplexTargetedMessage>(component, Handle);
276
-
277
- timer.Restart();
278
- do
279
- {
280
- message.EmitComponentTargeted(component);
281
- } while (timer.Elapsed < timeout);
282
- DisplayCount("DxMessaging (Component) - No-Copy", count, timeout);
283
- }
284
-
285
- private void NoCopyUntargeted(
286
- Stopwatch timer,
287
- TimeSpan timeout,
288
- EmptyMessageAwareComponent component,
289
- SimpleUntargetedMessage message
290
- )
291
- {
292
- int count = 0;
293
- var token = GetToken(component);
294
-
295
- void Handle(ref SimpleUntargetedMessage _)
296
- {
297
- ++count;
298
- }
299
-
300
- token.RegisterUntargeted<SimpleUntargetedMessage>(Handle);
301
-
302
- timer.Restart();
303
- do
304
- {
305
- message.EmitUntargeted();
306
- } while (timer.Elapsed < timeout);
307
- DisplayCount("DxMessaging (Untargeted) - No-Copy", count, timeout);
308
- }
309
- }
310
- }
1
+ namespace DxMessaging.Tests.Runtime.Benchmarks
2
+ {
3
+ using System;
4
+ using System.Diagnostics;
5
+ using Core;
6
+ using DxMessaging.Core;
7
+ using DxMessaging.Core.Extensions;
8
+ using global::Unity.PerformanceTesting;
9
+ using global::Unity.Profiling;
10
+ using NUnit.Framework;
11
+ using Scripts.Components;
12
+ using Scripts.Messages;
13
+ using UnityEngine;
14
+ using UnityEngine.Profiling;
15
+ using Debug = UnityEngine.Debug;
16
+ using Object = UnityEngine.Object;
17
+
18
+ public sealed class PerformanceTests : MessagingTestBase
19
+ {
20
+ internal static string FormatBytes(long bytes)
21
+ {
22
+ if (bytes < 1024)
23
+ {
24
+ return $"{bytes} B";
25
+ }
26
+
27
+ string[] sizes = { "KB", "MB", "GB", "TB", "PB", "EB" };
28
+ double len = bytes;
29
+ int order = 0;
30
+
31
+ while (1024 <= len && order < sizes.Length - 1)
32
+ {
33
+ len /= 1024;
34
+ order++;
35
+ }
36
+
37
+ return $"{len:0.##} {sizes[order]}";
38
+ }
39
+
40
+ [SetUp]
41
+ public override void Setup()
42
+ {
43
+ base.Setup();
44
+ MessagingDebug.LogFunction = (_, _) => { };
45
+ }
46
+
47
+ [Test]
48
+ public void Benchmark()
49
+ {
50
+ TimeSpan timeout = TimeSpan.FromSeconds(2);
51
+
52
+ Debug.Log("| Message Tech | Operations / Second | Memory Allocated |");
53
+ Debug.Log("| ------------ | ------------------- | --------------- |");
54
+
55
+ ComplexTargetedMessage message = new(Guid.NewGuid());
56
+ Stopwatch timer = Stopwatch.StartNew();
57
+ ProfilerRecorder recorder = ProfilerRecorder.StartNew(
58
+ ProfilerCategory.Memory,
59
+ "GC.Alloc"
60
+ );
61
+ recorder.Stop();
62
+ RunTest(component => Unity(timer, timeout, component.gameObject, message));
63
+ RunTest(component => NormalGameObject(timer, timeout, component, message));
64
+ RunTest(component => NormalComponent(timer, timeout, component, message));
65
+ RunTest(component => NoCopyGameObject(timer, timeout, component, message));
66
+ RunTest(component => NoCopyComponent(timer, timeout, component, message));
67
+
68
+ SimpleUntargetedMessage untargetedMessage = new();
69
+ RunTest(component => NoCopyUntargeted(timer, timeout, component, untargetedMessage));
70
+ }
71
+
72
+ [Test]
73
+ [Performance]
74
+ public void BenchmarkBroadcast()
75
+ {
76
+ GameObject go = CreateGameObject();
77
+ MessageRegistrationToken token = GetToken(
78
+ go.GetComponent<EmptyMessageAwareComponent>()
79
+ );
80
+ int count = 0;
81
+ token.RegisterGameObjectBroadcast<SimpleBroadcastMessage>(go, Handle);
82
+
83
+ SimpleBroadcastMessage message = new();
84
+
85
+ Measure
86
+ .Method(() => message.EmitGameObjectBroadcast(go))
87
+ .WarmupCount(10)
88
+ .IterationsPerMeasurement(10)
89
+ .MeasurementCount(1_000)
90
+ .Run();
91
+ return;
92
+
93
+ void Handle(SimpleBroadcastMessage _)
94
+ {
95
+ ++count;
96
+ }
97
+ }
98
+
99
+ [Test]
100
+ [Performance]
101
+ public void BenchmarkTargeted()
102
+ {
103
+ GameObject go = CreateGameObject();
104
+ MessageRegistrationToken token = GetToken(
105
+ go.GetComponent<EmptyMessageAwareComponent>()
106
+ );
107
+ int count = 0;
108
+ token.RegisterGameObjectTargeted<SimpleTargetedMessage>(go, Handle);
109
+
110
+ SimpleTargetedMessage message = new();
111
+
112
+ Measure
113
+ .Method(() => message.EmitGameObjectTargeted(go))
114
+ .WarmupCount(10)
115
+ .IterationsPerMeasurement(10)
116
+ .MeasurementCount(1_000)
117
+ .Run();
118
+ return;
119
+
120
+ void Handle(SimpleTargetedMessage _)
121
+ {
122
+ ++count;
123
+ }
124
+ }
125
+
126
+ [Test]
127
+ [Performance]
128
+ public void BenchmarkUntargeted()
129
+ {
130
+ GameObject go = CreateGameObject();
131
+ MessageRegistrationToken token = GetToken(
132
+ go.GetComponent<EmptyMessageAwareComponent>()
133
+ );
134
+ int count = 0;
135
+ token.RegisterUntargeted<SimpleUntargetedMessage>(Handle);
136
+
137
+ SimpleUntargetedMessage message = new();
138
+
139
+ Measure
140
+ .Method(() => message.EmitUntargeted())
141
+ .WarmupCount(10)
142
+ .IterationsPerMeasurement(10)
143
+ .MeasurementCount(1_000)
144
+ .Run();
145
+ return;
146
+
147
+ void Handle(SimpleUntargetedMessage _)
148
+ {
149
+ ++count;
150
+ }
151
+ }
152
+
153
+ private GameObject CreateGameObject()
154
+ {
155
+ GameObject target = new(
156
+ nameof(Benchmark),
157
+ typeof(EmptyMessageAwareComponent),
158
+ typeof(SpriteRenderer),
159
+ typeof(Rigidbody2D),
160
+ typeof(CircleCollider2D),
161
+ typeof(LineRenderer)
162
+ );
163
+ _spawned.Add(target);
164
+
165
+ return target;
166
+ }
167
+
168
+ private static void DisplayCount(
169
+ string testName,
170
+ int count,
171
+ TimeSpan timeout,
172
+ long memoryUsed
173
+ )
174
+ {
175
+ Debug.Log(
176
+ $"| {testName} | {Math.Floor(count / timeout.TotalSeconds):N0} | {FormatBytes(Math.Max(memoryUsed, 0))} |"
177
+ );
178
+ }
179
+
180
+ private void RunTest(Action<EmptyMessageAwareComponent> test)
181
+ {
182
+ GameObject go = CreateGameObject();
183
+ try
184
+ {
185
+ test(go.GetComponent<EmptyMessageAwareComponent>());
186
+ }
187
+ finally
188
+ {
189
+ _spawned.Remove(go);
190
+ Object.Destroy(go);
191
+ }
192
+ }
193
+
194
+ private static void Unity(
195
+ Stopwatch timer,
196
+ TimeSpan timeout,
197
+ GameObject target,
198
+ ComplexTargetedMessage message
199
+ )
200
+ {
201
+ int count = 0;
202
+ var component = target.AddComponent<SimpleMessageAwareComponent>();
203
+ component.slowComplexTargetedHandler = () => ++count;
204
+ ProfilerRecorder recorder = ProfilerRecorder.StartNew(
205
+ ProfilerCategory.Memory,
206
+ "GC.Alloc"
207
+ );
208
+ timer.Restart();
209
+ do
210
+ {
211
+ target.SendMessage(
212
+ nameof(SimpleMessageAwareComponent.HandleSlowComplexTargetedMessage),
213
+ message
214
+ );
215
+ } while (timer.Elapsed < timeout);
216
+ recorder.Stop();
217
+ DisplayCount("Unity", count, timeout, recorder.LastValue);
218
+ }
219
+
220
+ private void NormalGameObject(
221
+ Stopwatch timer,
222
+ TimeSpan timeout,
223
+ EmptyMessageAwareComponent component,
224
+ ComplexTargetedMessage message
225
+ )
226
+ {
227
+ int count = 0;
228
+ var token = GetToken(component);
229
+
230
+ GameObject go = component.gameObject;
231
+ token.RegisterGameObjectTargeted<ComplexTargetedMessage>(go, Handle);
232
+ ProfilerRecorder recorder = ProfilerRecorder.StartNew(
233
+ ProfilerCategory.Memory,
234
+ "GC.Alloc"
235
+ );
236
+ timer.Restart();
237
+ do
238
+ {
239
+ message.EmitGameObjectTargeted(go);
240
+ } while (timer.Elapsed < timeout);
241
+
242
+ recorder.Stop();
243
+ DisplayCount("DxMessaging (GameObject) - Normal", count, timeout, recorder.LastValue);
244
+ return;
245
+
246
+ void Handle(ComplexTargetedMessage _)
247
+ {
248
+ ++count;
249
+ }
250
+ }
251
+
252
+ private void NormalComponent(
253
+ Stopwatch timer,
254
+ TimeSpan timeout,
255
+ EmptyMessageAwareComponent component,
256
+ ComplexTargetedMessage message
257
+ )
258
+ {
259
+ int count = 0;
260
+ var token = GetToken(component);
261
+
262
+ token.RegisterComponentTargeted<ComplexTargetedMessage>(component, Handle);
263
+ ProfilerRecorder recorder = ProfilerRecorder.StartNew(
264
+ ProfilerCategory.Memory,
265
+ "GC.Alloc"
266
+ );
267
+ timer.Restart();
268
+ do
269
+ {
270
+ message.EmitComponentTargeted(component);
271
+ } while (timer.Elapsed < timeout);
272
+ recorder.Stop();
273
+ DisplayCount("DxMessaging (Component) - Normal", count, timeout, recorder.LastValue);
274
+ return;
275
+
276
+ void Handle(ComplexTargetedMessage _)
277
+ {
278
+ ++count;
279
+ }
280
+ }
281
+
282
+ private void NoCopyGameObject(
283
+ Stopwatch timer,
284
+ TimeSpan timeout,
285
+ EmptyMessageAwareComponent component,
286
+ ComplexTargetedMessage message
287
+ )
288
+ {
289
+ int count = 0;
290
+ var token = GetToken(component);
291
+
292
+ GameObject go = component.gameObject;
293
+ token.RegisterGameObjectTargeted<ComplexTargetedMessage>(go, Handle);
294
+ ProfilerRecorder recorder = ProfilerRecorder.StartNew(
295
+ ProfilerCategory.Memory,
296
+ "GC.Alloc"
297
+ );
298
+ timer.Restart();
299
+ do
300
+ {
301
+ message.EmitGameObjectTargeted(component.gameObject);
302
+ } while (timer.Elapsed < timeout);
303
+ recorder.Stop();
304
+ DisplayCount("DxMessaging (GameObject) - No-Copy", count, timeout, recorder.LastValue);
305
+ return;
306
+
307
+ void Handle(ref ComplexTargetedMessage _)
308
+ {
309
+ ++count;
310
+ }
311
+ }
312
+
313
+ private void NoCopyComponent(
314
+ Stopwatch timer,
315
+ TimeSpan timeout,
316
+ EmptyMessageAwareComponent component,
317
+ ComplexTargetedMessage message
318
+ )
319
+ {
320
+ int count = 0;
321
+ var token = GetToken(component);
322
+
323
+ token.RegisterComponentTargeted<ComplexTargetedMessage>(component, Handle);
324
+ ProfilerRecorder recorder = ProfilerRecorder.StartNew(
325
+ ProfilerCategory.Memory,
326
+ "GC.Alloc"
327
+ );
328
+ timer.Restart();
329
+ do
330
+ {
331
+ message.EmitComponentTargeted(component);
332
+ } while (timer.Elapsed < timeout);
333
+ recorder.Stop();
334
+ DisplayCount("DxMessaging (Component) - No-Copy", count, timeout, recorder.LastValue);
335
+ return;
336
+
337
+ void Handle(ref ComplexTargetedMessage _)
338
+ {
339
+ ++count;
340
+ }
341
+ }
342
+
343
+ private void NoCopyUntargeted(
344
+ Stopwatch timer,
345
+ TimeSpan timeout,
346
+ EmptyMessageAwareComponent component,
347
+ SimpleUntargetedMessage message
348
+ )
349
+ {
350
+ int count = 0;
351
+ var token = GetToken(component);
352
+
353
+ token.RegisterUntargeted<SimpleUntargetedMessage>(Handle);
354
+ ProfilerRecorder recorder = ProfilerRecorder.StartNew(
355
+ ProfilerCategory.Memory,
356
+ "GC.Alloc"
357
+ );
358
+ timer.Restart();
359
+ do
360
+ {
361
+ message.EmitUntargeted();
362
+ } while (timer.Elapsed < timeout);
363
+ recorder.Stop();
364
+ DisplayCount("DxMessaging (Untargeted) - No-Copy", count, timeout, recorder.LastValue);
365
+ return;
366
+
367
+ void Handle(ref SimpleUntargetedMessage _)
368
+ {
369
+ ++count;
370
+ }
371
+ }
372
+ }
373
+ }