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.
- package/.github/workflows/format-on-demand.yml +2 -2
- package/.github/workflows/json-format-check.yml +1 -1
- package/.github/workflows/markdown-json.yml +1 -1
- package/.github/workflows/markdownlint.yml +1 -1
- package/.github/workflows/npm-publish.yml +1 -1
- package/.github/workflows/prettier-autofix.yml +2 -2
- package/.github/workflows/yaml-format-lint.yml +1 -1
- package/Docs/Advanced.md +26 -1
- package/Docs/Comparisons.md +1229 -146
- package/Docs/Compatibility.md +27 -0
- package/Docs/DesignAndArchitecture.md +41 -34
- package/Docs/EmitShorthands.md +34 -0
- package/Docs/Helpers.md +1 -1
- package/Docs/Index.md +28 -25
- package/Docs/Install.md +29 -6
- package/Docs/Integrations/Reflex.md +292 -0
- package/Docs/Integrations/Reflex.md.meta +7 -0
- package/Docs/Integrations/VContainer.md +324 -0
- package/Docs/Integrations/VContainer.md.meta +7 -0
- package/Docs/Integrations/Zenject.md +333 -0
- package/Docs/Integrations/Zenject.md.meta +7 -0
- package/{Editor/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.pdb.meta → Docs/Integrations.meta} +2 -1
- package/Docs/InterceptorsAndOrdering.md +371 -17
- package/Docs/ListeningPatterns.md +206 -0
- package/Docs/MessageBusProviders.md +496 -0
- package/Docs/MessageBusProviders.md.meta +7 -0
- package/Docs/MessageTypes.md +27 -0
- package/Docs/MigrationGuide.md +45 -0
- package/Docs/Patterns.md +286 -0
- package/Docs/Performance.md +9 -9
- package/Docs/QuickReference.md +31 -0
- package/Docs/RuntimeConfiguration.md +407 -0
- package/Docs/RuntimeConfiguration.md.meta +7 -0
- package/Docs/UnityIntegration.md +3 -1
- package/Docs/VisualGuide.md +206 -157
- package/Editor/CustomEditors/MessagingComponentEditor.cs +15 -6
- package/README.md +148 -26
- package/Runtime/AssemblyInfo.cs +4 -0
- package/Runtime/Core/Extensions/MessageBusExtensions.cs +253 -0
- package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +12 -0
- package/Runtime/Core/Extensions/MessageExtensions.cs +137 -89
- package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs +23 -0
- package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs.meta +11 -0
- package/Runtime/Core/MessageBus/IMessageBusProvider.cs +14 -0
- package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +11 -0
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs +18 -0
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs.meta +11 -0
- package/Runtime/Core/MessageBus/MessageBusRebindMode.cs +26 -0
- package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +11 -0
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs +383 -0
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs.meta +11 -0
- package/Runtime/Core/MessageHandler.cs +198 -27
- package/Runtime/Core/MessageRegistrationToken.cs +67 -25
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs +31 -0
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs.meta +12 -0
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs +38 -0
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs.meta +12 -0
- package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs +11 -0
- package/Runtime/Unity/Integrations/Reflex/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs +73 -0
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs.meta +11 -0
- package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef +20 -0
- package/Runtime/Unity/Integrations/Reflex/WallstopStudios.DxMessaging.Reflex.asmdef.meta +7 -0
- package/Runtime/Unity/Integrations/Reflex.meta +8 -0
- package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs +11 -0
- package/Runtime/Unity/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs +46 -0
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs.meta +11 -0
- package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef +30 -0
- package/Runtime/Unity/Integrations/VContainer/WallstopStudios.DxMessaging.VContainer.asmdef.meta +7 -0
- package/Runtime/Unity/Integrations/VContainer.meta +8 -0
- package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs +11 -0
- package/Runtime/Unity/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef +30 -0
- package/Runtime/Unity/Integrations/Zenject/WallstopStudios.DxMessaging.Zenject.asmdef.meta +7 -0
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs +55 -0
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs.meta +11 -0
- package/Runtime/Unity/Integrations/Zenject.meta +8 -0
- package/Runtime/Unity/Integrations.meta +8 -0
- package/Runtime/Unity/MessageAwareComponent.cs +102 -0
- package/Runtime/Unity/MessageBusProviderHandle.cs +97 -0
- package/Runtime/Unity/MessageBusProviderHandle.cs.meta +12 -0
- package/Runtime/Unity/MessagingComponent.cs +164 -2
- package/Runtime/Unity/MessagingComponentInstaller.cs +120 -0
- package/Runtime/Unity/MessagingComponentInstaller.cs.meta +12 -0
- package/Runtime/Unity/ScriptableMessageBusProvider.cs +14 -0
- package/Runtime/Unity/ScriptableMessageBusProvider.cs.meta +12 -0
- package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab +98 -0
- package/Samples~/DI/Prefabs/MessagingInstallerSample.prefab.meta +7 -0
- package/Samples~/DI/Prefabs.meta +8 -0
- package/Samples~/DI/Providers/GlobalMessageBusProvider.asset +14 -0
- package/Samples~/DI/Providers/GlobalMessageBusProvider.asset.meta +8 -0
- package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset +14 -0
- package/Samples~/DI/Providers/InitialGlobalMessageBusProvider.asset.meta +8 -0
- package/Samples~/DI/Providers.meta +8 -0
- package/Samples~/DI/README.md +51 -0
- package/Samples~/DI/README.md.meta +7 -0
- package/Samples~/DI/Reflex/SampleInstaller.cs +75 -0
- package/Samples~/DI/Reflex/SampleInstaller.cs.meta +11 -0
- package/Samples~/DI/Reflex.meta +8 -0
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs +81 -0
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +11 -0
- package/Samples~/DI/VContainer.meta +8 -0
- package/Samples~/DI/Zenject/SampleInstaller.cs +67 -0
- package/Samples~/DI/Zenject/SampleInstaller.cs.meta +11 -0
- package/Samples~/DI/Zenject.meta +8 -0
- package/Samples~/DI.meta +8 -0
- package/Samples~/Mini Combat/README.md +5 -7
- package/Samples~/Mini Combat/Walkthrough.md +18 -24
- package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs +12 -2
- package/Samples~/UI Buttons + Inspector/README.md.meta +7 -0
- package/Tests/Runtime/Benchmarks/BenchmarkSession.cs +444 -0
- package/Tests/Runtime/Benchmarks/BenchmarkSession.cs.meta +11 -0
- package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs +94 -0
- package/Tests/Runtime/Benchmarks/BenchmarkTestBase.cs.meta +11 -0
- package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs +395 -0
- package/Tests/Runtime/Benchmarks/ComparisonPerformanceTests.cs.meta +11 -0
- package/Tests/Runtime/Benchmarks/PerformanceTests.cs +77 -429
- package/Tests/Runtime/Benchmarks/ProviderResolutionBenchmarks.cs +142 -0
- package/Tests/Runtime/Benchmarks/ProviderResolutionBenchmarks.cs.meta +12 -0
- package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef +50 -0
- package/Tests/Runtime/Benchmarks/WallstopStudios.DxMessaging.Tests.Runtime.Benchmarks.asmdef.meta +7 -0
- package/Tests/Runtime/Core/DefaultBusFallbackTests.cs +333 -0
- package/Tests/Runtime/Core/DefaultBusFallbackTests.cs.meta +11 -0
- package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs +278 -0
- package/Tests/Runtime/Core/Extensions/MessageBusExtensionsTests.cs.meta +11 -0
- package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs +289 -0
- package/Tests/Runtime/Core/Extensions/MessageExtensionsProviderTests.cs.meta +11 -0
- package/Tests/Runtime/Core/Extensions.meta +8 -0
- package/Tests/Runtime/Core/IntegrationShimSmokeTests.cs +57 -0
- package/Tests/Runtime/Core/IntegrationShimSmokeTests.cs.meta +11 -0
- package/Tests/Runtime/Core/MessageHandlerGlobalBusTests.cs +219 -0
- package/Tests/Runtime/Core/MessageHandlerGlobalBusTests.cs.meta +11 -0
- package/Tests/Runtime/Core/MessageRegistrationBuilderTests.cs +204 -0
- package/Tests/Runtime/Core/MessageRegistrationBuilderTests.cs.meta +11 -0
- package/Tests/Runtime/Core/MessagingTestBase.cs +4 -4
- package/Tests/Runtime/Core/NominalTests.cs +2 -2
- package/Tests/Runtime/Core/TypedShorthandTests.cs +2 -2
- package/Tests/Runtime/Core/UntargetedEquivalenceTests.cs +1 -1
- package/Tests/Runtime/Core/UntargetedPrefreezeTests.cs +2 -4
- package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs +162 -0
- package/Tests/Runtime/Integrations/Reflex/ReflexIntegrationTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Reflex/Resources/ReflexSettings.asset +16 -0
- package/Tests/Runtime/Integrations/Reflex/Resources/ReflexSettings.asset.meta +8 -0
- package/Tests/Runtime/Integrations/Reflex/Resources.meta +8 -0
- package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef +27 -0
- package/Tests/Runtime/Integrations/Reflex/WallstopStudios.DxMessaging.Tests.Runtime.Reflex.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/Reflex.meta +8 -0
- package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs +140 -0
- package/Tests/Runtime/Integrations/VContainer/VContainerIntegrationTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef +37 -0
- package/Tests/Runtime/Integrations/VContainer/WallstopStudios.DxMessaging.Tests.Runtime.VContainer.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/VContainer.meta +8 -0
- package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef +37 -0
- package/Tests/Runtime/Integrations/Zenject/WallstopStudios.DxMessaging.Tests.Runtime.Zenject.asmdef.meta +7 -0
- package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs +140 -0
- package/Tests/Runtime/Integrations/Zenject/ZenjectIntegrationTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Zenject.meta +8 -0
- package/Tests/Runtime/Integrations.meta +8 -0
- package/Tests/Runtime/Scripts/Components/EmptyMessageAwareComponent.cs +1 -1
- package/Tests/Runtime/Scripts/Components/GenericMessageAwareComponent.cs +1 -1
- package/Tests/Runtime/Scripts/Components/SimpleMessageAwareComponent.cs +1 -1
- package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs +64 -0
- package/Tests/Runtime/TestUtilities/UnityFixtureBase.cs.meta +12 -0
- package/Tests/Runtime/TestUtilities.meta +9 -0
- package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs +57 -0
- package/Tests/Runtime/Unity/MessageBusProviderAssetTests.cs.meta +11 -0
- package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs +107 -0
- package/Tests/Runtime/Unity/MessageBusProviderHandleTests.cs.meta +12 -0
- package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs +210 -0
- package/Tests/Runtime/Unity/MessagingComponentProviderIntegrationTests.cs.meta +12 -0
- package/Tests/Runtime/Unity.meta +9 -0
- package/Tests/Runtime/WallstopStudios.DxMessaging.Tests.Runtime.asmdef +3 -1
- package/package.json +1 -1
package/Docs/Compatibility.md
CHANGED
|
@@ -15,3 +15,30 @@ Notes
|
|
|
15
15
|
|
|
16
16
|
- RP‑agnostic: DxMessaging does not depend on rendering APIs; it works equally across Built‑In, URP, and HDRP.
|
|
17
17
|
- Minimum version is governed by the package manifest (`unity`: 2021.3). Newer LTS versions are expected to work.
|
|
18
|
+
|
|
19
|
+
## Architecture Pattern Compatibility
|
|
20
|
+
|
|
21
|
+
### Scriptable Object Architecture (SOA)
|
|
22
|
+
|
|
23
|
+
DxMessaging can work alongside Scriptable Object Architecture patterns, though SOA has documented limitations. See [Pattern 14: SOA Compatibility](Patterns.md#14-compatibility-with-scriptable-object-architecture-soa) for detailed integration strategies, code examples, and migration paths.
|
|
24
|
+
|
|
25
|
+
#### Quick summary
|
|
26
|
+
|
|
27
|
+
- ✅ **Compatible** - DxMessaging can bridge with SOA systems
|
|
28
|
+
- ⚠️ **Not recommended** - SOA has scalability and maintainability concerns ([detailed critique](https://github.com/cathei/AntiScriptableObjectArchitecture))
|
|
29
|
+
- ✅ **Best practice** - Use ScriptableObjects for immutable design data, DxMessaging for runtime events
|
|
30
|
+
- → See [SOA Integration Patterns](Patterns.md#14-compatibility-with-scriptable-object-architecture-soa) for three coexistence strategies with code examples
|
|
31
|
+
|
|
32
|
+
### Dependency Injection (DI) Frameworks
|
|
33
|
+
|
|
34
|
+
DxMessaging integrates seamlessly with popular DI frameworks:
|
|
35
|
+
|
|
36
|
+
- **Zenject** - See [Zenject Integration Guide](Integrations/Zenject.md)
|
|
37
|
+
- **VContainer** - See [VContainer Integration Guide](Integrations/VContainer.md)
|
|
38
|
+
- **Reflex** - See [Reflex Integration Guide](Integrations/Reflex.md)
|
|
39
|
+
|
|
40
|
+
DI and DxMessaging complement each other: DI manages dependencies/services, DxMessaging handles event communication.
|
|
41
|
+
|
|
42
|
+
### Other Unity Frameworks
|
|
43
|
+
|
|
44
|
+
For comparisons with other messaging/event frameworks (UniRx, MessagePipe, Zenject Signals, etc.), see [Framework Comparisons](Comparisons.md).
|
|
@@ -49,42 +49,49 @@ DxMessaging was built with these principles:
|
|
|
49
49
|
|
|
50
50
|
## Architecture Overview
|
|
51
51
|
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
52
|
+
```mermaid
|
|
53
|
+
%%{init: {'theme':'base', 'themeVariables': { 'primaryColor':'#fff','primaryTextColor':'#000','primaryBorderColor':'#000','lineColor':'#2563eb','secondaryColor':'#fff','tertiaryColor':'#fff','edgeLabelBackground':'#fff'}}}%%
|
|
54
|
+
flowchart TB
|
|
55
|
+
subgraph App["<b>Application Layer</b>"]
|
|
56
|
+
CompA[Component A<br/>Token.Reg]
|
|
57
|
+
CompB[Component B<br/>Token.Reg]
|
|
58
|
+
CompC[Component C<br/>Token.Reg]
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
subgraph Token["<b>Registration Layer</b>"]
|
|
62
|
+
MRT[MessageRegistrationToken<br/>• Stages registrations<br/>• Enable/Disable<br/>• Lifecycle management]
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
subgraph Handler["<b>Handler Layer</b>"]
|
|
66
|
+
MH[MessageHandler<br/>• Per-component handler<br/>• Active/Inactive state]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
subgraph Bus["<b>Message Bus Layer</b>"]
|
|
70
|
+
MB[MessageBus<br/>• Interceptors<br/>• Handlers<br/>• Post-Processors]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
CompA ==> MRT
|
|
74
|
+
CompB ==> MRT
|
|
75
|
+
CompC ==> MRT
|
|
76
|
+
MRT ==> MH
|
|
77
|
+
MH ==> MB
|
|
78
|
+
|
|
79
|
+
style App fill:#bae7ff,stroke:#0050b3,stroke-width:3px,color:#000
|
|
80
|
+
style Token fill:#ffe7ba,stroke:#d48806,stroke-width:3px,color:#000
|
|
81
|
+
style Handler fill:#d3adf7,stroke:#531dab,stroke-width:3px,color:#000
|
|
82
|
+
style Bus fill:#b7eb8f,stroke:#389e0d,stroke-width:3px,color:#000
|
|
83
|
+
style MRT fill:#ffe7ba,stroke:#d48806,stroke-width:2px,color:#000
|
|
84
|
+
style MH fill:#d3adf7,stroke:#531dab,stroke-width:2px,color:#000
|
|
85
|
+
style MB fill:#b7eb8f,stroke:#389e0d,stroke-width:2px,color:#000
|
|
86
86
|
```
|
|
87
87
|
|
|
88
|
+
### Layer Responsibilities
|
|
89
|
+
|
|
90
|
+
1. **Application Layer** - Your Unity components register message handlers
|
|
91
|
+
1. **Registration Layer** - Token manages handler lifecycle (enable/disable/cleanup)
|
|
92
|
+
1. **Handler Layer** - Per-component state management (active/inactive)
|
|
93
|
+
1. **Message Bus Layer** - Routes messages through interceptors → handlers → post-processors
|
|
94
|
+
|
|
88
95
|
## Performance Optimizations
|
|
89
96
|
|
|
90
97
|
- Struct messages passed by `ref` to avoid copying and GC.
|
package/Docs/EmitShorthands.md
CHANGED
|
@@ -45,6 +45,40 @@ var damage = new TookDamage(5);
|
|
|
45
45
|
damage.EmitFrom(enemy); // Broadcast: listeners interested in enemy damage receive this
|
|
46
46
|
```
|
|
47
47
|
|
|
48
|
+
### Bus-First Helpers
|
|
49
|
+
|
|
50
|
+
Prefer injecting `IMessageBus` (or `IMessageRegistrationBuilder`) in DI scenarios and use the bus-first extensions for parity with the shorthands:
|
|
51
|
+
|
|
52
|
+
```csharp
|
|
53
|
+
using DxMessaging.Core.Extensions;
|
|
54
|
+
using DxMessaging.Core.Attributes;
|
|
55
|
+
|
|
56
|
+
public sealed class ScoreReporter
|
|
57
|
+
{
|
|
58
|
+
private readonly IMessageBus messageBus;
|
|
59
|
+
|
|
60
|
+
public ScoreReporter(IMessageBus messageBus)
|
|
61
|
+
{
|
|
62
|
+
this.messageBus = messageBus;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public void Report(int value)
|
|
66
|
+
{
|
|
67
|
+
ScoreChanged message = new ScoreChanged(value);
|
|
68
|
+
messageBus.EmitUntargeted(ref message);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
[DxUntargetedMessage]
|
|
73
|
+
public readonly struct ScoreChanged
|
|
74
|
+
{
|
|
75
|
+
public readonly int Value;
|
|
76
|
+
public ScoreChanged(int value) => Value = value;
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
These helpers mirror the struct/class/targeted/broadcast overloads available on message instances. They keep DI-friendly services aligned with the same dispatch path as Unity shorthands.
|
|
81
|
+
|
|
48
82
|
## Understanding Each Shorthand
|
|
49
83
|
|
|
50
84
|
### `Emit()` — Global Broadcast (Untargeted)
|
package/Docs/Helpers.md
CHANGED
|
@@ -355,7 +355,7 @@ using DxMessaging.Core.MessageBus;
|
|
|
355
355
|
|
|
356
356
|
// Create isolated bus
|
|
357
357
|
var testBus = new MessageBus();
|
|
358
|
-
var handler = new MessageHandler(new InstanceId(1)) { active = true };
|
|
358
|
+
var handler = new MessageHandler(new InstanceId(1), testBus) { active = true };
|
|
359
359
|
var token = MessageRegistrationToken.Create(handler, testBus);
|
|
360
360
|
|
|
361
361
|
// Register on isolated bus
|
package/Docs/Index.md
CHANGED
|
@@ -4,28 +4,18 @@
|
|
|
4
4
|
|
|
5
5
|
## Visual Documentation Map
|
|
6
6
|
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
│ (5 min) │ │ (10 min) │ │ (5 min) │
|
|
20
|
-
└─────┬──────┘ └─────┬──────┘ └─────┬──────┘
|
|
21
|
-
│ │ │
|
|
22
|
-
└──────────────────┼──────────────────┘
|
|
23
|
-
│
|
|
24
|
-
┌──────▼──────┐
|
|
25
|
-
│ Patterns │
|
|
26
|
-
│ & Samples │
|
|
27
|
-
│ (Hands-on!) │
|
|
28
|
-
└─────────────┘
|
|
7
|
+
```mermaid
|
|
8
|
+
graph TD
|
|
9
|
+
Start[START HERE<br/>Visual Guide<br/>5 minutes]
|
|
10
|
+
Start --> Quick[Quick Start<br/>5 min]
|
|
11
|
+
Start --> Getting[Getting Started<br/>10 min]
|
|
12
|
+
Start --> Overview[Overview<br/>5 min]
|
|
13
|
+
Quick --> Patterns[Patterns & Samples<br/>Hands-on!]
|
|
14
|
+
Getting --> Patterns
|
|
15
|
+
Overview --> Patterns
|
|
16
|
+
|
|
17
|
+
style Start fill:#91d5ff,stroke:#096dd9,stroke-width:3px,color:#000
|
|
18
|
+
style Patterns fill:#95de64,stroke:#237804,stroke-width:2px,color:#000
|
|
29
19
|
```
|
|
30
20
|
|
|
31
21
|
## Table of Contents
|
|
@@ -108,6 +98,8 @@
|
|
|
108
98
|
### Tools & Utilities
|
|
109
99
|
|
|
110
100
|
- **[Helpers](Helpers.md)** — Source generators, attributes, extensions
|
|
101
|
+
- **[Message Bus Providers](MessageBusProviders.md)** — Provider system and MessageBusProviderHandle for flexible bus configuration
|
|
102
|
+
- **[Runtime Configuration](RuntimeConfiguration.md)** — Setting message buses at runtime, re-binding registrations
|
|
111
103
|
- **[Emit Shorthands](EmitShorthands.md)** — `Emit`/`EmitAt`/`EmitFrom` usage and pitfalls
|
|
112
104
|
- **[String Messages](StringMessages.md)** — Prototyping and debugging
|
|
113
105
|
- **[Compatibility](Compatibility.md)** — Unity versions and render pipelines
|
|
@@ -159,6 +151,9 @@ From [Common Patterns](Patterns.md):
|
|
|
159
151
|
- **Debug message flow** → Use [Diagnostics](Diagnostics.md)
|
|
160
152
|
- **Optimize performance** → Read [Performance Tips](DesignAndArchitecture.md#performance-tuning-tips)
|
|
161
153
|
- **Isolate tests** → Create [Local Bus Islands](DesignAndArchitecture.md#local-bus-islands)
|
|
154
|
+
- **Use dependency injection** → [DxMessaging + Zenject](Integrations/Zenject.md), [DxMessaging + VContainer](Integrations/VContainer.md), [DxMessaging + Reflex](Integrations/Reflex.md)
|
|
155
|
+
- **Configure buses at runtime** → See [Runtime Configuration](RuntimeConfiguration.md)
|
|
156
|
+
- **Use message bus providers** → Learn [Message Bus Providers](MessageBusProviders.md)
|
|
162
157
|
|
|
163
158
|
## 📊 Visual: Message Pipeline
|
|
164
159
|
|
|
@@ -169,9 +164,9 @@ flowchart LR
|
|
|
169
164
|
P[Producer] --> I[Interceptors<br/>validate/mutate/cancel]
|
|
170
165
|
I --> H[Handlers<br/>main logic by priority]
|
|
171
166
|
H --> PP[Post-Processors<br/>analytics/logging]
|
|
172
|
-
style I fill:#
|
|
173
|
-
style H fill:#
|
|
174
|
-
style PP fill:#
|
|
167
|
+
style I fill:#ffe7ba,stroke:#d48806,stroke-width:2px,color:#000
|
|
168
|
+
style H fill:#91d5ff,stroke:#096dd9,stroke-width:2px,color:#000
|
|
169
|
+
style PP fill:#b7eb8f,stroke:#389e0d,stroke-width:2px,color:#000
|
|
175
170
|
```
|
|
176
171
|
|
|
177
172
|
## 🎓 Learning Resources
|
|
@@ -269,6 +264,14 @@ From [Comparisons](Comparisons.md):
|
|
|
269
264
|
- [FAQ](FAQ.md)
|
|
270
265
|
- [Troubleshooting](Troubleshooting.md)
|
|
271
266
|
|
|
267
|
+
### Dependency Injection
|
|
268
|
+
|
|
269
|
+
- [Runtime Configuration](RuntimeConfiguration.md) — Setting and overriding message buses, re-binding registrations
|
|
270
|
+
- [Message Bus Providers](MessageBusProviders.md) — Provider system and MessageBusProviderHandle
|
|
271
|
+
- [DxMessaging + Zenject](Integrations/Zenject.md) — Zenject integration guide
|
|
272
|
+
- [DxMessaging + VContainer](Integrations/VContainer.md) — VContainer integration guide
|
|
273
|
+
- [DxMessaging + Reflex](Integrations/Reflex.md) — Reflex integration guide
|
|
274
|
+
|
|
272
275
|
### Miscellaneous
|
|
273
276
|
|
|
274
277
|
- [String Messages](StringMessages.md)
|
package/Docs/Install.md
CHANGED
|
@@ -2,34 +2,57 @@
|
|
|
2
2
|
|
|
3
3
|
This page helps you install DxMessaging into a Unity 2021.3+ project using the Unity Package Manager (UPM).
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Methods
|
|
6
|
+
|
|
7
|
+
### Fast path
|
|
6
8
|
|
|
7
9
|
- Unity Package Manager > Add package from git URL...
|
|
8
10
|
- Paste:
|
|
9
11
|
|
|
10
12
|
```text
|
|
11
|
-
https://github.com/wallstop/DxMessaging.git
|
|
13
|
+
https://github.com/wallstop/DxMessaging.git
|
|
12
14
|
```
|
|
13
15
|
|
|
14
16
|
- Click Add. Unity imports the package and its analyzers/generators.
|
|
15
17
|
|
|
16
|
-
|
|
18
|
+
### To Install as Unity Package
|
|
19
|
+
|
|
20
|
+
1. Open Unity Package Manager
|
|
21
|
+
1. (Optional) Enable Pre-release packages to get the latest, cutting-edge builds
|
|
22
|
+
1. Open the Advanced Package Settings
|
|
23
|
+
1. Add an entry for a new "Scoped Registry"
|
|
24
|
+
- Name: `NPM`
|
|
25
|
+
- URL: `https://registry.npmjs.org`
|
|
26
|
+
- Scope(s): `com.wallstop-studios.dxmessaging`
|
|
27
|
+
1. Resolve the latest `DxMessaging`
|
|
28
|
+
|
|
29
|
+
⭐ Bonus of Unity Package way - Unity will tell you of version updates
|
|
30
|
+
|
|
31
|
+
### From Releases
|
|
32
|
+
|
|
33
|
+
Check out the latest [Releases](https://github.com/wallstop/DxMessaging/releases) to grab the Unity Package and import to your project.
|
|
34
|
+
|
|
35
|
+
### From Source
|
|
36
|
+
|
|
37
|
+
Grab a copy of this repo (either `git clone` [this repo](https://github.com/wallstop/DxMessaging) or [download a zip of the source](https://github.com/wallstop/DxMessaging/archive/refs/heads/master.zip)) and copy the contents to your project's `Assets` directory.
|
|
38
|
+
|
|
39
|
+
### Manual - Manifest.json (alternative, not recommended)
|
|
17
40
|
|
|
18
41
|
- Open your project’s `Packages/manifest.json` and add:
|
|
19
42
|
|
|
20
43
|
```json
|
|
21
44
|
{
|
|
22
45
|
"dependencies": {
|
|
23
|
-
"com.wallstop-studios.dxmessaging": "https://github.com/wallstop/DxMessaging.git
|
|
46
|
+
"com.wallstop-studios.dxmessaging": "https://github.com/wallstop/DxMessaging.git"
|
|
24
47
|
}
|
|
25
48
|
}
|
|
26
49
|
```
|
|
27
50
|
|
|
28
|
-
Minimum requirements
|
|
51
|
+
## Minimum requirements
|
|
29
52
|
|
|
30
53
|
- Unity 2021.3+ (LTS recommended). See [Compatibility](Compatibility.md) for Unity × Render Pipeline support (Built‑In, URP, HDRP).
|
|
31
54
|
|
|
32
|
-
After install
|
|
55
|
+
## After install
|
|
33
56
|
|
|
34
57
|
- In your project, create a GameObject and add `MessagingComponent` to start sending/receiving.
|
|
35
58
|
- Optional: enable diagnostics in Editor from the MessagingComponent inspector to see live emissions.
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
# DxMessaging + Reflex
|
|
2
|
+
|
|
3
|
+
[← Back to Integrations Overview](../README.md#-integrations)
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
**Reflex** is a minimal, lightweight dependency injection framework for Unity with blazing-fast performance. DxMessaging integrates seamlessly with Reflex, allowing you to:
|
|
10
|
+
|
|
11
|
+
- **Inject `IMessageBus`** in any class with minimal overhead
|
|
12
|
+
- **Use DI for construction** + DxMessaging for events (best of both worlds)
|
|
13
|
+
- **Minimal API surface** — easy to learn, easy to use
|
|
14
|
+
- **High performance** — Reflex + DxMessaging = minimal allocations
|
|
15
|
+
|
|
16
|
+
**Why combine DI + Messaging?** Use constructor injection for service dependencies (repositories, managers) and messaging for reactive events (damage taken, item collected). Reflex's minimal API makes integration simple and straightforward.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
### Prerequisites
|
|
23
|
+
|
|
24
|
+
- DxMessaging installed via UPM
|
|
25
|
+
- Reflex installed (`gustavopsantos/Reflex`) via source or UPM
|
|
26
|
+
|
|
27
|
+
### 1. Create a Reflex Installer
|
|
28
|
+
|
|
29
|
+
```csharp
|
|
30
|
+
using DxMessaging.Core.MessageBus;
|
|
31
|
+
using Reflex.Core;
|
|
32
|
+
|
|
33
|
+
public sealed class DxMessagingInstaller : Installer
|
|
34
|
+
{
|
|
35
|
+
public override void InstallBindings(ContainerDescriptor descriptor)
|
|
36
|
+
{
|
|
37
|
+
// Bind MessageBus as both concrete and interface
|
|
38
|
+
descriptor.AddSingleton(typeof(MessageBus), typeof(MessageBus));
|
|
39
|
+
descriptor.AddSingleton(typeof(IMessageBus), c => c.Resolve<MessageBus>());
|
|
40
|
+
|
|
41
|
+
// Optional: Enable automatic IMessageRegistrationBuilder binding
|
|
42
|
+
// Requires REFLEX_PRESENT define (auto-added by DxMessaging when Reflex detected)
|
|
43
|
+
#if REFLEX_PRESENT
|
|
44
|
+
descriptor.AddMessageRegistrationBuilder();
|
|
45
|
+
#endif
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### Add to your scene
|
|
51
|
+
|
|
52
|
+
1. Create a `SceneContext` or `ProjectContext` in your scene
|
|
53
|
+
1. Add `DxMessagingInstaller` to the installers list
|
|
54
|
+
1. Reflex will now inject `IMessageBus` automatically
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## Usage Patterns
|
|
59
|
+
|
|
60
|
+
### Pattern 1: Inject into Plain Classes (Recommended for Services)
|
|
61
|
+
|
|
62
|
+
Use `IMessageRegistrationBuilder` to create message handlers in non-MonoBehaviour classes:
|
|
63
|
+
|
|
64
|
+
```csharp
|
|
65
|
+
using DxMessaging.Core.MessageBus;
|
|
66
|
+
using DxMessaging.Core.Attributes;
|
|
67
|
+
|
|
68
|
+
// Define a message
|
|
69
|
+
[DxUntargetedMessage]
|
|
70
|
+
[DxAutoConstructor]
|
|
71
|
+
public readonly partial struct PlayerDamaged
|
|
72
|
+
{
|
|
73
|
+
public readonly int damage;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Service that listens to messages
|
|
77
|
+
public sealed class DamageService
|
|
78
|
+
{
|
|
79
|
+
private readonly MessageRegistrationLease _lease;
|
|
80
|
+
|
|
81
|
+
// Builder is injected automatically when using the installer
|
|
82
|
+
public DamageService(IMessageRegistrationBuilder registrationBuilder)
|
|
83
|
+
{
|
|
84
|
+
var options = new MessageRegistrationBuildOptions
|
|
85
|
+
{
|
|
86
|
+
Configure = token =>
|
|
87
|
+
{
|
|
88
|
+
_ = token.RegisterUntargeted<PlayerDamaged>(OnPlayerDamaged);
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
_lease = registrationBuilder.Build(options);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public void Initialize()
|
|
96
|
+
{
|
|
97
|
+
_lease.Activate(); // Start listening
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
public void Dispose()
|
|
101
|
+
{
|
|
102
|
+
_lease.Dispose(); // Clean up
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private static void OnPlayerDamaged(ref PlayerDamaged message)
|
|
106
|
+
{
|
|
107
|
+
UnityEngine.Debug.Log($"Player took {message.damage} damage!");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### Register the service in your installer
|
|
113
|
+
|
|
114
|
+
```csharp
|
|
115
|
+
public override void InstallBindings(ContainerDescriptor descriptor)
|
|
116
|
+
{
|
|
117
|
+
descriptor.AddSingleton<DamageService>();
|
|
118
|
+
// Call Initialize() from a bootstrap MonoBehaviour
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**Note:** Reflex doesn't have lifecycle interfaces like `IInitializable`. Call `Initialize()` and `Dispose()` manually from a controlling MonoBehaviour or bootstrap script.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### Pattern 2: Configure MessagingComponents (For Existing MonoBehaviours)
|
|
127
|
+
|
|
128
|
+
```csharp
|
|
129
|
+
using DxMessaging.Core.MessageBus;
|
|
130
|
+
using DxMessaging.Unity;
|
|
131
|
+
using Reflex.Attributes;
|
|
132
|
+
using UnityEngine;
|
|
133
|
+
|
|
134
|
+
[DisallowMultipleComponent]
|
|
135
|
+
[RequireComponent(typeof(MessagingComponent))]
|
|
136
|
+
public sealed class MessagingComponentConfigurator : MonoBehaviour
|
|
137
|
+
{
|
|
138
|
+
[Inject]
|
|
139
|
+
private IMessageBus _messageBus;
|
|
140
|
+
|
|
141
|
+
private void Awake()
|
|
142
|
+
{
|
|
143
|
+
GetComponent<MessagingComponent>().Configure(
|
|
144
|
+
_messageBus,
|
|
145
|
+
MessageBusRebindMode.RebindActive
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Usage
|
|
152
|
+
|
|
153
|
+
1. Add `MessagingComponentConfigurator` alongside any `MessagingComponent` in your prefabs
|
|
154
|
+
1. Reflex will inject the bus in `Awake()` before handlers are registered
|
|
155
|
+
1. Your message handlers now use the container-managed bus
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
### Pattern 3: Inject IMessageBus Directly
|
|
160
|
+
|
|
161
|
+
For simple emission without listening, inject `IMessageBus` directly:
|
|
162
|
+
|
|
163
|
+
```csharp
|
|
164
|
+
public sealed class GameBootstrap : MonoBehaviour
|
|
165
|
+
{
|
|
166
|
+
[Inject]
|
|
167
|
+
private IMessageBus _messageBus;
|
|
168
|
+
|
|
169
|
+
private void Start()
|
|
170
|
+
{
|
|
171
|
+
var message = new GameStarted();
|
|
172
|
+
_messageBus.EmitUntargeted(ref message);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
---
|
|
178
|
+
|
|
179
|
+
## Advanced: Object Pooling
|
|
180
|
+
|
|
181
|
+
When using object pooling with Reflex:
|
|
182
|
+
|
|
183
|
+
```csharp
|
|
184
|
+
public sealed class EnemyPool
|
|
185
|
+
{
|
|
186
|
+
private readonly Container _container;
|
|
187
|
+
private readonly Queue<Enemy> _pool = new();
|
|
188
|
+
|
|
189
|
+
public EnemyPool(Container container)
|
|
190
|
+
{
|
|
191
|
+
_container = container;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
public Enemy Spawn()
|
|
195
|
+
{
|
|
196
|
+
Enemy enemy;
|
|
197
|
+
if (_pool.Count > 0)
|
|
198
|
+
{
|
|
199
|
+
enemy = _pool.Dequeue();
|
|
200
|
+
}
|
|
201
|
+
else
|
|
202
|
+
{
|
|
203
|
+
enemy = Object.Instantiate(enemyPrefab);
|
|
204
|
+
_container.Inject(enemy); // Inject dependencies
|
|
205
|
+
}
|
|
206
|
+
return enemy;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
public void Return(Enemy enemy)
|
|
210
|
+
{
|
|
211
|
+
_pool.Enqueue(enemy);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Testing with Reflex
|
|
219
|
+
|
|
220
|
+
### Unit Tests
|
|
221
|
+
|
|
222
|
+
```csharp
|
|
223
|
+
using DxMessaging.Core.MessageBus;
|
|
224
|
+
using Reflex.Core;
|
|
225
|
+
using NUnit.Framework;
|
|
226
|
+
|
|
227
|
+
[TestFixture]
|
|
228
|
+
public class DamageServiceTests
|
|
229
|
+
{
|
|
230
|
+
[Test]
|
|
231
|
+
public void Initialize_ListensToMessages()
|
|
232
|
+
{
|
|
233
|
+
// Arrange
|
|
234
|
+
var builder = new ContainerBuilder();
|
|
235
|
+
var bus = new MessageBus();
|
|
236
|
+
builder.AddSingleton<IMessageBus>(bus);
|
|
237
|
+
builder.AddSingleton<DamageService>();
|
|
238
|
+
var container = builder.Build();
|
|
239
|
+
|
|
240
|
+
bool messageReceived = false;
|
|
241
|
+
var handler = new MessageHandler(new InstanceId(1), bus) { active = true };
|
|
242
|
+
var token = MessageRegistrationToken.Create(handler, bus);
|
|
243
|
+
_ = token.RegisterUntargeted<PlayerDamaged>(ref msg => messageReceived = true);
|
|
244
|
+
token.Enable();
|
|
245
|
+
|
|
246
|
+
// Act
|
|
247
|
+
var service = container.Resolve<DamageService>();
|
|
248
|
+
service.Initialize();
|
|
249
|
+
var message = new PlayerDamaged(25);
|
|
250
|
+
bus.EmitUntargeted(ref message);
|
|
251
|
+
|
|
252
|
+
// Assert
|
|
253
|
+
Assert.IsTrue(messageReceived);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Checklist
|
|
261
|
+
|
|
262
|
+
### Initial Setup
|
|
263
|
+
|
|
264
|
+
- [ ] Install DxMessaging and Reflex
|
|
265
|
+
- [ ] Create `DxMessagingInstaller` with bus bindings
|
|
266
|
+
- [ ] Add installer to your `SceneContext` or `ProjectContext`
|
|
267
|
+
- [ ] Add `#if REFLEX_PRESENT` check and call `descriptor.AddMessageRegistrationBuilder()`
|
|
268
|
+
|
|
269
|
+
### Integration
|
|
270
|
+
|
|
271
|
+
- [ ] Use `IMessageRegistrationBuilder` in plain classes
|
|
272
|
+
- [ ] Call `Initialize()` and `Dispose()` manually from a bootstrap script
|
|
273
|
+
- [ ] Add `MessagingComponentConfigurator` to prefabs with `MessagingComponent`
|
|
274
|
+
- [ ] Replace `MessageHandler.MessageBus` references with injected `IMessageBus`
|
|
275
|
+
|
|
276
|
+
### Pooling
|
|
277
|
+
|
|
278
|
+
- [ ] Use `container.Inject(instance)` for pooled objects
|
|
279
|
+
- [ ] Ensure injection happens before message handlers are registered
|
|
280
|
+
|
|
281
|
+
### Testing
|
|
282
|
+
|
|
283
|
+
- [ ] Create isolated `ContainerBuilder` instances in tests
|
|
284
|
+
- [ ] Use `builder.AddSingleton<IMessageBus>(new MessageBus())` for test buses
|
|
285
|
+
|
|
286
|
+
---
|
|
287
|
+
|
|
288
|
+
## Next Steps
|
|
289
|
+
|
|
290
|
+
- **[Zenject Integration](Zenject.md)** — Full-featured DI with extensive Unity support
|
|
291
|
+
- **[VContainer Integration](VContainer.md)** — Lightweight alternative with scoped lifetimes
|
|
292
|
+
- **[Back to Documentation Hub](../Index.md)** — Browse all docs
|