com.wallstop-studios.dxmessaging 2.0.0 → 2.1.0

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 (174) hide show
  1. package/.github/workflows/format-on-demand.yml +2 -2
  2. package/.github/workflows/json-format-check.yml +1 -1
  3. package/.github/workflows/markdown-json.yml +1 -1
  4. package/.github/workflows/markdownlint.yml +1 -1
  5. package/.github/workflows/npm-publish.yml +1 -1
  6. package/.github/workflows/prettier-autofix.yml +2 -2
  7. package/.github/workflows/yaml-format-lint.yml +1 -1
  8. package/Docs/Advanced.md +26 -1
  9. package/Docs/Comparisons.md +1229 -146
  10. package/Docs/Compatibility.md +27 -0
  11. package/Docs/DesignAndArchitecture.md +41 -34
  12. package/Docs/EmitShorthands.md +34 -0
  13. package/Docs/Helpers.md +1 -1
  14. package/Docs/Index.md +28 -25
  15. package/Docs/Install.md +29 -6
  16. package/Docs/Integrations/Reflex.md +292 -0
  17. package/Docs/Integrations/Reflex.md.meta +7 -0
  18. package/Docs/Integrations/VContainer.md +324 -0
  19. package/Docs/Integrations/VContainer.md.meta +7 -0
  20. package/Docs/Integrations/Zenject.md +333 -0
  21. package/Docs/Integrations/Zenject.md.meta +7 -0
  22. package/{Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.pdb.meta → Docs/Integrations.meta} +2 -1
  23. package/Docs/InterceptorsAndOrdering.md +371 -17
  24. package/Docs/ListeningPatterns.md +206 -0
  25. package/Docs/MessageBusProviders.md +496 -0
  26. package/Docs/MessageBusProviders.md.meta +7 -0
  27. package/Docs/MessageTypes.md +27 -0
  28. package/Docs/MigrationGuide.md +45 -0
  29. package/Docs/Patterns.md +286 -0
  30. package/Docs/Performance.md +9 -9
  31. package/Docs/QuickReference.md +31 -0
  32. package/Docs/RuntimeConfiguration.md +407 -0
  33. package/Docs/RuntimeConfiguration.md.meta +7 -0
  34. package/Docs/UnityIntegration.md +3 -1
  35. package/Docs/VisualGuide.md +206 -157
  36. package/Editor/CustomEditors/MessagingComponentEditor.cs +15 -6
  37. package/README.md +148 -26
  38. package/Runtime/AssemblyInfo.cs +4 -0
  39. package/Runtime/Core/Extensions/MessageBusExtensions.cs +253 -0
  40. package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +12 -0
  41. package/Runtime/Core/Extensions/MessageExtensions.cs +137 -89
  42. package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs +23 -0
  43. package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs.meta +11 -0
  44. package/Runtime/Core/MessageBus/IMessageBusProvider.cs +14 -0
  45. package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +11 -0
  46. package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +18 -0
  47. package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs.meta +11 -0
  48. package/Runtime/Core/MessageBus/MessageBusRebindMode.cs +26 -0
  49. package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +11 -0
  50. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +383 -0
  51. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs.meta +11 -0
  52. package/Runtime/Core/MessageHandler.cs +198 -27
  53. package/Runtime/Core/MessageRegistrationToken.cs +67 -25
  54. package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs +31 -0
  55. package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs.meta +12 -0
  56. package/Runtime/Unity/InitialGlobalMessageBusProvider.cs +38 -0
  57. package/Runtime/Unity/InitialGlobalMessageBusProvider.cs.meta +12 -0
  58. package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs +11 -0
  59. package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +3 -0
  60. package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +73 -0
  61. package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs.meta +11 -0
  62. package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef +20 -0
  63. package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef.meta +7 -0
  64. package/Runtime/Unity/Integrations/Reflex.meta +8 -0
  65. package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs +11 -0
  66. package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
  67. package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +46 -0
  68. package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs.meta +11 -0
  69. package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef +30 -0
  70. package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef.meta +7 -0
  71. package/Runtime/Unity/Integrations/VContainer.meta +8 -0
  72. package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs +11 -0
  73. package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
  74. package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef +30 -0
  75. package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef.meta +7 -0
  76. package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +55 -0
  77. package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs.meta +11 -0
  78. package/Runtime/Unity/Integrations/Zenject.meta +8 -0
  79. package/Runtime/Unity/Integrations.meta +8 -0
  80. package/Runtime/Unity/MessageAwareComponent.cs +102 -0
  81. package/Runtime/Unity/MessageBusProviderHandle.cs +97 -0
  82. package/Runtime/Unity/MessageBusProviderHandle.cs.meta +12 -0
  83. package/Runtime/Unity/MessagingComponent.cs +164 -2
  84. package/Runtime/Unity/MessagingComponentInstaller.cs +120 -0
  85. package/Runtime/Unity/MessagingComponentInstaller.cs.meta +12 -0
  86. package/Runtime/Unity/ScriptableMessageBusProvider.cs +14 -0
  87. package/Runtime/Unity/ScriptableMessageBusProvider.cs.meta +12 -0
  88. package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab +98 -0
  89. package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab.meta +7 -0
  90. package/Samples~/DI/Prefabs.meta +8 -0
  91. package/Samples~/DI/Providers/GlobalMessageBusProvider.asset +14 -0
  92. package/Samples~/DI/Providers/GlobalMessageBusProvider.asset.meta +8 -0
  93. package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset +14 -0
  94. package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset.meta +8 -0
  95. package/Samples~/DI/Providers.meta +8 -0
  96. package/Samples~/DI/README.md +51 -0
  97. package/Samples~/DI/README.md.meta +7 -0
  98. package/Samples~/DI/Reflex/SampleInstaller.cs +75 -0
  99. package/Samples~/DI/Reflex/SampleInstaller.cs.meta +11 -0
  100. package/Samples~/DI/Reflex.meta +8 -0
  101. package/Samples~/DI/VContainer/SampleLifetimeScope.cs +81 -0
  102. package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +11 -0
  103. package/Samples~/DI/VContainer.meta +8 -0
  104. package/Samples~/DI/Zenject/SampleInstaller.cs +67 -0
  105. package/Samples~/DI/Zenject/SampleInstaller.cs.meta +11 -0
  106. package/Samples~/DI/Zenject.meta +8 -0
  107. package/Samples~/DI.meta +8 -0
  108. package/Samples~/Mini Combat/README.md +5 -7
  109. package/Samples~/Mini Combat/Walkthrough.md +18 -24
  110. package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs +12 -2
  111. package/Samples~/UI Buttons + Inspector/README.md.meta +7 -0
  112. package/Tests/Runtime/Benchmarks/BenchmarkSession.cs +444 -0
  113. package/Tests/Runtime/Benchmarks/BenchmarkSession.cs.meta +11 -0
  114. package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs +94 -0
  115. package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs.meta +11 -0
  116. package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs +395 -0
  117. package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs.meta +11 -0
  118. package/Tests/Runtime/Benchmarks/PerformanceTests.cs +77 -429
  119. package/Tests/Runtime/Benchmarks/ProviderResolutionBenchmarks.cs +142 -0
  120. package/Tests/Runtime/Benchmarks/ProviderResolutionBenchmarks.cs.meta +12 -0
  121. package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef +50 -0
  122. package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef.meta +7 -0
  123. package/Tests/Runtime/Core/DefaultBusFallbackTests.cs +333 -0
  124. package/Tests/Runtime/Core/DefaultBusFallbackTests.cs.meta +11 -0
  125. package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs +278 -0
  126. package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs.meta +11 -0
  127. package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs +289 -0
  128. package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs.meta +11 -0
  129. package/Tests/Runtime/Core/Extensions.meta +8 -0
  130. package/Tests/Runtime/Core/IntegrationShimSmokeTests.cs +57 -0
  131. package/Tests/Runtime/Core/IntegrationShimSmokeTests.cs.meta +11 -0
  132. package/Tests/Runtime/Core/MessageHandlerGlobalBusTests.cs +219 -0
  133. package/Tests/Runtime/Core/MessageHandlerGlobalBusTests.cs.meta +11 -0
  134. package/Tests/Runtime/Core/MessageRegistrationBuilderTests.cs +204 -0
  135. package/Tests/Runtime/Core/MessageRegistrationBuilderTests.cs.meta +11 -0
  136. package/Tests/Runtime/Core/MessagingTestBase.cs +4 -4
  137. package/Tests/Runtime/Core/NominalTests.cs +2 -2
  138. package/Tests/Runtime/Core/TypedShorthandTests.cs +2 -2
  139. package/Tests/Runtime/Core/UntargetedEquivalenceTests.cs +1 -1
  140. package/Tests/Runtime/Core/UntargetedPrefreezeTests.cs +2 -4
  141. package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs +162 -0
  142. package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs.meta +11 -0
  143. package/Tests/Runtime/Integrations/Reflex/Resources/ReflexSettings.asset +16 -0
  144. package/Tests/Runtime/Integrations/Reflex/Resources/ReflexSettings.asset.meta +8 -0
  145. package/Tests/Runtime/Integrations/Reflex/Resources.meta +8 -0
  146. package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef +27 -0
  147. package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef.meta +7 -0
  148. package/Tests/Runtime/Integrations/Reflex.meta +8 -0
  149. package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs +140 -0
  150. package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs.meta +11 -0
  151. package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef +37 -0
  152. package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef.meta +7 -0
  153. package/Tests/Runtime/Integrations/VContainer.meta +8 -0
  154. package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef +37 -0
  155. package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef.meta +7 -0
  156. package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs +140 -0
  157. package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs.meta +11 -0
  158. package/Tests/Runtime/Integrations/Zenject.meta +8 -0
  159. package/Tests/Runtime/Integrations.meta +8 -0
  160. package/Tests/Runtime/Scripts/Components/EmptyMessageAwareComponent.cs +1 -1
  161. package/Tests/Runtime/Scripts/Components/GenericMessageAwareComponent.cs +1 -1
  162. package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs +1 -1
  163. package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs +64 -0
  164. package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs.meta +12 -0
  165. package/Tests/Runtime/TestUtilities.meta +9 -0
  166. package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs +57 -0
  167. package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs.meta +11 -0
  168. package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs +107 -0
  169. package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs.meta +12 -0
  170. package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs +210 -0
  171. package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs.meta +12 -0
  172. package/Tests/Runtime/Unity.meta +9 -0
  173. package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.asmdef +3 -1
  174. package/package.json +1 -1
@@ -0,0 +1,278 @@
1
+ namespace DxMessaging.Tests.Runtime.Core.Extensions
2
+ {
3
+ using System;
4
+ using DxMessaging.Core;
5
+ using DxMessaging.Core.Extensions;
6
+ using DxMessaging.Core.MessageBus;
7
+ using DxMessaging.Core.Messages;
8
+ using NUnit.Framework;
9
+ using MessageBus = DxMessaging.Core.MessageBus.MessageBus;
10
+
11
+ [TestFixture]
12
+ public sealed class MessageBusExtensionsTests
13
+ {
14
+ private IMessageBus _originalGlobalBus;
15
+
16
+ [SetUp]
17
+ public void SetUp()
18
+ {
19
+ _originalGlobalBus = MessageHandler.MessageBus;
20
+ MessageHandler.ResetGlobalMessageBus();
21
+ }
22
+
23
+ [TearDown]
24
+ public void TearDown()
25
+ {
26
+ MessageHandler.SetGlobalMessageBus(_originalGlobalBus);
27
+ }
28
+
29
+ [Test]
30
+ public void EmitUntargetedClassMessageUsesBus()
31
+ {
32
+ MessageBus bus = new MessageBus();
33
+ MessageHandler handler = new MessageHandler(new InstanceId(10), bus) { active = true };
34
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, bus);
35
+ int count = 0;
36
+ _ = token.RegisterUntargeted<ClassUntargetedMessage>(
37
+ (ref ClassUntargetedMessage _) => count++
38
+ );
39
+ token.Enable();
40
+
41
+ ClassUntargetedMessage message = new ClassUntargetedMessage();
42
+ bus.EmitUntargeted(message);
43
+
44
+ Assert.AreEqual(1, count);
45
+ token.Disable();
46
+ }
47
+
48
+ [Test]
49
+ public void EmitUntargetedStructMessageUsesBus()
50
+ {
51
+ MessageBus bus = new MessageBus();
52
+ MessageHandler handler = new MessageHandler(new InstanceId(20), bus) { active = true };
53
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, bus);
54
+ int count = 0;
55
+ _ = token.RegisterUntargeted<StructUntargetedMessage>(
56
+ (ref StructUntargetedMessage _) => count++
57
+ );
58
+ token.Enable();
59
+
60
+ StructUntargetedMessage message = new StructUntargetedMessage(1);
61
+ bus.EmitUntargeted(ref message);
62
+
63
+ Assert.AreEqual(1, count);
64
+ token.Disable();
65
+ }
66
+
67
+ [Test]
68
+ public void EmitUntargetedStructMessageHonorsInterceptorsAndPostProcessors()
69
+ {
70
+ MessageBus bus = new MessageBus();
71
+ MessageHandler handler = new MessageHandler(new InstanceId(21), bus) { active = true };
72
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, bus);
73
+ StructInterceptedMessage intercepted = default;
74
+ int postProcessCount = 0;
75
+
76
+ _ = bus.RegisterUntargetedInterceptor<StructInterceptedMessage>(
77
+ (ref StructInterceptedMessage msg) =>
78
+ {
79
+ msg.Value += 10;
80
+ return true;
81
+ }
82
+ );
83
+
84
+ _ = token.RegisterUntargeted<StructInterceptedMessage>(
85
+ (ref StructInterceptedMessage msg) => intercepted = msg
86
+ );
87
+
88
+ _ = token.RegisterUntargetedPostProcessor<StructInterceptedMessage>(
89
+ (ref StructInterceptedMessage _) => postProcessCount++
90
+ );
91
+
92
+ token.Enable();
93
+
94
+ StructInterceptedMessage message = new StructInterceptedMessage(5);
95
+ bus.EmitUntargeted(ref message);
96
+
97
+ Assert.AreEqual(15, intercepted.Value);
98
+ Assert.AreEqual(1, postProcessCount);
99
+
100
+ token.Disable();
101
+ }
102
+
103
+ [Test]
104
+ public void EmitUntargetedRandomizedMatchesMessageExtensions()
105
+ {
106
+ MessageBus bus = new MessageBus();
107
+ MessageHandler handler = new MessageHandler(new InstanceId(25), bus) { active = true };
108
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, bus);
109
+ int busSum = 0;
110
+
111
+ _ = token.RegisterUntargeted<StructUntargetedMessage>(
112
+ (ref StructUntargetedMessage msg) => busSum += msg.Value
113
+ );
114
+
115
+ token.Enable();
116
+
117
+ const int iterations = 256;
118
+ int[] values = new int[iterations];
119
+ Random random = new Random(1234);
120
+
121
+ for (int i = 0; i < iterations; i++)
122
+ {
123
+ int value = random.Next(-1_000, 1_000);
124
+ values[i] = value;
125
+ StructUntargetedMessage message = new StructUntargetedMessage(value);
126
+ bus.EmitUntargeted(ref message);
127
+ }
128
+
129
+ token.Disable();
130
+
131
+ MessageHandler handler2 = new MessageHandler(new InstanceId(26), bus) { active = true };
132
+ MessageRegistrationToken token2 = MessageRegistrationToken.Create(handler2, bus);
133
+ int messageSum = 0;
134
+
135
+ _ = token2.RegisterUntargeted<StructUntargetedMessage>(
136
+ (ref StructUntargetedMessage msg) => messageSum += msg.Value
137
+ );
138
+
139
+ token2.Enable();
140
+
141
+ for (int i = 0; i < iterations; i++)
142
+ {
143
+ StructUntargetedMessage message = new StructUntargetedMessage(values[i]);
144
+ message.EmitUntargeted(bus);
145
+ }
146
+
147
+ token2.Disable();
148
+
149
+ Assert.AreEqual(busSum, messageSum);
150
+ }
151
+
152
+ [Test]
153
+ public void EmitTargetedStructMessageUsesBus()
154
+ {
155
+ MessageBus bus = new MessageBus();
156
+ InstanceId target = new InstanceId(42);
157
+
158
+ MessageHandler handler = new MessageHandler(new InstanceId(30), bus) { active = true };
159
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, bus);
160
+ int count = 0;
161
+ _ = token.RegisterTargeted<StructTargetedMessage>(
162
+ target,
163
+ (ref StructTargetedMessage _) => count++
164
+ );
165
+ token.Enable();
166
+
167
+ StructTargetedMessage message = new StructTargetedMessage(5);
168
+ bus.EmitTargeted(target, ref message);
169
+
170
+ Assert.AreEqual(1, count);
171
+ token.Disable();
172
+ }
173
+
174
+ [Test]
175
+ public void EmitBroadcastStructMessageUsesBus()
176
+ {
177
+ MessageBus bus = new MessageBus();
178
+ InstanceId source = new InstanceId(99);
179
+
180
+ MessageHandler handler = new MessageHandler(new InstanceId(40), bus) { active = true };
181
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, bus);
182
+ int count = 0;
183
+ _ = token.RegisterBroadcast<StructBroadcastMessage>(
184
+ source,
185
+ (ref StructBroadcastMessage _) => count++
186
+ );
187
+ token.Enable();
188
+
189
+ StructBroadcastMessage message = new StructBroadcastMessage(7);
190
+ bus.EmitBroadcast(source, ref message);
191
+
192
+ Assert.AreEqual(1, count);
193
+ token.Disable();
194
+ }
195
+
196
+ [Test]
197
+ public void EmitStringHelpersUseBus()
198
+ {
199
+ MessageBus bus = new MessageBus();
200
+ InstanceId target = new InstanceId(11);
201
+ InstanceId source = new InstanceId(12);
202
+
203
+ MessageHandler handler = new MessageHandler(new InstanceId(50), bus) { active = true };
204
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, bus);
205
+ string targeted = null;
206
+ string broadcast = null;
207
+ string untargeted = null;
208
+
209
+ _ = token.RegisterTargeted<StringMessage>(
210
+ target,
211
+ (ref StringMessage m) => targeted = m.message
212
+ );
213
+
214
+ _ = token.RegisterBroadcast<SourcedStringMessage>(
215
+ source,
216
+ (ref SourcedStringMessage m) => broadcast = m.message
217
+ );
218
+
219
+ _ = token.RegisterUntargeted<GlobalStringMessage>(
220
+ (ref GlobalStringMessage m) => untargeted = m.message
221
+ );
222
+
223
+ token.Enable();
224
+
225
+ bus.EmitAt(target, "target");
226
+ bus.EmitFrom(source, "broadcast");
227
+ bus.Emit("untargeted");
228
+
229
+ Assert.AreEqual("target", targeted);
230
+ Assert.AreEqual("broadcast", broadcast);
231
+ Assert.AreEqual("untargeted", untargeted);
232
+
233
+ token.Disable();
234
+ }
235
+
236
+ private sealed class ClassUntargetedMessage : IUntargetedMessage { }
237
+
238
+ private readonly struct StructUntargetedMessage : IUntargetedMessage
239
+ {
240
+ internal StructUntargetedMessage(int value)
241
+ {
242
+ Value = value;
243
+ }
244
+
245
+ internal int Value { get; }
246
+ }
247
+
248
+ private struct StructInterceptedMessage : IUntargetedMessage
249
+ {
250
+ internal StructInterceptedMessage(int value)
251
+ {
252
+ Value = value;
253
+ }
254
+
255
+ internal int Value;
256
+ }
257
+
258
+ private readonly struct StructTargetedMessage : ITargetedMessage
259
+ {
260
+ internal StructTargetedMessage(int value)
261
+ {
262
+ Value = value;
263
+ }
264
+
265
+ internal int Value { get; }
266
+ }
267
+
268
+ private readonly struct StructBroadcastMessage : IBroadcastMessage
269
+ {
270
+ internal StructBroadcastMessage(int value)
271
+ {
272
+ Value = value;
273
+ }
274
+
275
+ internal int Value { get; }
276
+ }
277
+ }
278
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 3eb102d745b7a274682d6de7f87281e8
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,289 @@
1
+ namespace DxMessaging.Tests.Runtime.Core.Extensions
2
+ {
3
+ using DxMessaging.Core;
4
+ using DxMessaging.Core.Extensions;
5
+ using DxMessaging.Core.MessageBus;
6
+ using DxMessaging.Core.Messages;
7
+ using NUnit.Framework;
8
+ using MessageBus = DxMessaging.Core.MessageBus.MessageBus;
9
+
10
+ [TestFixture]
11
+ public sealed class MessageExtensionsProviderTests
12
+ {
13
+ private IMessageBus _originalGlobalBus;
14
+
15
+ [SetUp]
16
+ public void SetUp()
17
+ {
18
+ _originalGlobalBus = MessageHandler.MessageBus;
19
+ MessageHandler.ResetGlobalMessageBus();
20
+ }
21
+
22
+ [TearDown]
23
+ public void TearDown()
24
+ {
25
+ MessageHandler.SetGlobalMessageBus(_originalGlobalBus);
26
+ }
27
+
28
+ [Test]
29
+ public void GlobalMessageBusProviderReturnsGlobalSingleton()
30
+ {
31
+ MessageBus customBus = new();
32
+ MessageHandler.SetGlobalMessageBus(customBus);
33
+
34
+ IMessageBus resolved = GlobalMessageBusProvider.Instance.Resolve();
35
+
36
+ Assert.AreSame(customBus, resolved);
37
+ }
38
+
39
+ [Test]
40
+ public void EmitUntargetedWithProviderUsesProvidedBus()
41
+ {
42
+ MessageBus providerBus = new();
43
+ MessageHandler handler = new(new InstanceId(101), providerBus) { active = true };
44
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, providerBus);
45
+ int providerCount = 0;
46
+ _ = token.RegisterUntargeted((ref TestUntargetedMessage _) => providerCount++);
47
+ token.Enable();
48
+
49
+ MessageHandler globalHandler = new(new InstanceId(102)) { active = true };
50
+ MessageRegistrationToken globalToken = MessageRegistrationToken.Create(
51
+ globalHandler,
52
+ MessageHandler.MessageBus
53
+ );
54
+ int globalCount = 0;
55
+ _ = globalToken.RegisterUntargeted((ref TestUntargetedMessage _) => globalCount++);
56
+ globalToken.Enable();
57
+
58
+ TestUntargetedMessage message = new(5);
59
+ TestMessageBusProvider provider = new(providerBus);
60
+ message.EmitUntargeted(messageBusProvider: provider);
61
+
62
+ Assert.AreEqual(1, providerCount);
63
+ Assert.AreEqual(0, globalCount);
64
+
65
+ token.Disable();
66
+ globalToken.Disable();
67
+ }
68
+
69
+ [Test]
70
+ public void EmitUntargetedWithNullProviderFallsBackToGlobalBus()
71
+ {
72
+ MessageHandler globalHandler = new(new InstanceId(201)) { active = true };
73
+ MessageRegistrationToken globalToken = MessageRegistrationToken.Create(
74
+ globalHandler,
75
+ MessageHandler.MessageBus
76
+ );
77
+ int globalCount = 0;
78
+ _ = globalToken.RegisterUntargeted((ref TestUntargetedMessage _) => globalCount++);
79
+ globalToken.Enable();
80
+
81
+ TestUntargetedMessage message = new(9);
82
+ NullMessageBusProvider provider = new();
83
+ message.EmitUntargeted(messageBusProvider: provider);
84
+
85
+ Assert.AreEqual(1, provider.ResolveCount);
86
+ Assert.AreEqual(1, globalCount);
87
+
88
+ globalToken.Disable();
89
+ }
90
+
91
+ [Test]
92
+ public void EmitUntargetedPrefersExplicitBusOverProvider()
93
+ {
94
+ MessageBus explicitBus = new();
95
+ MessageBus providerBus = new();
96
+
97
+ MessageHandler explicitHandler = new(new InstanceId(301), explicitBus)
98
+ {
99
+ active = true,
100
+ };
101
+ MessageRegistrationToken explicitToken = MessageRegistrationToken.Create(
102
+ explicitHandler,
103
+ explicitBus
104
+ );
105
+ int explicitCount = 0;
106
+ _ = explicitToken.RegisterUntargeted((ref TestUntargetedMessage _) => explicitCount++);
107
+ explicitToken.Enable();
108
+
109
+ MessageHandler providerHandler = new(new InstanceId(302), providerBus)
110
+ {
111
+ active = true,
112
+ };
113
+ MessageRegistrationToken providerToken = MessageRegistrationToken.Create(
114
+ providerHandler,
115
+ providerBus
116
+ );
117
+ int providerCount = 0;
118
+ _ = providerToken.RegisterUntargeted((ref TestUntargetedMessage _) => providerCount++);
119
+ providerToken.Enable();
120
+
121
+ TestUntargetedMessage message = new(11);
122
+ TestMessageBusProvider provider = new(providerBus);
123
+ message.EmitUntargeted(explicitBus, provider);
124
+
125
+ Assert.AreEqual(1, explicitCount);
126
+ Assert.AreEqual(0, providerCount);
127
+
128
+ explicitToken.Disable();
129
+ providerToken.Disable();
130
+ }
131
+
132
+ [Test]
133
+ public void EmitTargetedWithProviderRoutesToProviderBus()
134
+ {
135
+ MessageBus providerBus = new();
136
+ InstanceId target = new(901);
137
+
138
+ MessageHandler handler = new(new InstanceId(401), providerBus) { active = true };
139
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, providerBus);
140
+ int providerCount = 0;
141
+ _ = token.RegisterTargeted(target, (ref TestTargetedMessage _) => providerCount++);
142
+ token.Enable();
143
+
144
+ MessageHandler globalHandler = new(new InstanceId(402)) { active = true };
145
+ MessageRegistrationToken globalToken = MessageRegistrationToken.Create(
146
+ globalHandler,
147
+ MessageHandler.MessageBus
148
+ );
149
+ int globalCount = 0;
150
+ _ = globalToken.RegisterTargeted(target, (ref TestTargetedMessage _) => globalCount++);
151
+ globalToken.Enable();
152
+
153
+ TestTargetedMessage message = new(17);
154
+ TestMessageBusProvider provider = new(providerBus);
155
+ message.EmitTargeted(target, messageBusProvider: provider);
156
+
157
+ Assert.AreEqual(1, providerCount);
158
+ Assert.AreEqual(0, globalCount);
159
+
160
+ token.Disable();
161
+ globalToken.Disable();
162
+ }
163
+
164
+ [Test]
165
+ public void EmitBroadcastWithProviderRoutesToProviderBus()
166
+ {
167
+ MessageBus providerBus = new();
168
+ InstanceId source = new(777);
169
+
170
+ MessageHandler handler = new(new InstanceId(501), providerBus) { active = true };
171
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, providerBus);
172
+ int providerCount = 0;
173
+ _ = token.RegisterBroadcast(source, (ref TestBroadcastMessage _) => providerCount++);
174
+ token.Enable();
175
+
176
+ MessageHandler globalHandler = new(new InstanceId(502)) { active = true };
177
+ MessageRegistrationToken globalToken = MessageRegistrationToken.Create(
178
+ globalHandler,
179
+ MessageHandler.MessageBus
180
+ );
181
+ int globalCount = 0;
182
+ _ = globalToken.RegisterBroadcast(
183
+ source,
184
+ (ref TestBroadcastMessage _) => globalCount++
185
+ );
186
+ globalToken.Enable();
187
+
188
+ TestBroadcastMessage message = new(23);
189
+ TestMessageBusProvider provider = new(providerBus);
190
+ message.EmitBroadcast(source, messageBusProvider: provider);
191
+
192
+ Assert.AreEqual(1, providerCount);
193
+ Assert.AreEqual(0, globalCount);
194
+
195
+ token.Disable();
196
+ globalToken.Disable();
197
+ }
198
+
199
+ [Test]
200
+ public void StringEmitUsesProvidedBus()
201
+ {
202
+ MessageBus providerBus = new();
203
+ InstanceId target = new(1234);
204
+
205
+ MessageHandler handler = new(new InstanceId(601), providerBus) { active = true };
206
+ MessageRegistrationToken token = MessageRegistrationToken.Create(handler, providerBus);
207
+ string? received = null;
208
+ _ = token.RegisterTargeted(target, (ref StringMessage m) => received = m.message);
209
+ token.Enable();
210
+
211
+ MessageHandler globalHandler = new(new InstanceId(602)) { active = true };
212
+ MessageRegistrationToken globalToken = MessageRegistrationToken.Create(
213
+ globalHandler,
214
+ MessageHandler.MessageBus
215
+ );
216
+ string? globalReceived = null;
217
+ _ = globalToken.RegisterTargeted(
218
+ target,
219
+ (ref StringMessage m) => globalReceived = m.message
220
+ );
221
+ globalToken.Enable();
222
+
223
+ TestMessageBusProvider provider = new(providerBus);
224
+ "provider-route".Emit(target, messageBusProvider: provider);
225
+
226
+ Assert.AreEqual("provider-route", received);
227
+ Assert.IsNull(globalReceived);
228
+
229
+ token.Disable();
230
+ globalToken.Disable();
231
+ }
232
+
233
+ private sealed class TestMessageBusProvider : IMessageBusProvider
234
+ {
235
+ private readonly IMessageBus _bus;
236
+
237
+ public TestMessageBusProvider(IMessageBus bus)
238
+ {
239
+ _bus = bus;
240
+ }
241
+
242
+ public IMessageBus Resolve()
243
+ {
244
+ return _bus;
245
+ }
246
+ }
247
+
248
+ private sealed class NullMessageBusProvider : IMessageBusProvider
249
+ {
250
+ public int ResolveCount { get; private set; }
251
+
252
+ public IMessageBus Resolve()
253
+ {
254
+ ResolveCount++;
255
+ return null;
256
+ }
257
+ }
258
+
259
+ private readonly struct TestUntargetedMessage : IUntargetedMessage
260
+ {
261
+ public TestUntargetedMessage(int value)
262
+ {
263
+ Value = value;
264
+ }
265
+
266
+ public int Value { get; }
267
+ }
268
+
269
+ private readonly struct TestTargetedMessage : ITargetedMessage
270
+ {
271
+ public TestTargetedMessage(int value)
272
+ {
273
+ Value = value;
274
+ }
275
+
276
+ public int Value { get; }
277
+ }
278
+
279
+ private readonly struct TestBroadcastMessage : IBroadcastMessage
280
+ {
281
+ public TestBroadcastMessage(int value)
282
+ {
283
+ Value = value;
284
+ }
285
+
286
+ public int Value { get; }
287
+ }
288
+ }
289
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: cbdf955d8072cd743bc4c6bb87a25a1a
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 5f66800fd9454f54880213d6b7a72a72
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,57 @@
1
+ namespace DxMessaging.Tests.Runtime.Core
2
+ {
3
+ using System;
4
+ using NUnit.Framework;
5
+
6
+ public sealed class IntegrationShimSmokeTests
7
+ {
8
+ [Test]
9
+ public void ZenjectShimTypeAvailableWhenDefined()
10
+ {
11
+ #if ZENJECT_PRESENT
12
+ AssertIntegrationType(
13
+ "DxMessaging.Unity.Integrations.Zenject.DxMessagingRegistrationInstaller",
14
+ "WallstopStudios.DxMessaging.Zenject"
15
+ );
16
+ #else
17
+ Assert.Ignore("ZENJECT_PRESENT not defined; skipping Zenject shim smoke test.");
18
+ #endif
19
+ }
20
+
21
+ [Test]
22
+ public void VContainerShimTypeAvailableWhenDefined()
23
+ {
24
+ #if VCONTAINER_PRESENT
25
+ AssertIntegrationType(
26
+ "DxMessaging.Unity.Integrations.VContainer.VContainerRegistrationExtensions",
27
+ "WallstopStudios.DxMessaging.VContainer"
28
+ );
29
+ #else
30
+ Assert.Ignore("VCONTAINER_PRESENT not defined; skipping VContainer shim smoke test.");
31
+ #endif
32
+ }
33
+
34
+ [Test]
35
+ public void ReflexShimTypeAvailableWhenDefined()
36
+ {
37
+ #if REFLEX_PRESENT
38
+ AssertIntegrationType(
39
+ "DxMessaging.Unity.Integrations.Reflex.DxMessagingRegistrationInstaller",
40
+ "WallstopStudios.DxMessaging.Reflex"
41
+ );
42
+ #else
43
+ Assert.Ignore("REFLEX_PRESENT not defined; skipping Reflex shim smoke test.");
44
+ #endif
45
+ }
46
+
47
+ private static void AssertIntegrationType(string typeName, string assemblyName)
48
+ {
49
+ string qualifiedName = $"{typeName}, {assemblyName}";
50
+ Type type = Type.GetType(qualifiedName, throwOnError: false);
51
+ Assert.IsNotNull(
52
+ type,
53
+ $"Expected type '{qualifiedName}' to be available when the corresponding scripting define is set."
54
+ );
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 2f56f0d5a857ed048abc4485e4152810
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant: