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.
- 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 +1352 -141
- package/Docs/Compatibility.md +27 -0
- package/Docs/DesignAndArchitecture.md +41 -34
- package/Docs/EmitShorthands.md +34 -0
- package/Docs/GettingStarted.md +84 -17
- 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/Overview.md +114 -20
- package/Docs/Patterns.md +327 -2
- 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 +281 -167
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- package/Editor/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +3 -3
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll +0 -0
- package/Editor/Analyzers/Microsoft.CodeAnalysis.dll.meta +2 -2
- package/Editor/Analyzers/System.Collections.Immutable.dll +0 -0
- package/Editor/Analyzers/System.Reflection.Metadata.dll +0 -0
- package/Editor/Analyzers/System.Runtime.CompilerServices.Unsafe.dll +0 -0
- package/Editor/CustomEditors/MessagingComponentEditor.cs +15 -6
- package/README.md +388 -67
- 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 +86 -28
- package/Samples~/Mini Combat/Walkthrough.md +41 -25
- package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs +12 -2
- package/Samples~/UI Buttons + Inspector/README.md +55 -12
- 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/SourceGeneratorNestedTests.cs +1 -1
- 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/VisualGuide.md
CHANGED
|
@@ -6,45 +6,67 @@ If you're brand new to messaging systems, this visual guide will help you unders
|
|
|
6
6
|
|
|
7
7
|
### The Old Way (Spaghetti Code)
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
9
|
+
```mermaid
|
|
10
|
+
graph LR
|
|
11
|
+
Player[Player]
|
|
12
|
+
Enemy[Enemy]
|
|
13
|
+
Inventory[Inventory]
|
|
14
|
+
UI[UI]
|
|
15
|
+
Audio[Audio]
|
|
16
|
+
|
|
17
|
+
Player -->|direct ref| UI
|
|
18
|
+
Player -->|direct ref| Audio
|
|
19
|
+
Enemy -->|direct ref| UI
|
|
20
|
+
Enemy -->|direct ref| Audio
|
|
21
|
+
Inventory -->|direct ref| Audio
|
|
22
|
+
|
|
23
|
+
style Player fill:#ffa39e,stroke:#cf1322,stroke-width:2px,color:#000
|
|
24
|
+
style Enemy fill:#ffa39e,stroke:#cf1322,stroke-width:2px,color:#000
|
|
25
|
+
style Inventory fill:#ffa39e,stroke:#cf1322,stroke-width:2px,color:#000
|
|
26
|
+
style UI fill:#b7eb8f,stroke:#389e0d,stroke-width:2px,color:#000
|
|
27
|
+
style Audio fill:#b7eb8f,stroke:#389e0d,stroke-width:2px,color:#000
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
#### Problems
|
|
31
|
+
|
|
32
|
+
- ❌ Everyone needs to know everyone else
|
|
33
|
+
- ❌ Hard to add/remove systems
|
|
34
|
+
- ❌ Memory leaks from forgotten unsubscribes
|
|
27
35
|
|
|
28
36
|
### The DxMessaging Way (Clean Separation)
|
|
29
37
|
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
38
|
+
```mermaid
|
|
39
|
+
graph TB
|
|
40
|
+
Player[Player]
|
|
41
|
+
Enemy[Enemy]
|
|
42
|
+
Inventory[Inventory]
|
|
43
|
+
Bus((Message<br/>Bus))
|
|
44
|
+
UI[UI]
|
|
45
|
+
Audio[Audio]
|
|
46
|
+
Analytics[Analytics]
|
|
47
|
+
|
|
48
|
+
Player -->|message| Bus
|
|
49
|
+
Enemy -->|message| Bus
|
|
50
|
+
Inventory -->|message| Bus
|
|
51
|
+
|
|
52
|
+
Bus -->|notify| UI
|
|
53
|
+
Bus -->|notify| Audio
|
|
54
|
+
Bus -->|notify| Analytics
|
|
55
|
+
|
|
56
|
+
style Player fill:#91d5ff,stroke:#096dd9,stroke-width:2px,color:#000
|
|
57
|
+
style Enemy fill:#91d5ff,stroke:#096dd9,stroke-width:2px,color:#000
|
|
58
|
+
style Inventory fill:#91d5ff,stroke:#096dd9,stroke-width:2px,color:#000
|
|
59
|
+
style Bus fill:#ffd591,stroke:#d46b08,stroke-width:3px,color:#000
|
|
60
|
+
style UI fill:#95de64,stroke:#237804,stroke-width:2px,color:#000
|
|
61
|
+
style Audio fill:#95de64,stroke:#237804,stroke-width:2px,color:#000
|
|
62
|
+
style Analytics fill:#95de64,stroke:#237804,stroke-width:2px,color:#000
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### Benefits
|
|
66
|
+
|
|
67
|
+
- ✅ Nobody knows about anyone else
|
|
68
|
+
- ✅ Easy to add/remove systems
|
|
69
|
+
- ✅ Zero memory leaks (automatic cleanup)
|
|
48
70
|
|
|
49
71
|
## 📨 The Three Message Types (Simple!)
|
|
50
72
|
|
|
@@ -66,9 +88,9 @@ msg.Emit();
|
|
|
66
88
|
|
|
67
89
|
// Anyone can listen
|
|
68
90
|
_ = token.RegisterUntargeted<GamePaused>(OnPause);
|
|
69
|
-
```
|
|
91
|
+
```
|
|
70
92
|
|
|
71
|
-
#### Real-world uses
|
|
93
|
+
#### Real-world uses
|
|
72
94
|
|
|
73
95
|
- "Game paused!"
|
|
74
96
|
- "Settings changed!"
|
|
@@ -90,9 +112,9 @@ heal.EmitGameObjectTargeted(playerObject);
|
|
|
90
112
|
|
|
91
113
|
// Only the player listens
|
|
92
114
|
_ = token.RegisterComponentTargeted<Heal>(this, OnHeal);
|
|
93
|
-
```
|
|
115
|
+
```
|
|
94
116
|
|
|
95
|
-
#### Real-world uses
|
|
117
|
+
#### Real-world uses
|
|
96
118
|
|
|
97
119
|
- "Player, heal yourself!"
|
|
98
120
|
- "Enemy #3, take damage!"
|
|
@@ -117,9 +139,9 @@ _ = token.RegisterGameObjectBroadcast<TookDamage>(enemyObject, OnThisEnemy);
|
|
|
117
139
|
|
|
118
140
|
// OR achievement system can listen to ALL enemies
|
|
119
141
|
_ = token.RegisterBroadcastWithoutSource<TookDamage>(OnAnyEnemy);
|
|
120
|
-
```
|
|
142
|
+
```
|
|
121
143
|
|
|
122
|
-
#### Real-world uses
|
|
144
|
+
#### Real-world uses
|
|
123
145
|
|
|
124
146
|
- "I (player) took damage!"
|
|
125
147
|
- "I (enemy) died!"
|
|
@@ -129,33 +151,49 @@ _ = token.RegisterBroadcastWithoutSource<TookDamage>(OnAnyEnemy);
|
|
|
129
151
|
|
|
130
152
|
When you send a message, here's what happens:
|
|
131
153
|
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
154
|
+
```mermaid
|
|
155
|
+
sequenceDiagram
|
|
156
|
+
participant You as Your Code
|
|
157
|
+
participant Msg as Message
|
|
158
|
+
participant Int as Interceptors<br/>(Optional)
|
|
159
|
+
participant H0 as Handler<br/>priority: 0
|
|
160
|
+
participant H5 as Handler<br/>priority: 5
|
|
161
|
+
participant H10 as Handler<br/>priority: 10
|
|
162
|
+
participant PP as Post-Processors<br/>(Optional)
|
|
163
|
+
|
|
164
|
+
Note over You: 1. Create message
|
|
165
|
+
You->>Msg: var heal = new Heal(10);
|
|
166
|
+
|
|
167
|
+
Note over You,Msg: 2. Emit message
|
|
168
|
+
You->>Msg: heal.EmitGameObjectTargeted(player);
|
|
169
|
+
|
|
170
|
+
Note over Int: 3. Validate & Normalize
|
|
171
|
+
Msg->>Int: Check message
|
|
172
|
+
Int->>Int: Is valid? (>0)<br/>Clamp if needed (<999)
|
|
173
|
+
alt Invalid message
|
|
174
|
+
Int--xMsg: ❌ Cancel
|
|
175
|
+
else Valid message
|
|
176
|
+
Int->>H0: ✅ Continue
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
Note over H0,H10: 4. Execute handlers (by priority)
|
|
180
|
+
H0->>H0: SaveSystem runs first
|
|
181
|
+
H0->>H5: Next priority
|
|
182
|
+
H5->>H5: AudioSystem runs
|
|
183
|
+
H5->>H10: Next priority
|
|
184
|
+
H10->>H10: UISystem runs last
|
|
185
|
+
|
|
186
|
+
Note over PP: 5. Analytics & Logging
|
|
187
|
+
H10->>PP: All handlers complete
|
|
188
|
+
PP->>PP: Analytics.Track(...)<br/>Debug.Log(...)
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
### Key points
|
|
192
|
+
|
|
193
|
+
- **Step 1-2:** You create and emit the message
|
|
194
|
+
- **Step 3 (Optional):** Interceptors can validate, modify, or cancel
|
|
195
|
+
- **Step 4:** Handlers run in priority order (lower number = earlier)
|
|
196
|
+
- **Step 5 (Optional):** Post-processors run after everything (perfect for analytics)
|
|
159
197
|
|
|
160
198
|
## 🎮 Your First Message (3 Easy Steps)
|
|
161
199
|
|
|
@@ -169,7 +207,7 @@ using DxMessaging.Core.Attributes;
|
|
|
169
207
|
public readonly partial struct Heal {
|
|
170
208
|
public readonly int amount;
|
|
171
209
|
}
|
|
172
|
-
|
|
210
|
+
```
|
|
173
211
|
|
|
174
212
|
#### What are those `[DxSomething]` tags?
|
|
175
213
|
|
|
@@ -228,20 +266,29 @@ healMsg.EmitComponentTargeted(playerComponent);
|
|
|
228
266
|
|
|
229
267
|
### Pattern: Scene Transition
|
|
230
268
|
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
269
|
+
```mermaid
|
|
270
|
+
sequenceDiagram
|
|
271
|
+
participant SM as SceneManager
|
|
272
|
+
participant Bus as Message Bus
|
|
273
|
+
participant Audio as AudioSystem
|
|
274
|
+
participant Save as SaveSystem
|
|
275
|
+
|
|
276
|
+
Note over SM: Scene is changing
|
|
277
|
+
SM->>Bus: SceneChanged(sceneIndex: 2)
|
|
278
|
+
|
|
279
|
+
Note over Bus: Message broadcast to all listeners
|
|
280
|
+
|
|
281
|
+
Bus->>Audio: SceneChanged received
|
|
282
|
+
Audio->>Audio: FadeOutMusic()
|
|
283
|
+
|
|
284
|
+
Bus->>Save: SceneChanged received
|
|
285
|
+
Save->>Save: SaveGame()
|
|
286
|
+
|
|
287
|
+
Note over Audio,Save: ✅ All independent!<br/>No coupling!
|
|
243
288
|
```
|
|
244
289
|
|
|
290
|
+
**Why this works:** AudioSystem and SaveSystem don't know about SceneManager or each other. They just listen for `SceneChanged` messages and react independently.
|
|
291
|
+
|
|
245
292
|
Code:
|
|
246
293
|
|
|
247
294
|
```csharp
|
|
@@ -261,16 +308,23 @@ _ = saveToken.RegisterUntargeted<SceneChanged>(OnScene);
|
|
|
261
308
|
|
|
262
309
|
### Pattern: Player Input → Action
|
|
263
310
|
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
311
|
+
```mermaid
|
|
312
|
+
sequenceDiagram
|
|
313
|
+
participant Input as InputSystem
|
|
314
|
+
participant Bus as Message Bus
|
|
315
|
+
participant Player as Player
|
|
316
|
+
|
|
317
|
+
Note over Input: User presses Space
|
|
318
|
+
Input->>Bus: Jump(force: 10f)<br/>[Targeted to Player]
|
|
270
319
|
|
|
271
|
-
|
|
320
|
+
Bus->>Player: Jump message received
|
|
321
|
+
Player->>Player: ApplyForce()<br/>rb.AddForce(...)
|
|
322
|
+
|
|
323
|
+
Note over Input,Player: ✅ Decoupled!<br/>Input doesn't reference Player
|
|
272
324
|
```
|
|
273
325
|
|
|
326
|
+
**Why this works:** InputSystem doesn't need a reference to Player. It just sends a `Jump` message targeted at the player, and the player responds.
|
|
327
|
+
|
|
274
328
|
Code:
|
|
275
329
|
|
|
276
330
|
```csharp
|
|
@@ -291,15 +345,29 @@ void OnJump(ref Jump msg) {
|
|
|
291
345
|
|
|
292
346
|
### Pattern: Achievement Tracking
|
|
293
347
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
348
|
+
```mermaid
|
|
349
|
+
sequenceDiagram
|
|
350
|
+
participant E as Enemy
|
|
351
|
+
participant P as Player
|
|
352
|
+
participant C as Chest
|
|
353
|
+
participant Bus as Message Bus
|
|
354
|
+
participant Ach as Achievement System
|
|
355
|
+
|
|
356
|
+
Note over Ach: Listens to ALL messages
|
|
357
|
+
|
|
358
|
+
E->>Bus: EnemyKilled
|
|
359
|
+
Bus->>Ach: CheckProgress()<br/>UnlockIfReady()
|
|
300
360
|
|
|
301
|
-
|
|
302
|
-
|
|
361
|
+
P->>Bus: LevelCompleted
|
|
362
|
+
Bus->>Ach: CheckProgress()<br/>UnlockIfReady()
|
|
363
|
+
|
|
364
|
+
C->>Bus: ChestOpened
|
|
365
|
+
Bus->>Ach: CheckProgress()<br/>UnlockIfReady()
|
|
366
|
+
|
|
367
|
+
Note over Ach: ✅ Sees EVERYTHING<br/>without coupling!
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**Why this works:** Achievement System uses `RegisterGlobalAcceptAll()` to observe every message type, tracking progress across the entire game without any system knowing about it.
|
|
303
371
|
|
|
304
372
|
Code:
|
|
305
373
|
|
|
@@ -315,7 +383,7 @@ public class AchievementSystem : MessageAwareComponent {
|
|
|
315
383
|
);
|
|
316
384
|
}
|
|
317
385
|
}
|
|
318
|
-
|
|
386
|
+
```
|
|
319
387
|
|
|
320
388
|
## 🚦 When to Use Which Message Type
|
|
321
389
|
|
|
@@ -344,64 +412,51 @@ Think of DxMessaging like a restaurant:
|
|
|
344
412
|
|
|
345
413
|
### Untargeted = Restaurant Announcement
|
|
346
414
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
→ Everyone hears it
|
|
350
|
-
```text
|
|
415
|
+
> "Attention all customers: We're closing in 10 minutes!"
|
|
416
|
+
>
|
|
417
|
+
> → Everyone hears it
|
|
351
418
|
|
|
352
419
|
### Targeted = Waiter Delivering Food
|
|
353
420
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
→ Only table 5 gets it
|
|
357
|
-
````
|
|
421
|
+
> "Order for table 5: Here's your burger"
|
|
422
|
+
>
|
|
423
|
+
> → Only table 5 gets it
|
|
358
424
|
|
|
359
425
|
### Broadcast = Customer Calling Waiter
|
|
360
426
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
→ Comes from table 3
|
|
364
|
-
|
|
365
|
-
→
|
|
366
|
-
|
|
427
|
+
> "Excuse me, I need a refill!" (from table 3)
|
|
428
|
+
>
|
|
429
|
+
> → Comes from table 3
|
|
430
|
+
>
|
|
431
|
+
> → Any available waiter can respond
|
|
432
|
+
>
|
|
433
|
+
> → Manager might track it for statistics
|
|
367
434
|
|
|
368
435
|
## 🔍 Debugging Visualized
|
|
369
436
|
|
|
370
437
|
DxMessaging has built-in Inspector support!
|
|
371
438
|
|
|
372
|
-
|
|
373
|
-
MessagingComponent Inspector:
|
|
374
|
-
┌─────────────────────────────────────┐
|
|
375
|
-
│ Message History (last 10) │
|
|
376
|
-
│ ┌─────────────────────────────────┐ │
|
|
377
|
-
│ │ 12:34:05 - Heal → Player (50) │ │
|
|
378
|
-
│ │ 12:34:03 - Jump → Player │ │
|
|
379
|
-
│ │ 12:34:01 - GamePaused (global) │ │
|
|
380
|
-
│ └─────────────────────────────────┘ │
|
|
381
|
-
│ │
|
|
382
|
-
│ Registrations: │
|
|
383
|
-
│ ┌─────────────────────────────────┐ │
|
|
384
|
-
│ │ ✓ Heal (priority: 0, 5 calls) │ │
|
|
385
|
-
│ │ ✓ Jump (priority: 0, 2 calls) │ │
|
|
386
|
-
│ │ ✓ TookDamage (priority: 10) │ │
|
|
387
|
-
│ └─────────────────────────────────┘ │
|
|
388
|
-
└─────────────────────────────────────┘
|
|
389
|
-
````
|
|
439
|
+
### MessagingComponent Inspector
|
|
390
440
|
|
|
391
|
-
|
|
441
|
+
#### Message History (last 10)
|
|
392
442
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
443
|
+
- `12:34:05 - Heal → Player (50)`
|
|
444
|
+
- `12:34:03 - Jump → Player`
|
|
445
|
+
- `12:34:01 - GamePaused (global)`
|
|
396
446
|
|
|
397
|
-
|
|
398
|
-
Traditional Events: ████████░░ (can leak!)
|
|
399
|
-
DxMessaging: ██░░░░░░░░ (zero leaks, struct messages)
|
|
447
|
+
##### Registrations
|
|
400
448
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
449
|
+
- ✓ Heal (priority: 0, 5 calls)
|
|
450
|
+
- ✓ Jump (priority: 0, 2 calls)
|
|
451
|
+
- ✓ TookDamage (priority: 10)
|
|
452
|
+
|
|
453
|
+
## ⚡ Performance at a Glance
|
|
454
|
+
|
|
455
|
+
| Metric | Traditional C# Events | DxMessaging |
|
|
456
|
+
| ------------ | --------------------- | ----------------------------------- |
|
|
457
|
+
| **Speed** | ⚡⚡⚡⚡ (baseline) | ⚡⚡⚡⚡ (~10ns slower, negligible) |
|
|
458
|
+
| **Memory** | ⚠️ Can leak! | ✅ Zero leaks (struct messages) |
|
|
459
|
+
| **Coupling** | ❌ Tight coupling | ✅ Zero coupling |
|
|
405
460
|
|
|
406
461
|
**Bottom line:** Slightly slower than raw events, but:
|
|
407
462
|
|
|
@@ -412,57 +467,116 @@ DxMessaging: ░░░░░░░░░░ (zero!)
|
|
|
412
467
|
|
|
413
468
|
## 🎓 Learning Path
|
|
414
469
|
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
│
|
|
426
|
-
├─→ 4. Read Common Patterns (15 min)
|
|
427
|
-
│ [Real-world solutions]
|
|
428
|
-
│
|
|
429
|
-
└─→ 5. Build your first feature! (30 min)
|
|
430
|
-
[You're ready!]
|
|
470
|
+
```mermaid
|
|
471
|
+
graph TD
|
|
472
|
+
Start[START HERE<br/>Read this Visual Guide<br/>5 min ✓]
|
|
473
|
+
Start --> Step2[Try Quick Start example<br/>5 min<br/>Define → Listen → Send]
|
|
474
|
+
Step2 --> Step3[Import Mini Combat sample<br/>10 min<br/>See it in action!]
|
|
475
|
+
Step3 --> Step4[Read Common Patterns<br/>15 min<br/>Real-world solutions]
|
|
476
|
+
Step4 --> Step5[Build your first feature!<br/>30 min<br/>You're ready!]
|
|
477
|
+
|
|
478
|
+
style Start fill:#91d5ff,stroke:#096dd9,stroke-width:3px,color:#000
|
|
479
|
+
style Step5 fill:#95de64,stroke:#237804,stroke-width:2px,color:#000
|
|
431
480
|
```
|
|
432
481
|
|
|
433
482
|
## 🆘 Common Beginner Questions
|
|
434
483
|
|
|
435
484
|
### "Do I always need MessageAwareComponent?"
|
|
436
485
|
|
|
437
|
-
**For Unity:** Yes
|
|
486
|
+
**For Unity:** Yes! It's the easiest way. Think of it like `MonoBehaviour` - you inherit from it and it handles all the messy lifecycle stuff automatically.
|
|
487
|
+
|
|
488
|
+
**For pure C#:** No, you can use `MessageRegistrationToken` directly if you're not in Unity.
|
|
438
489
|
|
|
439
|
-
**
|
|
490
|
+
**Bottom line:** If you're in Unity, just use `MessageAwareComponent`. It'll save you hours of debugging.
|
|
440
491
|
|
|
441
492
|
### "Can I send a message to multiple targets?"
|
|
442
493
|
|
|
443
|
-
**No** - Targeted
|
|
494
|
+
**No** - Targeted messages go to ONE specific entity (like mailing a letter to one address).
|
|
495
|
+
|
|
496
|
+
#### Instead, use
|
|
497
|
+
|
|
498
|
+
- **Untargeted** if literally everyone should hear it (like a megaphone announcement)
|
|
499
|
+
- **Broadcast** if it's from one source and many can observe (like a news broadcast)
|
|
500
|
+
|
|
501
|
+
##### Example
|
|
502
|
+
|
|
503
|
+
```csharp
|
|
504
|
+
// ❌ DON'T: Try to target multiple entities
|
|
505
|
+
msg.EmitComponentTargeted(player1);
|
|
506
|
+
msg.EmitComponentTargeted(player2); // Feels wrong, right?
|
|
444
507
|
|
|
445
|
-
|
|
446
|
-
|
|
508
|
+
// ✅ DO: Use broadcast so everyone can listen
|
|
509
|
+
msg.EmitGameObjectBroadcast(enemy); // Now anyone can observe this enemy
|
|
510
|
+
```
|
|
447
511
|
|
|
448
512
|
### "What if I forget to unsubscribe?"
|
|
449
513
|
|
|
450
|
-
**You can't!**
|
|
514
|
+
**You literally can't forget!** 🎉
|
|
515
|
+
|
|
516
|
+
When your component is destroyed, DxMessaging automatically cleans up. No `OnDestroy()` needed. No memory leaks possible.
|
|
517
|
+
|
|
518
|
+
#### Old way (easy to forget)
|
|
519
|
+
|
|
520
|
+
```csharp
|
|
521
|
+
void OnEnable() { GameManager.OnScoreChanged += Update; }
|
|
522
|
+
void OnDisable() { GameManager.OnScoreChanged -= Update; } // Forgot this? LEAK!
|
|
523
|
+
```
|
|
524
|
+
|
|
525
|
+
##### DxMessaging way (impossible to forget)
|
|
526
|
+
|
|
527
|
+
```csharp
|
|
528
|
+
protected override void RegisterMessageHandlers() {
|
|
529
|
+
_ = Token.RegisterUntargeted<ScoreChanged>(Update);
|
|
530
|
+
}
|
|
531
|
+
// That's it! Automatic cleanup when component dies.
|
|
532
|
+
```
|
|
451
533
|
|
|
452
534
|
### "Is it slower than regular events?"
|
|
453
535
|
|
|
454
|
-
**Barely** (~10ns per handler
|
|
536
|
+
**Barely** (~10ns per handler = 0.00001 milliseconds).
|
|
537
|
+
|
|
538
|
+
#### Put it this way
|
|
539
|
+
|
|
540
|
+
- Regular C# event: ~50ns
|
|
541
|
+
- DxMessaging: ~60ns
|
|
542
|
+
- The difference: Drinking a coffee takes 3 billion nanoseconds
|
|
543
|
+
|
|
544
|
+
You get automatic lifecycle, zero leaks, full observability, and predictable ordering for a 20% overhead that's **completely negligible** in any real game.
|
|
455
545
|
|
|
456
546
|
### "Can I cancel a message?"
|
|
457
547
|
|
|
458
|
-
|
|
548
|
+
#### Yes! That's what interceptors are for
|
|
459
549
|
|
|
460
550
|
```csharp
|
|
461
|
-
|
|
462
|
-
|
|
551
|
+
// Cancel invalid damage
|
|
552
|
+
_ = token.RegisterBroadcastInterceptor<TookDamage>(
|
|
553
|
+
(ref InstanceId source, ref TookDamage msg) => {
|
|
554
|
+
if (msg.amount <= 0) return false; // Cancel invalid damage
|
|
555
|
+
if (IsInvincible(source)) return false; // Cancel during invincibility
|
|
556
|
+
return true; // Allow
|
|
557
|
+
}
|
|
463
558
|
);
|
|
464
559
|
```
|
|
465
560
|
|
|
561
|
+
##### Real-world uses
|
|
562
|
+
|
|
563
|
+
- Block input during cutscenes
|
|
564
|
+
- Cancel damage when invincible
|
|
565
|
+
- Prevent cheating (clamp values)
|
|
566
|
+
- Enforce game rules globally
|
|
567
|
+
|
|
568
|
+
### "Can I see what messages are firing?"
|
|
569
|
+
|
|
570
|
+
#### Yes! Open any component in the Inspector and scroll down
|
|
571
|
+
|
|
572
|
+
You'll see:
|
|
573
|
+
|
|
574
|
+
- Message history (last 50 messages with timestamps)
|
|
575
|
+
- Active registrations (what you're listening to)
|
|
576
|
+
- Call counts (how many times each handler ran)
|
|
577
|
+
|
|
578
|
+
**No more guessing.** You can literally see your event flow in real-time.
|
|
579
|
+
|
|
466
580
|
## ✅ Quick Checklist: Am I Doing It Right
|
|
467
581
|
|
|
468
582
|
- [ ] Using `MessageAwareComponent` for Unity components? ✅
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
fileFormatVersion: 2
|
|
2
|
-
guid:
|
|
2
|
+
guid: ac94a51a66736f443b68aa222d32eb04
|
|
3
3
|
PluginImporter:
|
|
4
4
|
externalObjects: {}
|
|
5
5
|
serializedVersion: 2
|
|
@@ -14,12 +14,12 @@ PluginImporter:
|
|
|
14
14
|
- first:
|
|
15
15
|
Any:
|
|
16
16
|
second:
|
|
17
|
-
enabled:
|
|
17
|
+
enabled: 1
|
|
18
18
|
settings: {}
|
|
19
19
|
- first:
|
|
20
20
|
Editor: Editor
|
|
21
21
|
second:
|
|
22
|
-
enabled:
|
|
22
|
+
enabled: 0
|
|
23
23
|
settings:
|
|
24
24
|
DefaultValueInitialized: true
|
|
25
25
|
- first:
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|