com.wallstop-studios.dxmessaging 2.0.0 → 2.1.1
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 +91 -76
- package/Docs/Index.md +28 -25
- package/Docs/Install.md +29 -6
- package/Docs/Integrations/Reflex.md +292 -0
- package/{package-lock.json.meta → Docs/Integrations/Reflex.md.meta} +1 -1
- 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/QuickStart.md +1 -2
- 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/Attributes/DxAutoConstructorAttribute.cs +1 -1
- package/Runtime/Core/Attributes/DxBroadcastMessageAttribute.cs +1 -1
- package/Runtime/Core/Attributes/DxOptionalParameterAttribute.cs +1 -1
- package/Runtime/Core/Attributes/DxTargetedMessageAttribute.cs +1 -1
- package/Runtime/Core/Attributes/DxUntargetedMessageAttribute.cs +1 -1
- 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/Core/Messages/IBroadcastMessage.cs +1 -1
- package/Runtime/Core/Messages/ITargetedMessage.cs +1 -1
- package/Runtime/Core/Messages/IUntargetedMessage.cs +1 -1
- 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 +175 -9
- 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 +79 -0
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +11 -0
- package/Samples~/DI/VContainer.meta +8 -0
- package/Samples~/DI/Zenject/SampleInstaller.cs +65 -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
|
+
[DxAutoConstructor]
|
|
74
|
+
public readonly partial struct ScoreChanged
|
|
75
|
+
{
|
|
76
|
+
public readonly int 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
|
@@ -186,34 +186,32 @@ public readonly partial struct ComplexMessage
|
|
|
186
186
|
|
|
187
187
|
## Why Use Attributes Instead of Manual Implementation
|
|
188
188
|
|
|
189
|
-
###
|
|
189
|
+
### ✅ Attribute Definition (Clean, Automatic)
|
|
190
190
|
|
|
191
191
|
```csharp
|
|
192
|
-
|
|
192
|
+
[DxTargetedMessage]
|
|
193
|
+
[DxAutoConstructor]
|
|
194
|
+
public readonly partial struct Heal
|
|
193
195
|
{
|
|
194
196
|
public readonly int amount;
|
|
195
|
-
|
|
196
|
-
// You write this yourself (boring!)
|
|
197
|
-
public Heal(int amount)
|
|
198
|
-
{
|
|
199
|
-
this.amount = amount;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
// Required plumbing (easy to mess up!)
|
|
203
|
-
public Type MessageType => typeof(Heal);
|
|
204
197
|
}
|
|
205
198
|
```
|
|
206
199
|
|
|
207
|
-
###
|
|
200
|
+
### What the generator emits (for reference)
|
|
208
201
|
|
|
209
202
|
```csharp
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
public readonly partial struct Heal
|
|
203
|
+
// Auto-generated by DxMessaging (no need to hand-write this)
|
|
204
|
+
public readonly partial struct Heal : ITargetedMessage<Heal>
|
|
213
205
|
{
|
|
214
206
|
public readonly int amount;
|
|
207
|
+
|
|
208
|
+
public Heal(int amount)
|
|
209
|
+
{
|
|
210
|
+
this.amount = amount;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
public Type MessageType => typeof(Heal);
|
|
215
214
|
}
|
|
216
|
-
// Constructor and plumbing generated automatically!
|
|
217
215
|
```
|
|
218
216
|
|
|
219
217
|
#### Benefits
|
|
@@ -223,14 +221,28 @@ public readonly partial struct Heal
|
|
|
223
221
|
- ✅ **Cleaner** - Focus on data, not boilerplate
|
|
224
222
|
- ✅ **Refactor-safe** - Add field? Constructor updates automatically!
|
|
225
223
|
|
|
226
|
-
## Complete Example:
|
|
224
|
+
## Complete Example: Attribute Definition vs Generated Output
|
|
227
225
|
|
|
228
|
-
###
|
|
226
|
+
### Attribute Definition (8 lines)
|
|
229
227
|
|
|
230
228
|
```csharp
|
|
231
|
-
using DxMessaging.Core.
|
|
229
|
+
using DxMessaging.Core.Attributes;
|
|
232
230
|
|
|
233
|
-
|
|
231
|
+
[DxBroadcastMessage]
|
|
232
|
+
[DxAutoConstructor]
|
|
233
|
+
public readonly partial struct PlayerDamaged
|
|
234
|
+
{
|
|
235
|
+
public readonly int amount;
|
|
236
|
+
public readonly string damageType;
|
|
237
|
+
public readonly GameObject source;
|
|
238
|
+
}
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
### Generated Output (20 lines you never write)
|
|
242
|
+
|
|
243
|
+
```csharp
|
|
244
|
+
// Auto-generated by DxMessaging (for reference only)
|
|
245
|
+
public readonly partial struct PlayerDamaged : IBroadcastMessage<PlayerDamaged>
|
|
234
246
|
{
|
|
235
247
|
public readonly int amount;
|
|
236
248
|
public readonly string damageType;
|
|
@@ -247,65 +259,76 @@ public readonly struct PlayerDamaged : IBroadcastMessage<PlayerDamaged>
|
|
|
247
259
|
}
|
|
248
260
|
```
|
|
249
261
|
|
|
250
|
-
###
|
|
262
|
+
### Result
|
|
251
263
|
|
|
252
|
-
|
|
253
|
-
|
|
264
|
+
- ✅ Same functionality
|
|
265
|
+
- ✅ Less code to maintain
|
|
266
|
+
- ✅ Automatically updates when you add/remove fields
|
|
267
|
+
- ✅ Works for class messages too
|
|
268
|
+
- ✅ Zero effort once you mark the struct partial
|
|
254
269
|
|
|
255
|
-
|
|
270
|
+
## Advanced: Manual Implementation (When Attributes Aren't Enough)
|
|
271
|
+
|
|
272
|
+
Attributes cover almost every scenario. If you intentionally drop `[DxTargetedMessage]`, `[DxUntargetedMessage]`, or `[DxBroadcastMessage]`, you'll need to hand-write the interface implementations and constructors shown in the “generated output” examples. Keep the attributes unless you have a very specific data-backed reason not to.
|
|
273
|
+
|
|
274
|
+
### Generic Message Interfaces (Zero-Boxing for Structs)
|
|
275
|
+
|
|
276
|
+
`readonly struct` messages marked with the attributes already implement the generic interfaces, so emissions stay allocation-free. You get the same performance characteristics as the manual approach without writing any plumbing.
|
|
277
|
+
|
|
278
|
+
```csharp
|
|
279
|
+
[DxTargetedMessage]
|
|
256
280
|
[DxAutoConstructor]
|
|
257
|
-
public readonly partial struct
|
|
281
|
+
public readonly partial struct Heal
|
|
258
282
|
{
|
|
259
283
|
public readonly int amount;
|
|
260
|
-
public readonly string damageType;
|
|
261
|
-
public readonly GameObject source;
|
|
262
284
|
}
|
|
263
285
|
```
|
|
264
286
|
|
|
265
|
-
|
|
287
|
+
### "Do I HAVE to use attributes?"
|
|
266
288
|
|
|
267
|
-
|
|
289
|
+
Technically no—but without them you must write the constructor, interface implementation, and `MessageType` property yourself (for speed, you can optionally leave this off, but it might box on certain call paths). Leaving the attributes on keeps everything consistent for the whole team.
|
|
268
290
|
|
|
269
|
-
|
|
291
|
+
```csharp
|
|
292
|
+
[DxUntargetedMessage]
|
|
293
|
+
[DxAutoConstructor]
|
|
294
|
+
public readonly partial struct MyMsg { }
|
|
295
|
+
```
|
|
270
296
|
|
|
271
|
-
###
|
|
297
|
+
### "What if I want custom constructor logic?"
|
|
272
298
|
|
|
273
|
-
|
|
299
|
+
Keep the attributes and add a factory/helper so you still benefit from the generated constructor:
|
|
274
300
|
|
|
275
301
|
```csharp
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
public readonly struct
|
|
302
|
+
[DxUntargetedMessage]
|
|
303
|
+
[DxAutoConstructor]
|
|
304
|
+
public readonly partial struct ComplexMessage
|
|
279
305
|
{
|
|
280
|
-
public readonly int
|
|
306
|
+
public readonly int value;
|
|
281
307
|
|
|
282
|
-
public
|
|
308
|
+
public static ComplexMessage FromRaw(int rawValue)
|
|
283
309
|
{
|
|
284
|
-
|
|
310
|
+
int clamped = Math.Clamp(rawValue, 0, 100);
|
|
311
|
+
return new ComplexMessage(clamped);
|
|
285
312
|
}
|
|
286
|
-
|
|
287
|
-
// Required for IMessage
|
|
288
|
-
public Type MessageType => typeof(Heal);
|
|
289
313
|
}
|
|
290
314
|
```
|
|
291
315
|
|
|
292
|
-
|
|
316
|
+
If you truly must write a custom constructor, drop `[DxAutoConstructor]` for that type but keep the `[DxUntargetedMessage]`/`[DxTargetedMessage]` attribute so the interface plumbing stays consistent.
|
|
293
317
|
|
|
294
|
-
|
|
295
|
-
- Provides stable `MessageType` without `GetType()` calls
|
|
296
|
-
- Same performance as attribute-based approach
|
|
318
|
+
### "Can I mix attribute-based and manual messages?"
|
|
297
319
|
|
|
298
|
-
|
|
320
|
+
Yes. Attribute-driven messages happily coexist with string messages and any manual implementations you already have. You can migrate gradually by converting one message at a time:
|
|
299
321
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
322
|
+
```csharp
|
|
323
|
+
[DxUntargetedMessage]
|
|
324
|
+
[DxAutoConstructor]
|
|
325
|
+
public readonly partial struct MessageA
|
|
326
|
+
{
|
|
327
|
+
public readonly int value;
|
|
328
|
+
}
|
|
305
329
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
- Easier to maintain
|
|
330
|
+
// Existing manual message types keep working alongside attribute-driven ones.
|
|
331
|
+
```
|
|
309
332
|
|
|
310
333
|
## Extension Methods (Emit Helpers)
|
|
311
334
|
|
|
@@ -355,7 +378,7 @@ using DxMessaging.Core.MessageBus;
|
|
|
355
378
|
|
|
356
379
|
// Create isolated bus
|
|
357
380
|
var testBus = new MessageBus();
|
|
358
|
-
var handler = new MessageHandler(new InstanceId(1)) { active = true };
|
|
381
|
+
var handler = new MessageHandler(new InstanceId(1), testBus) { active = true };
|
|
359
382
|
var token = MessageRegistrationToken.Create(handler, testBus);
|
|
360
383
|
|
|
361
384
|
// Register on isolated bus
|
|
@@ -549,50 +572,42 @@ public readonly partial struct MyMessage : IUntargetedMessage<MyMessage>
|
|
|
549
572
|
|
|
550
573
|
### "What if I want custom constructor logic?"
|
|
551
574
|
|
|
552
|
-
|
|
575
|
+
Keep the attributes and wrap the generated constructor with a helper so you can inject custom logic without losing the source-generated plumbing:
|
|
553
576
|
|
|
554
577
|
```csharp
|
|
555
|
-
|
|
578
|
+
[DxUntargetedMessage]
|
|
579
|
+
[DxAutoConstructor]
|
|
580
|
+
public readonly partial struct ComplexMessage
|
|
556
581
|
{
|
|
557
582
|
public readonly int value;
|
|
558
583
|
|
|
559
|
-
public ComplexMessage(int rawValue)
|
|
584
|
+
public static ComplexMessage FromRaw(int rawValue)
|
|
560
585
|
{
|
|
561
|
-
|
|
562
|
-
|
|
586
|
+
int clamped = Math.Clamp(rawValue, 0, 100);
|
|
587
|
+
return new ComplexMessage(clamped);
|
|
563
588
|
}
|
|
564
|
-
|
|
565
|
-
public Type MessageType => typeof(ComplexMessage);
|
|
566
589
|
}
|
|
567
590
|
```
|
|
568
591
|
|
|
592
|
+
If you truly need to hand-craft the constructor, drop `[DxAutoConstructor]` for that specific type but keep the `[DxUntargetedMessage]`/`[DxTargetedMessage]` attribute so the interface implementation is still generated.
|
|
593
|
+
|
|
569
594
|
### "Do attributes affect runtime performance?"
|
|
570
595
|
|
|
571
596
|
**No!** Source generation happens at **compile time**. Generated code is identical to hand-written code. Zero runtime overhead.
|
|
572
597
|
|
|
573
598
|
### "Can I mix attributes and manual implementation?"
|
|
574
599
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
- Some messages using attributes
|
|
578
|
-
- Other messages using manual implementation
|
|
579
|
-
- Mix and match across your codebase
|
|
600
|
+
Yes. Attribute-driven messages happily coexist with any legacy manual messages or string messages you already emit. Convert types gradually—one message at a time:
|
|
580
601
|
|
|
581
602
|
```csharp
|
|
582
|
-
// Message A: Attributes
|
|
583
603
|
[DxUntargetedMessage]
|
|
584
604
|
[DxAutoConstructor]
|
|
585
|
-
public readonly partial struct MessageA
|
|
586
|
-
|
|
587
|
-
// Message B: Manual
|
|
588
|
-
public readonly struct MessageB : IUntargetedMessage<MessageB>
|
|
605
|
+
public readonly partial struct MessageA
|
|
589
606
|
{
|
|
590
607
|
public readonly int value;
|
|
591
|
-
public MessageB(int value) { this.value = value; }
|
|
592
|
-
public Type MessageType => typeof(MessageB);
|
|
593
608
|
}
|
|
594
609
|
|
|
595
|
-
//
|
|
610
|
+
// Existing manual messages keep working alongside attribute-driven ones.
|
|
596
611
|
```
|
|
597
612
|
|
|
598
613
|
## Troubleshooting Source Generators
|
|
@@ -609,7 +624,7 @@ public readonly struct MessageB : IUntargetedMessage<MessageB>
|
|
|
609
624
|
##### Fix
|
|
610
625
|
|
|
611
626
|
```csharp
|
|
612
|
-
// ❌ Missing partial
|
|
627
|
+
// ❌ Missing partial, will not compile
|
|
613
628
|
[DxAutoConstructor]
|
|
614
629
|
public readonly struct MyMsg { }
|
|
615
630
|
|
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.
|