com.wallstop-studios.dxmessaging 3.2.0 → 3.2.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +8 -8
  3. package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs +171 -13
  4. package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +391 -96
  5. package/Editor/CustomEditors/MessageAwareComponentInspectorView.cs +279 -0
  6. package/Editor/CustomEditors/MessageAwareComponentInspectorView.cs.meta +11 -0
  7. package/Editor/DxMessagingEditorPalette.cs +66 -0
  8. package/Editor/DxMessagingEditorPalette.cs.meta +11 -0
  9. package/Editor/DxMessagingEditorTheme.cs +200 -0
  10. package/Editor/DxMessagingEditorTheme.cs.meta +11 -0
  11. package/Editor/Icons/dxmessaging-icon-256.png +0 -0
  12. package/Editor/Icons/dxmessaging-icon-256.png.meta +156 -0
  13. package/Editor/Icons/dxmessaging-icon-32.png +0 -0
  14. package/Editor/Icons/dxmessaging-icon-32.png.meta +156 -0
  15. package/Editor/Icons/dxmessaging-icon-48.png +0 -0
  16. package/Editor/Icons/dxmessaging-icon-48.png.meta +156 -0
  17. package/Editor/Icons.meta +8 -0
  18. package/Editor/Settings/DxMessagingSettingsProvider.cs +368 -33
  19. package/Editor/Testing/MessagingComponentEditorHarness.cs +11 -4
  20. package/Editor/Theme/DxMessagingTheme.uss +255 -0
  21. package/Editor/Theme/DxMessagingTheme.uss.meta +11 -0
  22. package/Editor/Theme/DxTokens.uss +90 -0
  23. package/Editor/Theme/DxTokens.uss.meta +11 -0
  24. package/Editor/Theme.meta +8 -0
  25. package/Editor/Windows/DxMessagingFlowGraphWindow.cs +5513 -0
  26. package/Editor/Windows/DxMessagingFlowGraphWindow.cs.meta +11 -0
  27. package/Editor/Windows/DxMessagingMessageMonitorWindow.cs +2288 -0
  28. package/Editor/Windows/DxMessagingMessageMonitorWindow.cs.meta +11 -0
  29. package/Editor/Windows.meta +8 -0
  30. package/README.md +84 -35
  31. package/Runtime/AssemblyInfo.cs +1 -0
  32. package/Runtime/Core/Diagnostics/MessageEmissionData.cs +29 -1
  33. package/Runtime/Core/Extensions/MessageExtensions.cs +4 -5
  34. package/Runtime/Core/Helper/MessageCache.cs +56 -23
  35. package/Runtime/Core/Internal/FlatDispatch.cs +32 -0
  36. package/Runtime/Core/Internal/TypedSlots.cs +3 -7
  37. package/Runtime/Core/MessageBus/MessageBus.cs +577 -142
  38. package/Runtime/Core/MessageBus/RegistrationLog.cs +25 -12
  39. package/Runtime/Core/MessageHandler.cs +774 -786
  40. package/Runtime/Core/MessageRegistrationHandle.cs +19 -5
  41. package/Runtime/Core/MessageRegistrationToken.cs +1080 -520
  42. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.cs +173 -0
  43. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.cs.meta +11 -0
  44. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.unity +424 -0
  45. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.unity.meta +7 -0
  46. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingReceiver.cs +185 -0
  47. package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingReceiver.cs.meta +11 -0
  48. package/Samples~/Diagnostics Tooling Exerciser/Messages.cs +46 -0
  49. package/Samples~/Diagnostics Tooling Exerciser/Messages.cs.meta +11 -0
  50. package/Samples~/Diagnostics Tooling Exerciser/README.md +53 -0
  51. package/Samples~/Diagnostics Tooling Exerciser/README.md.meta +7 -0
  52. package/Samples~/Diagnostics Tooling Exerciser/WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample.asmdef +13 -0
  53. package/Samples~/Diagnostics Tooling Exerciser/WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample.asmdef.meta +7 -0
  54. package/Samples~/Diagnostics Tooling Exerciser.meta +8 -0
  55. package/Samples~/Mini Combat/README.md +1 -1
  56. package/Samples~/Mini Combat/Walkthrough.md +3 -3
  57. package/docs/images/DxMessaging-banner.svg +79 -0
  58. package/docs/images/DxMessaging-banner.svg.meta +53 -0
  59. package/docs/images.meta +8 -0
  60. package/docs.meta +8 -0
  61. package/package.json +13 -4
@@ -0,0 +1,185 @@
1
+ namespace WallstopStudios.DxMessagingSamples.DiagnosticsToolingExerciser
2
+ {
3
+ using DxMessaging.Core;
4
+ using DxMessaging.Core.Messages;
5
+ using DxMessaging.Unity;
6
+ using UnityEngine;
7
+
8
+ [DisallowMultipleComponent]
9
+ public sealed class DiagnosticsToolingReceiver : MessageAwareComponent
10
+ {
11
+ [SerializeField]
12
+ private string listenerLabel = "Receiver";
13
+
14
+ [SerializeField]
15
+ private GameObject broadcastSourceFilter;
16
+
17
+ [SerializeField]
18
+ private bool enableLocalDiagnostics = true;
19
+
20
+ [SerializeField]
21
+ private bool registerGlobalAcceptAll = true;
22
+
23
+ [SerializeField]
24
+ private bool logMessages;
25
+
26
+ [SerializeField]
27
+ private int untargetedCount;
28
+
29
+ [SerializeField]
30
+ private int targetedCount;
31
+
32
+ [SerializeField]
33
+ private int broadcastCount;
34
+
35
+ [SerializeField]
36
+ private int globalAcceptAllCount;
37
+
38
+ [SerializeField]
39
+ private string lastTraceId = "None";
40
+
41
+ [SerializeField]
42
+ private string lastRoute = "None";
43
+
44
+ [SerializeField]
45
+ private string lastPayload = "None";
46
+
47
+ private bool toolingRegistrationsEnsured;
48
+
49
+ public string ListenerLabel => listenerLabel;
50
+
51
+ public int UntargetedCount => untargetedCount;
52
+
53
+ public int TargetedCount => targetedCount;
54
+
55
+ public int BroadcastCount => broadcastCount;
56
+
57
+ public int GlobalAcceptAllCount => globalAcceptAllCount;
58
+
59
+ protected override bool RegisterForStringMessages => false;
60
+
61
+ protected override void Awake()
62
+ {
63
+ base.Awake();
64
+ }
65
+
66
+ protected override void OnEnable()
67
+ {
68
+ base.OnEnable();
69
+ }
70
+
71
+ protected override void OnDisable()
72
+ {
73
+ base.OnDisable();
74
+ }
75
+
76
+ private void Start()
77
+ {
78
+ EnsureToolingRegistrations();
79
+ }
80
+
81
+ public void EnsureToolingRegistrations()
82
+ {
83
+ if (Token == null)
84
+ {
85
+ return;
86
+ }
87
+
88
+ if (!toolingRegistrationsEnsured)
89
+ {
90
+ RegisterMessageHandlers();
91
+ toolingRegistrationsEnsured = true;
92
+ }
93
+
94
+ Token.Enable();
95
+ }
96
+
97
+ protected override void RegisterMessageHandlers()
98
+ {
99
+ base.RegisterMessageHandlers();
100
+
101
+ if (enableLocalDiagnostics)
102
+ {
103
+ Token.DiagnosticMode = true;
104
+ }
105
+
106
+ _ = Token.RegisterUntargeted<ToolingPulse>(OnPulse);
107
+ _ = Token.RegisterGameObjectTargeted<ToolingCommand>(gameObject, OnCommand);
108
+ _ = Token.RegisterBroadcastWithoutSource<ToolingSignal>(OnSignalFromAnySource);
109
+
110
+ if (broadcastSourceFilter != null)
111
+ {
112
+ InstanceId source = broadcastSourceFilter;
113
+ _ = Token.RegisterBroadcast<ToolingSignal>(source, OnSignalFromExactSource);
114
+ }
115
+
116
+ if (registerGlobalAcceptAll)
117
+ {
118
+ _ = Token.RegisterGlobalAcceptAll(OnAnyUntargeted, OnAnyTargeted, OnAnyBroadcast);
119
+ }
120
+ }
121
+
122
+ [ContextMenu("Reset Counts")]
123
+ public void ResetCounts()
124
+ {
125
+ untargetedCount = 0;
126
+ targetedCount = 0;
127
+ broadcastCount = 0;
128
+ globalAcceptAllCount = 0;
129
+ lastTraceId = "None";
130
+ lastRoute = "None";
131
+ lastPayload = "None";
132
+ }
133
+
134
+ private void OnPulse(ref ToolingPulse message)
135
+ {
136
+ untargetedCount++;
137
+ Record("Untargeted", message.traceId, message.channel);
138
+ }
139
+
140
+ private void OnCommand(ref ToolingCommand message)
141
+ {
142
+ targetedCount++;
143
+ Record("Targeted", message.traceId, message.command);
144
+ }
145
+
146
+ private void OnSignalFromAnySource(InstanceId source, ToolingSignal message)
147
+ {
148
+ broadcastCount++;
149
+ Record("Broadcast without source", message.traceId, message.sourceLabel);
150
+ }
151
+
152
+ private void OnSignalFromExactSource(ref ToolingSignal message)
153
+ {
154
+ broadcastCount++;
155
+ Record("Broadcast exact source", message.traceId, message.sourceLabel);
156
+ }
157
+
158
+ private void OnAnyUntargeted(IUntargetedMessage message)
159
+ {
160
+ globalAcceptAllCount++;
161
+ }
162
+
163
+ private void OnAnyTargeted(InstanceId target, ITargetedMessage message)
164
+ {
165
+ globalAcceptAllCount++;
166
+ }
167
+
168
+ private void OnAnyBroadcast(InstanceId source, IBroadcastMessage message)
169
+ {
170
+ globalAcceptAllCount++;
171
+ }
172
+
173
+ private void Record(string route, string traceId, string payload)
174
+ {
175
+ lastRoute = route;
176
+ lastTraceId = traceId;
177
+ lastPayload = payload;
178
+
179
+ if (logMessages)
180
+ {
181
+ Debug.Log($"[{listenerLabel}] {lastRoute} {lastTraceId}: {lastPayload}", this);
182
+ }
183
+ }
184
+ }
185
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: a45996c05f2e369169f682be7e6de42a
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,46 @@
1
+ namespace WallstopStudios.DxMessagingSamples.DiagnosticsToolingExerciser
2
+ {
3
+ using DxMessaging.Core.Messages;
4
+
5
+ public readonly struct ToolingPulse : IUntargetedMessage<ToolingPulse>
6
+ {
7
+ public readonly string traceId;
8
+ public readonly string channel;
9
+ public readonly int sequence;
10
+
11
+ public ToolingPulse(string traceId, string channel, int sequence)
12
+ {
13
+ this.traceId = traceId;
14
+ this.channel = channel;
15
+ this.sequence = sequence;
16
+ }
17
+ }
18
+
19
+ public readonly struct ToolingCommand : ITargetedMessage<ToolingCommand>
20
+ {
21
+ public readonly string traceId;
22
+ public readonly string command;
23
+ public readonly int sequence;
24
+
25
+ public ToolingCommand(string traceId, string command, int sequence)
26
+ {
27
+ this.traceId = traceId;
28
+ this.command = command;
29
+ this.sequence = sequence;
30
+ }
31
+ }
32
+
33
+ public readonly struct ToolingSignal : IBroadcastMessage<ToolingSignal>
34
+ {
35
+ public readonly string traceId;
36
+ public readonly string sourceLabel;
37
+ public readonly int sequence;
38
+
39
+ public ToolingSignal(string traceId, string sourceLabel, int sequence)
40
+ {
41
+ this.traceId = traceId;
42
+ this.sourceLabel = sourceLabel;
43
+ this.sequence = sequence;
44
+ }
45
+ }
46
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 1a943bdedfd4a05329de004c3bf21f20
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -0,0 +1,53 @@
1
+ # Diagnostics Tooling Exerciser Sample
2
+
3
+ This sample imports a scene that generates deterministic diagnostics data for
4
+ the package editor tools.
5
+
6
+ ## What It Exercises
7
+
8
+ - **Message Monitor**: global history, component diagnostics, typed filters,
9
+ context filters, visible message-type lanes, and visible context lanes.
10
+ - **Flow Graph**: untargeted, targeted, broadcast, exact-source broadcast,
11
+ broadcast-without-source, `RegisterGlobalAcceptAll`, trace IDs, route-kind
12
+ lanes, component lanes, target lanes, context lanes, and route maps.
13
+ - **Inspector overlay**: each receiver is a `MessageAwareComponent` with a live
14
+ `MessagingComponent`, enabled token diagnostics, public counters, and recent
15
+ payload fields.
16
+ - **Project Settings**: the runner enables global diagnostics at play start, so
17
+ Project Settings changes to diagnostics targets and message buffer size are
18
+ visible immediately when the scene is rerun.
19
+
20
+ ## Run It
21
+
22
+ 1. Import **Diagnostics Tooling Exerciser** from the Package Manager Samples tab.
23
+ 1. Open `DiagnosticsToolingExerciser.unity`.
24
+ 1. Press Play. The runner emits a burst of one untargeted pulse, one targeted
25
+ command for each receiver, and one broadcast signal for each source.
26
+ 1. Open **Tools > Wallstop Studios > DxMessaging > Message Monitor**.
27
+ 1. Open **Tools > Wallstop Studios > DxMessaging > Flow Graph**.
28
+ 1. Select `Player Ship`, `Enemy Drone`, and `HUD Console` to inspect local
29
+ diagnostics counters.
30
+
31
+ The runner also exposes context-menu commands:
32
+
33
+ - **Emit One Of Each** sends one untargeted, targeted, and broadcast pass.
34
+ - **Emit Burst** repeats that pass using `burstCount`.
35
+ - Receiver **Reset Counts** clears the inspector counters without changing
36
+ registrations.
37
+
38
+ ## Expected Tool Data
39
+
40
+ After the default play-start burst:
41
+
42
+ - `DiagnosticsToolingExerciser.Sequence` is `3`.
43
+ - Message Monitor global history includes `ToolingPulse`, `ToolingCommand`, and
44
+ `ToolingSignal` entries with trace IDs like `sample-pulse-001`.
45
+ - Flow Graph shows three receiver components, three message types, targeted
46
+ routes to each receiver, exact-source broadcast routes for `Player Ship` and
47
+ `Enemy Drone`, and broadcast-without-source routes for all receivers.
48
+ - The component diagnostics panel shows enabled listener diagnostics and local
49
+ emissions for each receiver.
50
+
51
+ This sample is intentionally small and deterministic. If a tool surface changes,
52
+ update this README, the scene, and
53
+ `DiagnosticsToolingSampleContractTests` together.
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: 83e8290ee4feb017d2c6d73f5f3f6480
3
+ TextScriptImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -0,0 +1,13 @@
1
+ {
2
+ "name": "WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample",
3
+ "rootNamespace": "WallstopStudios.DxMessagingSamples.DiagnosticsToolingExerciser",
4
+ "references": ["WallstopStudios.DxMessaging"],
5
+ "includePlatforms": [],
6
+ "excludePlatforms": [],
7
+ "allowUnsafeCode": false,
8
+ "overrideReferences": false,
9
+ "precompiledReferences": [],
10
+ "autoReferenced": true,
11
+ "defineConstraints": [],
12
+ "noEngineReferences": false
13
+ }
@@ -0,0 +1,7 @@
1
+ fileFormatVersion: 2
2
+ guid: c133c0a50aa52ce1097ea4f2180859ef
3
+ AssemblyDefinitionImporter:
4
+ externalObjects: {}
5
+ userData:
6
+ assetBundleName:
7
+ assetBundleVariant:
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: da9cd5dfa03de0a56243f9f3d51d2758
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
@@ -40,7 +40,7 @@ public class Player : MessageAwareComponent {
40
40
  void Heal(int amount) {
41
41
  health += amount;
42
42
  var healed = new PlayerHealed(amount);
43
- healed.EmitBroadcast(this);
43
+ healed.EmitGameObjectBroadcast(gameObject);
44
44
  // Done! UI, audio, analytics all react automatically.
45
45
  }
46
46
  }
@@ -217,7 +217,7 @@ The Enemy doesn't know (or care) who needs to know about the damage. It just ann
217
217
  ### The Code Flow
218
218
 
219
219
  1. **[Enemy.cs](./Enemy.cs)** detects it took damage
220
- 1. **Enemy** calls: `this.EmitBroadcast(new TookDamage(amount))`
220
+ 1. **Enemy** creates `TookDamage tookDamage = new TookDamage(amount)` and calls `tookDamage.EmitGameObjectBroadcast(gameObject)`
221
221
  1. **UIOverlay** receives it via `RegisterBroadcastWithoutSource`
222
222
  1. **UIOverlay** displays the damage event
223
223
 
@@ -357,7 +357,7 @@ token.RegisterBroadcastWithoutSource<TookDamage>(OnTookDamage);
357
357
 
358
358
  **Use for**: Events that multiple systems care about
359
359
 
360
- **Key characteristic**: Uses `EmitBroadcast` to send messages
360
+ **Key characteristic**: Uses `EmitGameObjectBroadcast(gameObject)` to send messages from its GameObject
361
361
 
362
362
  ### Pattern 4: The Orchestrator (Boot)
363
363
 
@@ -420,7 +420,7 @@ Try modifying the sample:
420
420
  |------------|--------|---------|
421
421
  | Send to everyone | Untargeted | `var paused = new GamePaused(); paused.Emit();` |
422
422
  | Send to specific Component | Targeted | `var heal = new Heal(10); heal.EmitComponentTargeted(playerComponent);` |
423
- | Announce an event | Broadcast | `this.EmitBroadcast(new Exploded())` |
423
+ | Announce an event | Broadcast | `var exploded = new Exploded(); exploded.EmitGameObjectBroadcast(gameObject);` |
424
424
  | Listen to everything | `RegisterBroadcastWithoutSource` | `token.RegisterBroadcastWithoutSource<Damage>(OnDamage)` |
425
425
  | Listen to specific source | `RegisterComponentBroadcast` | `token.RegisterComponentBroadcast<Fire>(weapon, OnFire)` |
426
426
  | Receive targeted messages | `RegisterComponentTargeted` | `token.RegisterComponentTargeted<Heal>(this, OnHeal)` |
@@ -0,0 +1,79 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 200" width="800" height="200" role="img" aria-labelledby="dxmsgBannerTitle" aria-describedby="dxmsgBannerDesc">
2
+ <title id="dxmsgBannerTitle">DxMessaging: decoupled Unity messaging</title>
3
+ <desc id="dxmsgBannerDesc">A DxKit-family amber DxMessaging banner for decoupled, simple Unity systems.</desc>
4
+ <defs>
5
+ <linearGradient id="dxBannerBackground" x1="0" y1="0" x2="800" y2="200" gradientUnits="userSpaceOnUse">
6
+ <stop stop-color="#0d1117"/>
7
+ <stop offset="0.62" stop-color="#10151d"/>
8
+ <stop offset="1" stop-color="#1b1813"/>
9
+ </linearGradient>
10
+ <linearGradient id="dxBannerAmber" x1="40" y1="32" x2="742" y2="164" gradientUnits="userSpaceOnUse">
11
+ <stop stop-color="#ffd48e"/>
12
+ <stop offset="0.48" stop-color="#f4a836"/>
13
+ <stop offset="1" stop-color="#b07d1f"/>
14
+ </linearGradient>
15
+ <filter id="dxBannerSoftShadow" x="-20%" y="-20%" width="140%" height="140%">
16
+ <feDropShadow dx="0" dy="10" stdDeviation="12" flood-color="#000000" flood-opacity="0.32"/>
17
+ </filter>
18
+ </defs>
19
+
20
+ <rect width="800" height="200" fill="url(#dxBannerBackground)"/>
21
+ <path d="M0 150 C112 126 178 170 302 142 C444 110 538 134 800 72 L800 200 L0 200 Z" fill="#f4a836" opacity="0.06"/>
22
+ <path d="M0 38 C154 66 274 28 414 52 C558 78 650 62 800 34" fill="none" stroke="#f4a836" stroke-width="1.2" opacity="0.2"/>
23
+ <path d="M0 58 C168 88 296 48 432 72 C568 96 658 82 800 54" fill="none" stroke="#ffd48e" stroke-width="1.2" opacity="0.12"/>
24
+
25
+ <g transform="translate(34 42)" filter="url(#dxBannerSoftShadow)">
26
+ <polygon points="44,0 82,22 82,66 44,88 6,66 6,22" fill="#0d1117" stroke="#222b36" stroke-width="1.5" stroke-linejoin="round"/>
27
+ <polygon points="44,7 76,25 76,63 44,81 12,63 12,25" fill="none" stroke="url(#dxBannerAmber)" stroke-width="3" stroke-linejoin="round"/>
28
+ <path d="M44 44 L44 18 M44 44 L70 60 M44 44 L18 60" stroke="#ffd48e" stroke-width="2.8" stroke-linecap="round"/>
29
+ <circle cx="44" cy="15" r="4.3" fill="#ffd48e"/>
30
+ <circle cx="74" cy="62" r="4.3" fill="#ffd48e"/>
31
+ <circle cx="14" cy="62" r="4.3" fill="#ffd48e"/>
32
+ <circle cx="44" cy="44" r="7" fill="#ffd48e"/>
33
+ </g>
34
+
35
+ <g transform="translate(132 40)">
36
+ <text x="0" y="0" font-family="'JetBrains Mono', 'SF Mono', monospace" font-size="10" font-weight="700" letter-spacing="0.5" fill="#9aa3af">UNITY &#183; C#</text>
37
+ <text x="0" y="44" font-family="'Space Grotesk', 'IBM Plex Sans', 'Segoe UI', sans-serif" font-size="44" font-weight="700" letter-spacing="0" fill="#e9eef4">DxMessaging</text>
38
+ <text x="0" y="76" font-family="'IBM Plex Sans', 'Segoe UI', sans-serif" font-size="17" font-weight="700" letter-spacing="0" fill="#f4a836">Decoupled, simple systems.</text>
39
+ <text x="0" y="100" font-family="'IBM Plex Sans', 'Segoe UI', sans-serif" font-size="13" font-weight="500" letter-spacing="0" fill="#9aa3af">Typed routes. Managed listeners. Editor visibility.</text>
40
+ </g>
41
+
42
+ <g transform="translate(132 158)" font-family="'IBM Plex Sans', 'Segoe UI', sans-serif" font-size="12" font-weight="800">
43
+ <rect x="0" y="0" width="84" height="28" rx="8" fill="#f4a836"/>
44
+ <text x="42" y="18" text-anchor="middle" fill="#0d1117">Simple</text>
45
+ <rect x="96" y="0" width="58" height="28" rx="8" fill="none" stroke="#4a5462" stroke-width="1.5"/>
46
+ <text x="125" y="18" text-anchor="middle" fill="#c9d1d9">MIT</text>
47
+ <!-- Version text must contain vX.Y.Z for version sync. -->
48
+ <rect x="166" y="0" width="76" height="28" rx="8" fill="#0c1016" stroke="#232c38" stroke-width="1"/>
49
+ <text data-sync="version" x="204" y="18" text-anchor="middle" font-family="'JetBrains Mono', 'SF Mono', monospace" font-size="11" font-weight="800" fill="#e9eef4">v3.2.1</text>
50
+ </g>
51
+
52
+ <g transform="translate(536 40)" filter="url(#dxBannerSoftShadow)">
53
+ <rect x="0" y="0" width="226" height="126" rx="8" fill="#0c1016" stroke="#232c38"/>
54
+ <text x="18" y="26" font-family="'JetBrains Mono', 'SF Mono', monospace" font-size="10" font-weight="800" letter-spacing="0.5" fill="#e9eef4">ONE BUS &#183; THREE ROUTES</text>
55
+ <rect x="18" y="44" width="5" height="68" rx="2.5" fill="url(#dxBannerAmber)"/>
56
+ <g font-family="'IBM Plex Sans', 'Segoe UI', sans-serif" font-size="12" font-weight="700">
57
+ <g>
58
+ <circle cx="32" cy="54" r="4.5" fill="#7fa6d8"/>
59
+ <line x1="40" y1="54" x2="118" y2="54" stroke="#7fa6d8" stroke-width="2" stroke-linecap="round" stroke-dasharray="2 4" opacity="0.75"/>
60
+ <polygon points="120,54 113,50.5 113,57.5" fill="#7fa6d8"/>
61
+ <text x="132" y="58" fill="#7fa6d8">Untargeted</text>
62
+ </g>
63
+ <g>
64
+ <circle cx="32" cy="78" r="4.5" fill="#ec4661"/>
65
+ <line x1="40" y1="78" x2="118" y2="78" stroke="#ec4661" stroke-width="2" stroke-linecap="round" stroke-dasharray="2 4" opacity="0.75"/>
66
+ <polygon points="120,78 113,74.5 113,81.5" fill="#ec4661"/>
67
+ <text x="132" y="82" fill="#ec4661">Targeted</text>
68
+ </g>
69
+ <g>
70
+ <circle cx="32" cy="102" r="4.5" fill="#7fb88a"/>
71
+ <line x1="40" y1="102" x2="118" y2="102" stroke="#7fb88a" stroke-width="2" stroke-linecap="round" stroke-dasharray="2 4" opacity="0.75"/>
72
+ <polygon points="120,102 113,98.5 113,105.5" fill="#7fb88a"/>
73
+ <text x="132" y="106" fill="#7fb88a">Broadcast</text>
74
+ </g>
75
+ </g>
76
+ </g>
77
+
78
+ <text x="762" y="190" text-anchor="end" font-family="'IBM Plex Sans', 'Segoe UI', sans-serif" font-size="10" font-weight="700" letter-spacing="0" fill="#6b7480">Wallstop Studios</text>
79
+ </svg>
@@ -0,0 +1,53 @@
1
+ fileFormatVersion: 2
2
+ guid: 4c1ba6b3e8994dc41b8264e9001eb49f
3
+ ScriptedImporter:
4
+ internalIDToNameTable: []
5
+ externalObjects: {}
6
+ serializedVersion: 2
7
+ userData:
8
+ assetBundleName:
9
+ assetBundleVariant:
10
+ script: {fileID: 12408, guid: 0000000000000000e000000000000000, type: 0}
11
+ svgType: 3
12
+ texturedSpriteMeshType: 0
13
+ svgPixelsPerUnit: 100
14
+ gradientResolution: 64
15
+ alignment: 0
16
+ customPivot: {x: 0, y: 0}
17
+ generatePhysicsShape: 0
18
+ viewportOptions: 0
19
+ preserveViewport: 0
20
+ advancedMode: 0
21
+ tessellationMode: 1
22
+ predefinedResolutionIndex: 1
23
+ targetResolution: 1080
24
+ resolutionMultiplier: 1
25
+ stepDistance: 10
26
+ samplingStepDistance: 100
27
+ maxCordDeviationEnabled: 0
28
+ maxCordDeviation: 1
29
+ maxTangentAngleEnabled: 0
30
+ maxTangentAngle: 5
31
+ keepTextureAspectRatio: 1
32
+ textureSize: 256
33
+ textureWidth: 256
34
+ textureHeight: 256
35
+ wrapMode: 0
36
+ filterMode: 1
37
+ sampleCount: 4
38
+ preserveSVGImageAspect: 0
39
+ useSVGPixelsPerUnit: 0
40
+ spriteData:
41
+ TessellationDetail: 0
42
+ SpriteName:
43
+ SpritePivot: {x: 0, y: 0}
44
+ SpriteAlignment: 0
45
+ SpriteBorder: {x: 0, y: 0, z: 0, w: 0}
46
+ SpriteRect:
47
+ serializedVersion: 2
48
+ x: 0
49
+ y: 0
50
+ width: 0
51
+ height: 0
52
+ SpriteID:
53
+ PhysicsOutlines: []
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: aba5d56721c01744b8bd42e41253da83
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
package/docs.meta ADDED
@@ -0,0 +1,8 @@
1
+ fileFormatVersion: 2
2
+ guid: 1018165ed29202b4c9ae719674cbbb61
3
+ folderAsset: yes
4
+ DefaultImporter:
5
+ externalObjects: {}
6
+ userData:
7
+ assetBundleName:
8
+ assetBundleVariant:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.dxmessaging",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "displayName": "DxMessaging",
5
5
  "description": "Synchronous Event Bus for Unity",
6
6
  "unity": "2021.3",
@@ -45,6 +45,10 @@
45
45
  "SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.meta",
46
46
  "CHANGELOG.md",
47
47
  "CHANGELOG.md.meta",
48
+ "docs.meta",
49
+ "docs/images.meta",
50
+ "docs/images/DxMessaging-banner.svg",
51
+ "docs/images/DxMessaging-banner.svg.meta",
48
52
  "LICENSE.md",
49
53
  "LICENSE.md.meta",
50
54
  "README.md",
@@ -61,7 +65,7 @@
61
65
  "format": "prettier --write \"**/*.{md,markdown,json,asmdef,asmref,yml,yaml}\"",
62
66
  "format:check": "prettier --check \"**/*.{md,markdown,json,asmdef,asmref,yml,yaml}\"",
63
67
  "lint:markdown": "markdownlint-cli2 \"**/*.md\" \"**/*.markdown\"",
64
- "check:spelling": "cspell --no-progress --no-summary \"**/*.{md,markdown,cs,json,yml,yaml,ps1,js}\"",
68
+ "check:spelling": "cspell --no-progress --no-summary .",
65
69
  "sync:banner": "node scripts/sync-banner-version.js",
66
70
  "check:banner": "node scripts/sync-banner-version.js --check",
67
71
  "update:llms-txt": "node scripts/update-llms-txt.js",
@@ -82,8 +86,8 @@
82
86
  },
83
87
  "devDependencies": {
84
88
  "cspell": "10.0.1",
85
- "markdownlint-cli2": "0.22.1",
86
- "prettier": "3.9.3"
89
+ "markdownlint-cli2": "0.23.0",
90
+ "prettier": "3.9.4"
87
91
  },
88
92
  "samples": [
89
93
  {
@@ -96,6 +100,11 @@
96
100
  "description": "UI-driven message emissions and a global observer demonstrating inspector diagnostics and RegisterGlobalAcceptAll.",
97
101
  "path": "Samples~/UI Buttons + Inspector"
98
102
  },
103
+ {
104
+ "displayName": "Diagnostics Tooling Exerciser",
105
+ "description": "Deterministic scene that drives Message Monitor, Flow Graph, Inspector diagnostics, and Project Settings with all DxMessaging route kinds.",
106
+ "path": "Samples~/Diagnostics Tooling Exerciser"
107
+ },
99
108
  {
100
109
  "displayName": "Dependency Injection",
101
110
  "description": "Integration samples for Zenject, VContainer, and Reflex showing IMessageRegistrationBuilder usage with container lifecycles.",