com.wallstop-studios.dxmessaging 2.0.0-rc27.3.1 → 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 (185) 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 +1352 -141
  10. package/Docs/Compatibility.md +27 -0
  11. package/Docs/DesignAndArchitecture.md +41 -34
  12. package/Docs/EmitShorthands.md +34 -0
  13. package/Docs/GettingStarted.md +84 -17
  14. package/Docs/Helpers.md +1 -1
  15. package/Docs/Index.md +28 -25
  16. package/Docs/Install.md +29 -6
  17. package/Docs/Integrations/Reflex.md +292 -0
  18. package/Docs/Integrations/Reflex.md.meta +7 -0
  19. package/Docs/Integrations/VContainer.md +324 -0
  20. package/Docs/Integrations/VContainer.md.meta +7 -0
  21. package/Docs/Integrations/Zenject.md +333 -0
  22. package/Docs/Integrations/Zenject.md.meta +7 -0
  23. package/{Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.pdb.meta → Docs/Integrations.meta} +2 -1
  24. package/Docs/InterceptorsAndOrdering.md +371 -17
  25. package/Docs/ListeningPatterns.md +206 -0
  26. package/Docs/MessageBusProviders.md +496 -0
  27. package/Docs/MessageBusProviders.md.meta +7 -0
  28. package/Docs/MessageTypes.md +27 -0
  29. package/Docs/MigrationGuide.md +45 -0
  30. package/Docs/Overview.md +114 -20
  31. package/Docs/Patterns.md +327 -2
  32. package/Docs/Performance.md +9 -9
  33. package/Docs/QuickReference.md +31 -0
  34. package/Docs/RuntimeConfiguration.md +407 -0
  35. package/Docs/RuntimeConfiguration.md.meta +7 -0
  36. package/Docs/UnityIntegration.md +3 -1
  37. package/Docs/VisualGuide.md +281 -167
  38. package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll +0 -0
  39. package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +3 -3
  40. package/Editor/Analyzers/Microsoft.CodeAnalysis.dll +0 -0
  41. package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +2 -2
  42. package/Editor/Analyzers/System.Collections.Immutable.dll +0 -0
  43. package/Editor/Analyzers/System.Reflection.Metadata.dll +0 -0
  44. package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll +0 -0
  45. package/Editor/CustomEditors/MessagingComponentEditor.cs +15 -6
  46. package/README.md +388 -67
  47. package/Runtime/AssemblyInfo.cs +4 -0
  48. package/Runtime/Core/Extensions/MessageBusExtensions.cs +253 -0
  49. package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +12 -0
  50. package/Runtime/Core/Extensions/MessageExtensions.cs +137 -89
  51. package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs +23 -0
  52. package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs.meta +11 -0
  53. package/Runtime/Core/MessageBus/IMessageBusProvider.cs +14 -0
  54. package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +11 -0
  55. package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +18 -0
  56. package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs.meta +11 -0
  57. package/Runtime/Core/MessageBus/MessageBusRebindMode.cs +26 -0
  58. package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +11 -0
  59. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +383 -0
  60. package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs.meta +11 -0
  61. package/Runtime/Core/MessageHandler.cs +198 -27
  62. package/Runtime/Core/MessageRegistrationToken.cs +67 -25
  63. package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs +31 -0
  64. package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs.meta +12 -0
  65. package/Runtime/Unity/InitialGlobalMessageBusProvider.cs +38 -0
  66. package/Runtime/Unity/InitialGlobalMessageBusProvider.cs.meta +12 -0
  67. package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs +11 -0
  68. package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +3 -0
  69. package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +73 -0
  70. package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs.meta +11 -0
  71. package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef +20 -0
  72. package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef.meta +7 -0
  73. package/Runtime/Unity/Integrations/Reflex.meta +8 -0
  74. package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs +11 -0
  75. package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
  76. package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +46 -0
  77. package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs.meta +11 -0
  78. package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef +30 -0
  79. package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef.meta +7 -0
  80. package/Runtime/Unity/Integrations/VContainer.meta +8 -0
  81. package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs +11 -0
  82. package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
  83. package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef +30 -0
  84. package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef.meta +7 -0
  85. package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +55 -0
  86. package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs.meta +11 -0
  87. package/Runtime/Unity/Integrations/Zenject.meta +8 -0
  88. package/Runtime/Unity/Integrations.meta +8 -0
  89. package/Runtime/Unity/MessageAwareComponent.cs +102 -0
  90. package/Runtime/Unity/MessageBusProviderHandle.cs +97 -0
  91. package/Runtime/Unity/MessageBusProviderHandle.cs.meta +12 -0
  92. package/Runtime/Unity/MessagingComponent.cs +164 -2
  93. package/Runtime/Unity/MessagingComponentInstaller.cs +120 -0
  94. package/Runtime/Unity/MessagingComponentInstaller.cs.meta +12 -0
  95. package/Runtime/Unity/ScriptableMessageBusProvider.cs +14 -0
  96. package/Runtime/Unity/ScriptableMessageBusProvider.cs.meta +12 -0
  97. package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab +98 -0
  98. package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab.meta +7 -0
  99. package/Samples~/DI/Prefabs.meta +8 -0
  100. package/Samples~/DI/Providers/GlobalMessageBusProvider.asset +14 -0
  101. package/Samples~/DI/Providers/GlobalMessageBusProvider.asset.meta +8 -0
  102. package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset +14 -0
  103. package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset.meta +8 -0
  104. package/Samples~/DI/Providers.meta +8 -0
  105. package/Samples~/DI/README.md +51 -0
  106. package/Samples~/DI/README.md.meta +7 -0
  107. package/Samples~/DI/Reflex/SampleInstaller.cs +75 -0
  108. package/Samples~/DI/Reflex/SampleInstaller.cs.meta +11 -0
  109. package/Samples~/DI/Reflex.meta +8 -0
  110. package/Samples~/DI/VContainer/SampleLifetimeScope.cs +81 -0
  111. package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +11 -0
  112. package/Samples~/DI/VContainer.meta +8 -0
  113. package/Samples~/DI/Zenject/SampleInstaller.cs +67 -0
  114. package/Samples~/DI/Zenject/SampleInstaller.cs.meta +11 -0
  115. package/Samples~/DI/Zenject.meta +8 -0
  116. package/Samples~/DI.meta +8 -0
  117. package/Samples~/Mini Combat/README.md +86 -28
  118. package/Samples~/Mini Combat/Walkthrough.md +41 -25
  119. package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs +12 -2
  120. package/Samples~/UI Buttons + Inspector/README.md +55 -12
  121. package/Samples~/UI Buttons + Inspector/README.md.meta +7 -0
  122. package/Tests/Runtime/Benchmarks/BenchmarkSession.cs +444 -0
  123. package/Tests/Runtime/Benchmarks/BenchmarkSession.cs.meta +11 -0
  124. package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs +94 -0
  125. package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs.meta +11 -0
  126. package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs +395 -0
  127. package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs.meta +11 -0
  128. package/Tests/Runtime/Benchmarks/PerformanceTests.cs +77 -429
  129. package/Tests/Runtime/Benchmarks/ProviderResolutionBenchmarks.cs +142 -0
  130. package/Tests/Runtime/Benchmarks/ProviderResolutionBenchmarks.cs.meta +12 -0
  131. package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef +50 -0
  132. package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef.meta +7 -0
  133. package/Tests/Runtime/Core/DefaultBusFallbackTests.cs +333 -0
  134. package/Tests/Runtime/Core/DefaultBusFallbackTests.cs.meta +11 -0
  135. package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs +278 -0
  136. package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs.meta +11 -0
  137. package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs +289 -0
  138. package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs.meta +11 -0
  139. package/Tests/Runtime/Core/Extensions.meta +8 -0
  140. package/Tests/Runtime/Core/IntegrationShimSmokeTests.cs +57 -0
  141. package/Tests/Runtime/Core/IntegrationShimSmokeTests.cs.meta +11 -0
  142. package/Tests/Runtime/Core/MessageHandlerGlobalBusTests.cs +219 -0
  143. package/Tests/Runtime/Core/MessageHandlerGlobalBusTests.cs.meta +11 -0
  144. package/Tests/Runtime/Core/MessageRegistrationBuilderTests.cs +204 -0
  145. package/Tests/Runtime/Core/MessageRegistrationBuilderTests.cs.meta +11 -0
  146. package/Tests/Runtime/Core/MessagingTestBase.cs +4 -4
  147. package/Tests/Runtime/Core/NominalTests.cs +2 -2
  148. package/Tests/Runtime/Core/SourceGeneratorNestedTests.cs +1 -1
  149. package/Tests/Runtime/Core/TypedShorthandTests.cs +2 -2
  150. package/Tests/Runtime/Core/UntargetedEquivalenceTests.cs +1 -1
  151. package/Tests/Runtime/Core/UntargetedPrefreezeTests.cs +2 -4
  152. package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs +162 -0
  153. package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs.meta +11 -0
  154. package/Tests/Runtime/Integrations/Reflex/Resources/ReflexSettings.asset +16 -0
  155. package/Tests/Runtime/Integrations/Reflex/Resources/ReflexSettings.asset.meta +8 -0
  156. package/Tests/Runtime/Integrations/Reflex/Resources.meta +8 -0
  157. package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef +27 -0
  158. package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef.meta +7 -0
  159. package/Tests/Runtime/Integrations/Reflex.meta +8 -0
  160. package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs +140 -0
  161. package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs.meta +11 -0
  162. package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef +37 -0
  163. package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef.meta +7 -0
  164. package/Tests/Runtime/Integrations/VContainer.meta +8 -0
  165. package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef +37 -0
  166. package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef.meta +7 -0
  167. package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs +140 -0
  168. package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs.meta +11 -0
  169. package/Tests/Runtime/Integrations/Zenject.meta +8 -0
  170. package/Tests/Runtime/Integrations.meta +8 -0
  171. package/Tests/Runtime/Scripts/Components/EmptyMessageAwareComponent.cs +1 -1
  172. package/Tests/Runtime/Scripts/Components/GenericMessageAwareComponent.cs +1 -1
  173. package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs +1 -1
  174. package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs +64 -0
  175. package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs.meta +12 -0
  176. package/Tests/Runtime/TestUtilities.meta +9 -0
  177. package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs +57 -0
  178. package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs.meta +11 -0
  179. package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs +107 -0
  180. package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs.meta +12 -0
  181. package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs +210 -0
  182. package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs.meta +12 -0
  183. package/Tests/Runtime/Unity.meta +9 -0
  184. package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.asmdef +3 -1
  185. package/package.json +1 -1
@@ -0,0 +1,51 @@
1
+ # DxMessaging DI Samples
2
+
3
+ These snippets illustrate how to consume `IMessageRegistrationBuilder` inside common Unity dependency injection containers. The scripts compile only when the corresponding scripting define is enabled and the container package is present.
4
+
5
+ ## Setup
6
+
7
+ 1. Install the relevant container package (Zenject/Extenject, VContainer, or Reflex) into your Unity project.
8
+ 2. Enable the matching scripting define symbol in **Project Settings › Player › Scripting Define Symbols**:
9
+ - `ZENJECT_PRESENT`
10
+ - `VCONTAINER_PRESENT`
11
+ - `REFLEX_PRESENT`
12
+ 3. Import the sample folder you need into your Unity project (`Assets/Samples/DxMessaging/*`).
13
+
14
+ Each sample shows:
15
+
16
+ - Registering `IMessageRegistrationBuilder` via the provided shim under `Runtime/Unity/Integrations/`.
17
+ - Constructing a `MessageRegistrationLease` in a container-managed service.
18
+ - Activating/deactivating the lease using the container lifecycle.
19
+
20
+ ### Structure
21
+
22
+ - `Zenject/SampleInstaller.cs`
23
+ - `VContainer/SampleLifetimeScope.cs`
24
+ - `Reflex/SampleInstaller.cs`
25
+ - `Providers/CurrentGlobalMessageBusProvider.asset` — ScriptableObject that resolves whichever bus is currently configured as global.
26
+ - `Providers/InitialGlobalMessageBusProvider.asset` — ScriptableObject that always returns the original startup global bus, ignoring later overrides.
27
+ - `Prefabs/MessagingInstallerSample.prefab` — ready-to-use hierarchy with `MessagingComponentInstaller` configuring a child `MessagingComponent` using the provider asset. Drop it into a scene to see provider-driven wiring without writing setup code.
28
+
29
+ ## Walkthrough
30
+
31
+ 1. **Place the prefab**
32
+ Drag `Prefabs/MessagingInstallerSample.prefab` into your test scene. The root object carries `MessagingComponentInstaller` with its provider handle already pointing at the global provider ScriptableObject.
33
+
34
+ 2. **Hook up the container**
35
+ - **Zenject**:
36
+ - Add `DxMessagingRegistrationInstaller` (from `Runtime/Unity/Integrations/`) to your ProjectContext or scene installer list.
37
+ - Drop `Zenject/SampleInstaller.cs` into your project and register it alongside other installers. When the scene runs, the installer resolves `IMessageRegistrationBuilder`, stages a `PlayerSpawned` listener, and activates via the Zenject lifecycle.
38
+ - **VContainer**:
39
+ - Define `VCONTAINER_PRESENT` and reference the optional extension under `Runtime/Unity/Integrations/VContainerRegistrationExtensions.cs`.
40
+ - Add `VContainer/SampleLifetimeScope` to the scene (or derive from it); the sample scope registers the builder and an entry point that emits/consumes `ScoreUpdated` messages each tick.
41
+ - **Reflex**:
42
+ - Enable `REFLEX_PRESENT` and install `DxMessagingRegistrationInstaller` into your container bootstrap.
43
+ - Include `Reflex/SampleInstaller` in your installer chain. The sample service resolves `IMessageRegistrationBuilder`, subscribes to `PlayerAlert`, and can emit alerts via `EmitAlertFor`.
44
+
45
+ 3. **Emit a message**
46
+ Use the service exposed by the container (e.g., call into `ScoreboardService` or `PlayerAlertService`) to emit a message. Because the prefab already configured `MessagingComponent` instances via the installer, the listeners run immediately.
47
+
48
+ 4. **Swap providers** (optional)
49
+ Duplicate `Providers/CurrentGlobalMessageBusProvider.asset`, modify it to return a custom bus, assign it on the prefab root, and observe how builder-created leases now resolve that bus instead.
50
+
51
+ Feel free to duplicate these scripts into your own project and adjust lifecycles or message types as needed.
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: e3bac3e795986eb44becc1eadeb7756d
3
+ TextScriptImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -0,0 +1,75 @@
1
+ #if REFLEX_PRESENT
2
+ namespace DxMessaging.Samples.DI.Reflex
3
+ {
4
+ using DxMessaging.Core;
5
+ using DxMessaging.Core.MessageBus;
6
+ using DxMessaging.Core.Messages;
7
+ using DxMessaging.Unity.Integrations.Reflex;
8
+ using Reflex.Core;
9
+ using UnityEngine;
10
+
11
+ /// <summary>
12
+ /// Demonstrates wiring <see cref="IMessageRegistrationBuilder"/> inside a Reflex container.
13
+ /// Requires the Reflex package and the REFLEX_PRESENT scripting define.
14
+ /// </summary>
15
+ public sealed class SampleInstaller : Installer
16
+ {
17
+ protected override void InstallBindings()
18
+ {
19
+ Container.Bind<MessageBus>().AsSingleton();
20
+ Container.Bind<IMessageBus>().FromContainer<MessageBus>();
21
+
22
+ // The DxMessagingRegistrationInstaller shim will have been installed elsewhere; we simply resolve the builder.
23
+ Container.Bind<PlayerAlertService>().AsSingleton();
24
+ }
25
+
26
+ private sealed class PlayerAlertService : System.IDisposable
27
+ {
28
+ private readonly IMessageBus _messageBus;
29
+ private readonly MessageRegistrationLease _lease;
30
+
31
+ public PlayerAlertService(IMessageBus messageBus, IMessageRegistrationBuilder builder)
32
+ {
33
+ _messageBus = messageBus;
34
+ _lease = builder.Build(
35
+ new MessageRegistrationBuildOptions
36
+ {
37
+ Configure = token =>
38
+ {
39
+ _ = token.RegisterBroadcastWithoutSource<PlayerAlert>(OnPlayerAlert);
40
+ },
41
+ HandlerStartsActive = true,
42
+ ActivateOnBuild = true,
43
+ }
44
+ );
45
+ }
46
+
47
+ public void EmitAlertFor(GameObject source)
48
+ {
49
+ PlayerAlert alert = new PlayerAlert(source);
50
+ _messageBus.Emit(ref alert);
51
+ }
52
+
53
+ public void Dispose()
54
+ {
55
+ _lease.Dispose();
56
+ }
57
+
58
+ private void OnPlayerAlert(ref InstanceId source, ref PlayerAlert alert)
59
+ {
60
+ Debug.Log($"Reflex alert from {source.Id}");
61
+ }
62
+ }
63
+
64
+ private readonly struct PlayerAlert : IBroadcastMessage
65
+ {
66
+ public PlayerAlert(InstanceId source)
67
+ {
68
+ Source = source;
69
+ }
70
+
71
+ public InstanceId Source { get; }
72
+ }
73
+ }
74
+ }
75
+ #endif
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 7d4c41a51a756ed40a140efe764197a9
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: 0ea2325747ab75e4589eac788c59b276
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,81 @@
1
+ #if VCONTAINER_PRESENT
2
+ namespace DxMessaging.Samples.DI.VContainer
3
+ {
4
+ using System;
5
+ using Core.Attributes;
6
+ using Core.Extensions;
7
+ using Core.MessageBus;
8
+ using DxMessaging.Unity.Integrations.VContainer;
9
+ using UnityEngine;
10
+ using VContainer;
11
+ using VContainer.Unity;
12
+
13
+ /// <summary>
14
+ /// Sample lifetime scope showing DI-friendly registration via IMessageRegistrationBuilder.
15
+ /// Requires the VCONTAINER_PRESENT scripting define and VContainer package.
16
+ /// </summary>
17
+ public sealed class SampleLifetimeScope : LifetimeScope
18
+ {
19
+ protected override void Configure(IContainerBuilder builder)
20
+ {
21
+ builder.Register<MessageBus.MessageBus>(Lifetime.Singleton).As<IMessageBus>();
22
+ builder.RegisterMessageRegistrationBuilder();
23
+
24
+ builder.RegisterEntryPoint<ScoreboardService>(Lifetime.Singleton);
25
+ }
26
+
27
+ [DxUntargetedMessage]
28
+ private readonly struct ScoreUpdated
29
+ {
30
+ public readonly int Value;
31
+
32
+ public ScoreUpdated(int value)
33
+ {
34
+ Value = value;
35
+ }
36
+ }
37
+
38
+ private sealed class ScoreboardService : IStartable, ITickable, IDisposable
39
+ {
40
+ private readonly MessageRegistrationLease lease;
41
+ private int observedScores;
42
+
43
+ public ScoreboardService(IMessageRegistrationBuilder registrationBuilder)
44
+ {
45
+ lease = registrationBuilder.Build(
46
+ new MessageRegistrationBuildOptions
47
+ {
48
+ Configure = token =>
49
+ {
50
+ _ = token.RegisterUntargeted<ScoreUpdated>(OnScoreUpdated);
51
+ },
52
+ }
53
+ );
54
+ }
55
+
56
+ public void Start()
57
+ {
58
+ lease.Activate();
59
+ }
60
+
61
+ public void Tick()
62
+ {
63
+ // Emit periodically for demo purposes
64
+ ScoreUpdated message = new ScoreUpdated(UnityEngine.Random.Range(0, 100));
65
+ message.Emit();
66
+ }
67
+
68
+ public void Dispose()
69
+ {
70
+ lease.Dispose();
71
+ }
72
+
73
+ private void OnScoreUpdated(ref ScoreUpdated message)
74
+ {
75
+ observedScores = message.Value;
76
+ Debug.Log($"Score observed: {observedScores}");
77
+ }
78
+ }
79
+ }
80
+ }
81
+ #endif
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 6dea981cef444594bbffa73a5e6905d5
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: e08544c97dd3b1540886f6b5f5f8f111
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,67 @@
1
+ #if ZENJECT_PRESENT
2
+ namespace DxMessaging.Samples.DI.Zenject
3
+ {
4
+ using System;
5
+ using Core.Attributes;
6
+ using Core.MessageBus;
7
+ using UnityEngine;
8
+ using Zenject;
9
+
10
+ /// <summary>
11
+ /// Sample scene installer demonstrating how to bridge the registration builder into Zenject services.
12
+ /// Requires the DxMessaging Zenject registration shim and the ZENJECT_PRESENT scripting define.
13
+ /// </summary>
14
+ public sealed class SampleInstaller : MonoInstaller
15
+ {
16
+ public override void InstallBindings()
17
+ {
18
+ // Ensure the builder is available (provided by DxMessagingRegistrationInstaller).
19
+ Container.BindInterfacesTo<PlayerSpawnTracker>().AsSingle();
20
+ }
21
+
22
+ [DxUntargetedMessage]
23
+ private readonly struct PlayerSpawned
24
+ {
25
+ public readonly string PlayerName;
26
+
27
+ public PlayerSpawned(string playerName)
28
+ {
29
+ PlayerName = playerName;
30
+ }
31
+ }
32
+
33
+ private sealed class PlayerSpawnTracker : IInitializable, IDisposable
34
+ {
35
+ private readonly MessageRegistrationLease lease;
36
+
37
+ public PlayerSpawnTracker(IMessageRegistrationBuilder builder)
38
+ {
39
+ lease = builder.Build(
40
+ new MessageRegistrationBuildOptions
41
+ {
42
+ Configure = token =>
43
+ {
44
+ _ = token.RegisterUntargeted<PlayerSpawned>(OnPlayerSpawned);
45
+ },
46
+ }
47
+ );
48
+ }
49
+
50
+ public void Initialize()
51
+ {
52
+ lease.Activate();
53
+ }
54
+
55
+ public void Dispose()
56
+ {
57
+ lease.Dispose();
58
+ }
59
+
60
+ private static void OnPlayerSpawned(ref PlayerSpawned message)
61
+ {
62
+ Debug.Log($"Player spawned: {message.PlayerName}");
63
+ }
64
+ }
65
+ }
66
+ }
67
+ #endif
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 85ad1f9014b26d34caddf778e694f493
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: f772f4742ae2c4d4d8160700ab28009b
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 7f6cc70d4b4c2684b82c30c14d1ae67e
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -1,16 +1,79 @@
1
1
  # Mini Combat Sample
2
2
 
3
- > **What You'll Learn**: This sample demonstrates a simple combat system using DxMessaging to show how components communicate through messages. Perfect for beginners learning the messaging system!
3
+ > **Perfect for:** First-time users who want to see messaging in action with a working combat example
4
4
 
5
- ## Overview
5
+ ## What You'll Learn in 10 Minutes
6
6
 
7
- This mini-sample showcases a basic combat loop using DxMessaging with Unity-friendly APIs. You'll see how different game objects (Player, Enemy, UI) communicate without direct references to each other.
7
+ **Stop reading documentation and start seeing it work!** This sample shows:
8
8
 
9
- ### Key Concepts Demonstrated:
9
+ 1. How Player heals without UI knowing about Player (**zero coupling**)
10
+ 2. How Enemy broadcasts damage without knowing who cares (**observer pattern**)
11
+ 3. How settings changes update everything automatically (**global events**)
10
12
 
11
- - **Untargeted Messages**: Global messages anyone can listen to (like game settings)
12
- - **Targeted Messages**: Messages sent to a specific component (like healing a player)
13
- - **Broadcast Messages**: Messages announced to all listeners (like damage events)
13
+ **No prior messaging experience needed** - this sample walks you through everything.
14
+
15
+ ---
16
+
17
+ ## Why This Sample Matters
18
+
19
+ ### Before DxMessaging:
20
+
21
+ ```csharp
22
+ public class Player {
23
+ [SerializeField] private UI ui; // Coupling!
24
+ [SerializeField] private AudioManager audio; // More coupling!
25
+
26
+ void Heal(int amount) {
27
+ health += amount;
28
+ ui.UpdateHealth(health); // Manual call
29
+ audio.PlayHealSound(); // Manual call
30
+ }
31
+ }
32
+ ```
33
+
34
+ #### Every new system = another SerializeField + another manual call.
35
+
36
+ ##### With DxMessaging:
37
+
38
+ ```csharp
39
+ public class Player : MessageAwareComponent {
40
+ void Heal(int amount) {
41
+ health += amount;
42
+ new PlayerHealed(amount).EmitBroadcast(this);
43
+ // Done! UI, audio, analytics all react automatically.
44
+ }
45
+ }
46
+ ```
47
+
48
+ ###### Zero coupling. Zero manual wiring. That's the power of messaging.
49
+
50
+ ---
51
+
52
+ ## Key Concepts (3 Message Types)
53
+
54
+ ### 1. Untargeted - "Everyone, listen up!"
55
+
56
+ **Example:** Game settings changed
57
+
58
+ - Like a stadium announcement - everyone hears it
59
+ - No specific target
60
+ - Perfect for: settings, pause, scene transitions
61
+
62
+ ### 2. Targeted - "Hey YOU, do this!"
63
+
64
+ **Example:** Heal this specific player
65
+
66
+ - Like mailing a letter to one address
67
+ - Only the target receives it
68
+ - Perfect for: commands, direct actions
69
+
70
+ ### 3. Broadcast - "I did something!"
71
+
72
+ **Example:** Enemy took damage
73
+
74
+ - Like ringing a bell - anyone nearby can hear
75
+ - Source announces, observers react
76
+ - Perfect for: events, notifications, analytics
14
77
 
15
78
  ---
16
79
 
@@ -28,25 +91,22 @@ Here's what each script does:
28
91
 
29
92
  ---
30
93
 
31
- ## Quick Start Guide
94
+ ## Quick Start Guide (2 Minutes to Working Demo)
32
95
 
33
- ### Method 1: Import from Package Manager (Recommended)
96
+ ### Import & Run (Fastest Way)
34
97
 
35
- 1. **Open Package Manager**:
36
- - Window → Package Manager
98
+ #### Want to see it work immediately?
37
99
 
38
- 1. **Find DxMessaging**:
39
- - Look for "DxMessaging" in the package list
40
- - Click on it to select
100
+ 1. **Open Package Manager**: Window → Package Manager
101
+ 2. **Find DxMessaging** in the package list
102
+ 3. **Scroll to Samples** section → Find "Mini Combat" → Click **Import**
103
+ 4. **Navigate to** Assets/Samples/DxMessaging/.../Mini Combat/
104
+ 5. **Open the scene**
105
+ 6. **Press Play** 🎮
41
106
 
42
- 1. **Import the Sample**:
43
- - In the Package Manager details view, scroll down to find the "Samples" section
44
- - Find "Mini Combat" and click **Import**
45
- - The sample files will be imported into your Assets/Samples folder
107
+ **That's it!** Watch the Console logs as messages flow.
46
108
 
47
- 1. **Open the Scene**:
48
- - Navigate to Assets/Samples/DxMessaging/.../Mini Combat/
49
- - Open the sample scene or create a new scene and follow Step 1 below
109
+ **Pro tip:** Enable diagnostics in the Inspector (MessagingComponent → Enable Diagnostics) to see message traffic in real-time.
50
110
 
51
111
  ### Method 2: Manual Setup in Your Scene
52
112
 
@@ -87,13 +147,11 @@ Press Play! The Boot script will automatically:
87
147
 
88
148
  ### The Message Flow
89
149
 
90
- ```text
91
- Boot.cs (sends messages)
92
-
93
- ├─→ VideoSettingsChanged (Untargeted) → UIOverlay.cs (receives)
94
- ├─→ Heal (Targeted to Player) Player.cs (receives)
95
- └─→ TookDamage (Broadcast from Enemy) → UIOverlay.cs (receives)
96
- ```
150
+ #### Boot.cs sends messages:
151
+
152
+ 1. `VideoSettingsChanged` (Untargeted) → UIOverlay.cs receives
153
+ 2. `Heal` (Targeted to Player) → Player.cs receives
154
+ 3. `TookDamage` (Broadcast from Enemy) UIOverlay.cs receives
97
155
 
98
156
  ### Understanding Message Types
99
157
 
@@ -1,6 +1,28 @@
1
1
  # Mini Combat Walkthrough
2
2
 
3
- > **Deep Dive**: This walkthrough explains the implementation details and shows how all the sample scripts work together at runtime. Great for understanding the "why" behind the code!
3
+ > **Deep Dive**: Ready to understand HOW it works? This walkthrough explains every line of code and shows the complete message flow.
4
+
5
+ ## Who This Is For
6
+
7
+ - ✅ **You've imported and run the sample** - now you want to understand it
8
+ - ✅ **You want to build your own** - need to see the patterns in action
9
+ - ✅ **You're debugging something** - need to understand the flow
10
+
11
+ **Haven't run the sample yet?** Go back to [the sample README](README.md) and press Play first. Come back when you've seen it work.
12
+
13
+ ---
14
+
15
+ ## What You'll Understand By The End
16
+
17
+ After reading this walkthrough, you'll know:
18
+
19
+ 1. **Why each message type was chosen** - the reasoning behind Untargeted vs Targeted vs Broadcast
20
+ 2. **How the code flows** - step-by-step from Boot.cs through every script
21
+ 3. **Common patterns** - Observer, Broadcaster, Orchestrator, and more
22
+ 4. **Debugging strategies** - how to find and fix issues
23
+ 5. **How to extend it** - add your own messages and handlers
24
+
25
+ **Estimated time:** 20-30 minutes for thorough understanding
4
26
 
5
27
  ---
6
28
 
@@ -85,30 +107,24 @@ Let's understand what each script does:
85
107
 
86
108
  Here's the full sequence that happens when you press Play:
87
109
 
88
- ```text
89
- ┌─────────────────────────────────────────────────────────────────┐
90
- STEP 1: Boot starts and sends VideoSettingsChanged │
91
- │ (Untargeted - anyone can listen) │
92
- └────────────┬────────────────────────────────────────────────────┘
93
-
94
- ├──────────────► UIOverlay receives it
95
- │ └─► Rebuilds its UI
96
-
97
- ┌────────────▼────────────────────────────────────────────────────┐
98
- │ STEP 2: Boot sends Heal message to Player │
99
- │ (Targeted - only the Player Component receives it) │
100
- └────────────┬────────────────────────────────────────────────────┘
101
-
102
- ├──────────────► Player receives it
103
- │ └─► Increases HP by heal amount
104
-
105
- ┌────────────▼────────────────────────────────────────────────────┐
106
- │ STEP 3: Enemy broadcasts TookDamage │
107
- │ (Broadcast - all listeners receive it) │
108
- └────────────┬────────────────────────────────────────────────────┘
109
-
110
- ├──────────────► UIOverlay receives it
111
- └─► Shows damage notification
110
+ ```mermaid
111
+ sequenceDiagram
112
+ participant Boot
113
+ participant UIOverlay
114
+ participant Player
115
+ participant Enemy
116
+
117
+ Note over Boot: STEP 1: Boot starts
118
+ Boot->>UIOverlay: VideoSettingsChanged (Untargeted)
119
+ Note over UIOverlay: Rebuilds UI
120
+
121
+ Note over Boot: STEP 2: Boot sends Heal
122
+ Boot->>Player: Heal (Targeted)
123
+ Note over Player: Increases HP by heal amount
124
+
125
+ Note over Enemy: STEP 3: Enemy broadcasts
126
+ Enemy->>UIOverlay: TookDamage (Broadcast)
127
+ Note over UIOverlay: Shows damage notification
112
128
  ```
113
129
 
114
130
  ---
@@ -1,4 +1,5 @@
1
1
  using DxMessaging.Core;
2
+ using DxMessaging.Core.MessageBus;
2
3
  using UnityEngine;
3
4
 
4
5
  public sealed class DiagnosticsEnabler : MonoBehaviour
@@ -10,8 +11,17 @@ public sealed class DiagnosticsEnabler : MonoBehaviour
10
11
  {
11
12
  if (enableOnStart)
12
13
  {
13
- MessageHandler.MessageBus.DiagnosticsMode = true;
14
- Debug.Log("DxMessaging global diagnostics enabled.");
14
+ if (MessageHandler.MessageBus is MessageBus concreteBus)
15
+ {
16
+ concreteBus.DiagnosticsMode = true;
17
+ Debug.Log("DxMessaging global diagnostics enabled.");
18
+ }
19
+ else
20
+ {
21
+ Debug.LogWarning(
22
+ "Global diagnostics are unavailable because the active global bus is not the default DxMessaging implementation."
23
+ );
24
+ }
15
25
  }
16
26
  }
17
27
  }