com.wallstop-studios.dxmessaging 3.1.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.
- package/CHANGELOG.md +326 -0
- package/Editor/Analyzers/BaseCallLogMessageParser.cs.meta +3 -3
- package/Editor/Analyzers/BaseCallReportAggregator.cs.meta +3 -3
- package/Editor/Analyzers/DxMessagingConsoleHarvester.cs +8 -8
- package/Editor/Analyzers/DxMessagingConsoleHarvester.cs.meta +3 -3
- package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs +171 -13
- package/Editor/CustomEditors/MessageAwareComponentFallbackEditor.cs.meta +3 -3
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs +391 -96
- package/Editor/CustomEditors/MessageAwareComponentInspectorOverlay.cs.meta +3 -3
- package/Editor/CustomEditors/MessageAwareComponentInspectorView.cs +279 -0
- package/Editor/CustomEditors/MessageAwareComponentInspectorView.cs.meta +11 -0
- package/Editor/DxMessagingEditorPalette.cs +66 -0
- package/Editor/DxMessagingEditorPalette.cs.meta +11 -0
- package/Editor/DxMessagingEditorTheme.cs +200 -0
- package/Editor/DxMessagingEditorTheme.cs.meta +11 -0
- package/Editor/DxMessagingMenu.cs.meta +3 -3
- package/Editor/DxMessagingSceneBuildProcessor.cs.meta +3 -3
- package/Editor/Icons/dxmessaging-icon-256.png +0 -0
- package/Editor/Icons/dxmessaging-icon-256.png.meta +156 -0
- package/Editor/Icons/dxmessaging-icon-32.png +0 -0
- package/Editor/Icons/dxmessaging-icon-32.png.meta +156 -0
- package/Editor/Icons/dxmessaging-icon-48.png +0 -0
- package/Editor/Icons/dxmessaging-icon-48.png.meta +156 -0
- package/Editor/Icons.meta +8 -0
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs +2 -3
- package/Editor/Settings/DxMessagingBaseCallIgnoreSync.cs.meta +3 -3
- package/Editor/Settings/DxMessagingSettingsProvider.cs +368 -33
- package/Editor/SetupCscRsp.cs +232 -163
- package/Editor/Testing/MessagingComponentEditorHarness.cs +11 -4
- package/Editor/Theme/DxMessagingTheme.uss +255 -0
- package/Editor/Theme/DxMessagingTheme.uss.meta +11 -0
- package/Editor/Theme/DxTokens.uss +90 -0
- package/Editor/Theme/DxTokens.uss.meta +11 -0
- package/Editor/Theme.meta +8 -0
- package/Editor/Windows/DxMessagingFlowGraphWindow.cs +5513 -0
- package/Editor/Windows/DxMessagingFlowGraphWindow.cs.meta +11 -0
- package/Editor/Windows/DxMessagingMessageMonitorWindow.cs +2288 -0
- package/Editor/Windows/DxMessagingMessageMonitorWindow.cs.meta +11 -0
- package/Editor/Windows.meta +8 -0
- package/README.md +84 -35
- package/Runtime/Analyzers.meta +8 -0
- package/Runtime/AssemblyInfo.cs +1 -0
- package/Runtime/Core/Attributes/DxIgnoreMissingBaseCallAttribute.cs.meta +3 -3
- package/Runtime/Core/Diagnostics/MessageEmissionData.cs +29 -1
- package/Runtime/Core/DxMessagingStaticState.cs.meta +3 -3
- package/Runtime/Core/Extensions/MessageBusExtensions.cs.meta +3 -3
- package/Runtime/Core/Extensions/MessageExtensions.cs +4 -5
- package/Runtime/Core/Extensions/MessageExtensions.cs.meta +3 -3
- package/Runtime/Core/Helper/MessageCache.cs +56 -23
- package/Runtime/Core/IMessage.cs.meta +3 -3
- package/Runtime/Core/InstanceId.cs.meta +3 -3
- package/Runtime/Core/Internal/FlatDispatch.cs +32 -0
- package/Runtime/Core/Internal/TypedSlots.cs +45 -7
- package/Runtime/Core/MessageBus/DiagnosticsTarget.cs.meta +3 -3
- package/Runtime/Core/MessageBus/GlobalMessageBusProvider.cs.meta +3 -3
- package/Runtime/Core/MessageBus/IMessageBus.cs +63 -28
- package/Runtime/Core/MessageBus/IMessageBus.cs.meta +3 -3
- package/Runtime/Core/MessageBus/IMessageBusProvider.cs.meta +3 -3
- package/Runtime/Core/MessageBus/IMessageRegistrationBuilder.cs.meta +3 -3
- package/Runtime/Core/MessageBus/MessageBus.cs +1135 -626
- package/Runtime/Core/MessageBus/MessageBus.cs.meta +3 -3
- package/Runtime/Core/MessageBus/MessageBusRebindMode.cs.meta +3 -3
- package/Runtime/Core/MessageBus/MessageBusRegistration.cs +207 -0
- package/Runtime/Core/MessageBus/MessageBusRegistration.cs.meta +11 -0
- package/Runtime/Core/MessageBus/MessageRegistrationBuilder.cs.meta +3 -3
- package/Runtime/Core/MessageBus/MessagingRegistration.cs.meta +3 -3
- package/Runtime/Core/MessageBus/RegistrationLog.cs +25 -12
- package/Runtime/Core/MessageBus/RegistrationLog.cs.meta +3 -3
- package/Runtime/Core/MessageHandler.cs +1886 -1082
- package/Runtime/Core/MessageHandler.cs.meta +3 -3
- package/Runtime/Core/MessageRegistrationHandle.cs +19 -5
- package/Runtime/Core/MessageRegistrationHandle.cs.meta +3 -3
- package/Runtime/Core/MessageRegistrationToken.cs +1932 -895
- package/Runtime/Core/MessageRegistrationToken.cs.meta +3 -3
- package/Runtime/Core/Messages/IBroadcastMessage.cs.meta +3 -3
- package/Runtime/Core/Messages/ITargetedMessage.cs.meta +3 -3
- package/Runtime/Core/Messages/IUntargetedMessage.cs.meta +3 -3
- package/Runtime/Core/Messages/SourcedStringMessage.cs.meta +3 -3
- package/Runtime/Core/MessagingDebug.cs.meta +3 -3
- package/Runtime/Unity/CurrentGlobalMessageBusProvider.cs.meta +3 -3
- package/Runtime/Unity/DxMessagingRuntimeInitializer.cs.meta +3 -3
- package/Runtime/Unity/InitialGlobalMessageBusProvider.cs.meta +3 -3
- package/Runtime/Unity/Integrations/Reflex/ReflexRegistrationInstaller.cs.meta +3 -3
- package/Runtime/Unity/Integrations/VContainer/VContainerRegistrationExtensions.cs.meta +3 -3
- package/Runtime/Unity/Integrations/Zenject/ZenjectRegistrationInstaller.cs.meta +3 -3
- package/Runtime/Unity/MessageAwareComponent.cs.meta +3 -3
- package/Runtime/Unity/MessageBusProviderHandle.cs.meta +3 -3
- package/Runtime/Unity/MessagingComponent.cs.meta +3 -3
- package/Runtime/Unity/MessagingComponentInstaller.cs.meta +3 -3
- package/Runtime/Unity/ScriptableMessageBusProvider.cs.meta +3 -3
- package/Samples~/DI/Reflex/SampleInstaller.cs.meta +3 -3
- package/Samples~/DI/VContainer/SampleLifetimeScope.cs.meta +3 -3
- package/Samples~/DI/Zenject/SampleInstaller.cs.meta +3 -3
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.cs +173 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.cs.meta +11 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.unity +424 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingExerciser.unity.meta +7 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingReceiver.cs +185 -0
- package/Samples~/Diagnostics Tooling Exerciser/DiagnosticsToolingReceiver.cs.meta +11 -0
- package/Samples~/Diagnostics Tooling Exerciser/Messages.cs +46 -0
- package/Samples~/Diagnostics Tooling Exerciser/Messages.cs.meta +11 -0
- package/Samples~/Diagnostics Tooling Exerciser/README.md +53 -0
- package/Samples~/Diagnostics Tooling Exerciser/README.md.meta +7 -0
- package/Samples~/Diagnostics Tooling Exerciser/WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample.asmdef +13 -0
- package/Samples~/Diagnostics Tooling Exerciser/WallstopStudios.DxMessaging.DiagnosticsToolingExerciser.Sample.asmdef.meta +7 -0
- package/Samples~/Diagnostics Tooling Exerciser.meta +8 -0
- package/Samples~/Mini Combat/Boot.cs.meta +3 -3
- package/Samples~/Mini Combat/Enemy.cs.meta +3 -3
- package/Samples~/Mini Combat/Messages.cs.meta +3 -3
- package/Samples~/Mini Combat/Player.cs.meta +3 -3
- package/Samples~/Mini Combat/README.md +1 -1
- package/Samples~/Mini Combat/UIOverlay.cs.meta +3 -3
- package/Samples~/Mini Combat/Walkthrough.md +3 -3
- package/Samples~/UI Buttons + Inspector/DiagnosticsEnabler.cs.meta +3 -3
- package/Samples~/UI Buttons + Inspector/Messages.cs.meta +3 -3
- package/Samples~/UI Buttons + Inspector/MessagingObserver.cs.meta +3 -3
- package/Samples~/UI Buttons + Inspector/UIButtonEmitter.cs.meta +3 -3
- package/SourceGenerators/Directory.Build.props +5 -5
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/DxAutoConstructorGenerator.cs.meta +3 -3
- package/SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators/WallstopStudios.DxMessaging.SourceGenerators.csproj +12 -11
- package/docs/images/DxMessaging-banner.svg +79 -0
- package/docs/images/DxMessaging-banner.svg.meta +53 -0
- package/docs/images.meta +8 -0
- package/docs.meta +8 -0
- package/package.json +17 -5
- /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.CSharp.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.CSharp.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/Microsoft.CodeAnalysis.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Collections.Immutable.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Collections.Immutable.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Reflection.Metadata.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Reflection.Metadata.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Runtime.CompilerServices.Unsafe.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/System.Runtime.CompilerServices.Unsafe.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.Analyzer.dll.meta +0 -0
- /package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll +0 -0
- /package/{Editor → Runtime}/Analyzers/WallstopStudios.DxMessaging.SourceGenerators.dll.meta +0 -0
package/README.md
CHANGED
|
@@ -1,31 +1,37 @@
|
|
|
1
|
-
# DxMessaging
|
|
1
|
+
# DxMessaging
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
|
-
<img src="docs/images/DxMessaging-banner.svg" alt="DxMessaging -
|
|
4
|
+
<img src="docs/images/DxMessaging-banner.svg" alt="DxMessaging - Decoupled, simple systems for Unity" width="800"/>
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<a href="https://ambiguous-interactive.github.io/DxMessaging/">
|
|
9
|
-
<img src="https://img.shields.io/badge/
|
|
9
|
+
<img src="https://img.shields.io/badge/Docs-ambiguous--interactive.github.io-f4a836?style=for-the-badge" alt="Documentation" />
|
|
10
10
|
</a>
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
13
|
[](https://unity.com/releases/editor/archive)<br/>
|
|
14
|
-
[](LICENSE.md)<br/>
|
|
15
15
|
[](https://openupm.com/packages/com.wallstop-studios.dxmessaging/)<br/>
|
|
16
16
|
[](https://www.npmjs.com/package/com.wallstop-studios.dxmessaging)<br/>
|
|
17
|
-
[-
|
|
17
|
+
[-f4a836.svg>)](docs/architecture/performance.md)<br/>
|
|
18
18
|
[](https://github.com/Ambiguous-Interactive/DxMessaging/actions/workflows/markdown-link-validity.yml)
|
|
19
19
|
|
|
20
|
-
>
|
|
20
|
+
> **AI Assistance Disclosure:**
|
|
21
21
|
>
|
|
22
22
|
> This project has been actively developed and maintained by human authors for over a decade. Recent versions have utilized AI assistance for documentation, test coverage, and performance optimizations.
|
|
23
23
|
|
|
24
|
-
**DxMessaging is a type-safe
|
|
24
|
+
**DxMessaging is a synchronous, type-safe Unity message bus for decoupled, simple systems.** It replaces sprawling C# events, brittle UnityEvents, and global static event buses with explicit message contracts, lifecycle-managed registrations, and editor-visible routing.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
Use it when one system needs to announce a fact, command a target, or broadcast from a source without keeping a direct scene reference to the receiver.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
```bash
|
|
29
|
+
openupm add com.wallstop-studios.dxmessaging
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The core taxonomy is small: **Untargeted** announcements, **Targeted** commands, and **Broadcast** facts from a source. Diagnostics are built around that model: Message Monitor shows recent emissions and filters, Flow Graph shows registration topology and trace evidence, and the Inspector overlay catches `MessageAwareComponent` lifecycle mistakes.
|
|
33
|
+
|
|
34
|
+
See the [Install Guide](docs/getting-started/install.md) for Git URL, scoped registry, and release tarball options.
|
|
29
35
|
|
|
30
36
|
## Table of Contents
|
|
31
37
|
|
|
@@ -605,38 +611,79 @@ void OnDamage(ref TookDamage msg) {
|
|
|
605
611
|
- Block messages during cutscenes
|
|
606
612
|
- Log/audit sensitive actions
|
|
607
613
|
|
|
608
|
-
### Built-in
|
|
614
|
+
### Built-in Editor Diagnostics
|
|
609
615
|
|
|
610
616
|
**The problem with normal events:** "Which event fired? When? Who handled it? In what order?" = unknown
|
|
611
617
|
|
|
612
|
-
**DxMessaging solution:**
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
-
|
|
621
|
-
|
|
622
|
-
-
|
|
623
|
-
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
618
|
+
**DxMessaging solution:** turn on diagnostics in the Inspector or Project Settings, then use the
|
|
619
|
+
dedicated Unity editor tools under **Tools > Wallstop Studios > DxMessaging**.
|
|
620
|
+
|
|
621
|
+
#### Message Monitor
|
|
622
|
+
|
|
623
|
+
- Recent global-bus emissions, most-recent first
|
|
624
|
+
- Message type, context, and stack trace details
|
|
625
|
+
- Plain text filtering, `type:` / `message:` / `context:` / `stack:` field
|
|
626
|
+
filters, an active-filter summary with Clear, and Copy JSON export
|
|
627
|
+
- Visible message-type lanes showing per-filter entry counts, context breadth,
|
|
628
|
+
and message-volume share, plus context lanes showing context volume and
|
|
629
|
+
message breadth, with row-level Filter shortcuts and exact quoted context
|
|
630
|
+
shortcuts
|
|
631
|
+
- Loaded-scene `MessagingComponent` diagnostics, including listener counts,
|
|
632
|
+
registrations, calls, local messages, and provider warnings
|
|
633
|
+
|
|
634
|
+
#### Flow Graph
|
|
635
|
+
|
|
636
|
+
- Component nodes, message-type nodes, and registration edges
|
|
637
|
+
- Route-map route-kind mix, call shares, widest-message target-component
|
|
638
|
+
fan-out, most-routed target, inactive routed-target, hottest-route, and
|
|
639
|
+
no-call route summaries, recent traced-route coverage, busiest traced-route,
|
|
640
|
+
traced-message, and traced-target share, visible message lanes grouped by
|
|
641
|
+
message type, visible target lanes grouped by target component, visible trace
|
|
642
|
+
route-kind lanes grouped by traced registration kind, visible trace message
|
|
643
|
+
lanes grouped by traced message type, visible trace target lanes grouped by
|
|
644
|
+
traced target component, visible trace-id lanes grouped by positive trace id,
|
|
645
|
+
visible trace context lanes grouped by normalized context, visible trace
|
|
646
|
+
context volume and share, visible trace-id
|
|
647
|
+
breadth, visible trace-target/path concentration, selected
|
|
648
|
+
component/message route-health and busiest traced-route details, selected
|
|
649
|
+
component busiest traced-message details, selected message busiest
|
|
650
|
+
traced-target details, selected
|
|
651
|
+
component/message/route visible traced-share details, and selected
|
|
652
|
+
component/message/route trace context volume, trace context delivery,
|
|
653
|
+
busiest-context-share, trace-id breadth, selected component trace-message,
|
|
654
|
+
selected message trace-target, busiest-path, and busiest-path-share details
|
|
655
|
+
- Recent global/listener emission evidence
|
|
656
|
+
- Exact recent traced delivery counts per registration edge
|
|
657
|
+
- Recent trace-path/context aggregates, including busiest trace context share,
|
|
658
|
+
busiest trace message/target/path shares, visible flow corridors by
|
|
659
|
+
message/target pair, visible trace route-kind lanes by traced registration
|
|
660
|
+
kind, visible trace message lanes by traced message type, visible trace target
|
|
661
|
+
lanes by traced target component, visible trace context lanes by normalized
|
|
662
|
+
context, visible trace-id lanes by positive trace id, widest visible trace id
|
|
663
|
+
by path count, and exact trace-id export arrays when diagnostics capture token
|
|
664
|
+
delivery records with positive trace ids
|
|
665
|
+
|
|
666
|
+
#### Inspector integration
|
|
667
|
+
|
|
668
|
+
Click any `MessagingComponent` in the Inspector for component-local diagnostics
|
|
669
|
+
and any `MessageAwareComponent` subclass for base-call warning surfaces.
|
|
630
670
|
|
|
631
671
|
#### Real-world debugging scenarios
|
|
632
672
|
|
|
633
|
-
- "Did my message fire?" -> Check
|
|
634
|
-
- "Why didn't my handler run?" -> Check registrations
|
|
635
|
-
- "What's firing too often?" ->
|
|
636
|
-
- "
|
|
673
|
+
- "Did my message fire?" -> Check Message Monitor history.
|
|
674
|
+
- "Why didn't my handler run?" -> Check registrations and Flow Graph edges.
|
|
675
|
+
- "What's firing too often?" -> Compare call counts in component and route summaries.
|
|
676
|
+
- "Which source/target context was involved?" -> Check Message Monitor context
|
|
677
|
+
and Flow Graph trace paths.
|
|
637
678
|
|
|
638
679
|
**No more:** Setting 50 breakpoints and stepping through code for 30 minutes.
|
|
639
680
|
|
|
681
|
+
See [Diagnostics](docs/guides/diagnostics.md) for the current editor tooling and
|
|
682
|
+
trace-path semantics. The
|
|
683
|
+
[Diagnostics Tooling Exerciser](Samples~/Diagnostics%20Tooling%20Exerciser/README.md)
|
|
684
|
+
sample imports a deterministic scene that drives Message Monitor, Flow Graph,
|
|
685
|
+
Inspector diagnostics, and Project Settings together.
|
|
686
|
+
|
|
640
687
|
### Local Bus Islands for Testing
|
|
641
688
|
|
|
642
689
|
**The problem with normal events:** Global static events contaminate tests. Mock complexity. Flaky tests.
|
|
@@ -654,8 +701,9 @@ public void TestAchievementSystem() {
|
|
|
654
701
|
// Test in isolation
|
|
655
702
|
_ = token.RegisterBroadcastWithoutSource<EnemyKilled>(achievements.OnKill);
|
|
656
703
|
|
|
704
|
+
var gameObject = new GameObject();
|
|
657
705
|
var msg = new EnemyKilled("Boss");
|
|
658
|
-
msg.EmitGameObjectBroadcast(
|
|
706
|
+
msg.EmitGameObjectBroadcast(gameObject, testBus); // Only this test sees it
|
|
659
707
|
|
|
660
708
|
Assert.IsTrue(achievements.Unlocked("BossSlayer"));
|
|
661
709
|
}
|
|
@@ -693,7 +741,7 @@ public void TestAchievementSystem() {
|
|
|
693
741
|
|
|
694
742
|
- [Unity Integration](docs/guides/unity-integration.md) -- MessagingComponent deep dive
|
|
695
743
|
- [Targeting & Context](docs/concepts/targeting-and-context.md) -- GameObject vs Component
|
|
696
|
-
- [Diagnostics](docs/guides/diagnostics.md) --
|
|
744
|
+
- [Diagnostics](docs/guides/diagnostics.md) -- editor tools, traces, and debugging
|
|
697
745
|
- [Memory Reclamation](docs/guides/memory-reclamation.md) -- idle eviction, explicit Trim, and tuning the runtime settings asset
|
|
698
746
|
|
|
699
747
|
Important: Inheritance with MessageAwareComponent
|
|
@@ -872,6 +920,7 @@ Import samples from Package Manager:
|
|
|
872
920
|
|
|
873
921
|
- **[Mini Combat](Samples~/Mini%20Combat/README.md)** -- Simple combat with Heal/Damage messages
|
|
874
922
|
- **[UI Buttons + Inspector](Samples~/UI%20Buttons%20%2B%20Inspector/README.md)** -- Interactive diagnostics demo
|
|
923
|
+
- **[Diagnostics Tooling Exerciser](Samples~/Diagnostics%20Tooling%20Exerciser/README.md)** -- Deterministic scene for Message Monitor, Flow Graph, Inspector diagnostics, and Project Settings
|
|
875
924
|
|
|
876
925
|
## Requirements
|
|
877
926
|
|
|
@@ -908,7 +957,7 @@ DxMessaging publishes machine-readable context for AI agents through [llms.txt](
|
|
|
908
957
|
|
|
909
958
|
- **[llms.txt](llms.txt)** -- Complete project overview, API reference, and context in a single file
|
|
910
959
|
- **[Repository Guidelines](.llm/context.md)** -- Coding standards and development workflows
|
|
911
|
-
- **[AI Agent Skills](.llm/skills/)** --
|
|
960
|
+
- **[AI Agent Skills](.llm/skills/)** -- 159+ specialized skill documents covering documentation, testing, GitHub Actions, and more
|
|
912
961
|
|
|
913
962
|
The `llms.txt` file is automatically updated via CI/CD to stay current with project changes. It includes:
|
|
914
963
|
|
package/Runtime/AssemblyInfo.cs
CHANGED
|
@@ -14,3 +14,4 @@ using System.Runtime.CompilerServices;
|
|
|
14
14
|
[assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.Runtime.Zenject")]
|
|
15
15
|
[assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.Editor")]
|
|
16
16
|
[assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.Editor.Allocations")]
|
|
17
|
+
[assembly: InternalsVisibleTo("WallstopStudios.DxMessaging.Tests.00.Runtime.Benchmarks")]
|
|
@@ -17,7 +17,9 @@ namespace DxMessaging.Core.Diagnostics
|
|
|
17
17
|
/// that excludes DxMessaging internals for easier debugging.
|
|
18
18
|
///
|
|
19
19
|
/// The <see cref="context"/> contains the relevant <see cref="InstanceId"/> for targeted/broadcast messages
|
|
20
|
-
/// (target or source respectively) and is null for untargeted messages.
|
|
20
|
+
/// (target or source respectively) and is null for untargeted messages. Runtime records emitted by a
|
|
21
|
+
/// <see cref="MessageBus.MessageBus"/> also carry a <see cref="traceId"/> that token-local delivery records can
|
|
22
|
+
/// use to join a bus emission to the registrations that observed it.
|
|
21
23
|
/// </remarks>
|
|
22
24
|
public readonly struct MessageEmissionData
|
|
23
25
|
{
|
|
@@ -33,15 +35,41 @@ namespace DxMessaging.Core.Diagnostics
|
|
|
33
35
|
/// <summary>Trimmed stack trace captured at the emission site.</summary>
|
|
34
36
|
public readonly string stackTrace;
|
|
35
37
|
|
|
38
|
+
/// <summary>
|
|
39
|
+
/// Dispatch trace identifier shared by bus-side emission records and token-side delivery records.
|
|
40
|
+
/// </summary>
|
|
41
|
+
public readonly long traceId;
|
|
42
|
+
|
|
43
|
+
/// <summary>
|
|
44
|
+
/// Registration handle that observed this message; default for bus-side emission records.
|
|
45
|
+
/// </summary>
|
|
46
|
+
public readonly MessageRegistrationHandle registrationHandle;
|
|
47
|
+
|
|
36
48
|
/// <summary>
|
|
37
49
|
/// Creates a new diagnostic record for an emitted message.
|
|
38
50
|
/// </summary>
|
|
39
51
|
/// <param name="message">The message that was emitted.</param>
|
|
40
52
|
/// <param name="context">Target or source depending on message category; null for untargeted.</param>
|
|
41
53
|
public MessageEmissionData(IMessage message, InstanceId? context = null)
|
|
54
|
+
: this(message, context, traceId: 0, registrationHandle: default) { }
|
|
55
|
+
|
|
56
|
+
internal MessageEmissionData(IMessage message, long traceId)
|
|
57
|
+
: this(message, context: null, traceId, registrationHandle: default) { }
|
|
58
|
+
|
|
59
|
+
internal MessageEmissionData(IMessage message, InstanceId? context, long traceId)
|
|
60
|
+
: this(message, context, traceId, registrationHandle: default) { }
|
|
61
|
+
|
|
62
|
+
internal MessageEmissionData(
|
|
63
|
+
IMessage message,
|
|
64
|
+
InstanceId? context,
|
|
65
|
+
long traceId,
|
|
66
|
+
MessageRegistrationHandle registrationHandle
|
|
67
|
+
)
|
|
42
68
|
{
|
|
43
69
|
this.message = message;
|
|
44
70
|
this.context = context;
|
|
71
|
+
this.traceId = traceId;
|
|
72
|
+
this.registrationHandle = registrationHandle;
|
|
45
73
|
stackTrace = GetAccurateStackTrace();
|
|
46
74
|
}
|
|
47
75
|
|
|
@@ -23,10 +23,9 @@ namespace DxMessaging.Core.Extensions
|
|
|
23
23
|
/// var heal = new Heal(10);
|
|
24
24
|
/// heal.EmitTargeted(target);
|
|
25
25
|
///
|
|
26
|
-
/// // Broadcast (from
|
|
27
|
-
/// var source = (DxMessaging.Core.InstanceId)gameObject;
|
|
26
|
+
/// // Broadcast (from this GameObject)
|
|
28
27
|
/// var dmg = new TookDamage(5);
|
|
29
|
-
/// dmg.
|
|
28
|
+
/// dmg.EmitGameObjectBroadcast(gameObject);
|
|
30
29
|
///
|
|
31
30
|
/// // Unity conveniences
|
|
32
31
|
/// var hello = new StringMessage("Hello");
|
|
@@ -334,11 +333,11 @@ namespace DxMessaging.Core.Extensions
|
|
|
334
333
|
/// public readonly partial struct TookDamage { public readonly int amount; }
|
|
335
334
|
///
|
|
336
335
|
/// var dmg = new TookDamage(5);
|
|
337
|
-
/// dmg.EmitFrom((InstanceId)gameObject); // OK: from GameObject
|
|
338
336
|
/// dmg.EmitGameObjectBroadcast(gameObject); // explicit, preferred in Unity code
|
|
337
|
+
/// dmg.EmitFrom(gameObject); // shorthand from the same GameObject
|
|
339
338
|
///
|
|
340
339
|
/// // Pitfall: identifies the Component as source (won't match GO-source registrations)
|
|
341
|
-
/// dmg.
|
|
340
|
+
/// dmg.EmitComponentBroadcast(this);
|
|
342
341
|
/// </code>
|
|
343
342
|
/// </example>
|
|
344
343
|
public static void EmitFrom<TMessage>(
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
namespace DxMessaging.Core.Helper
|
|
2
2
|
{
|
|
3
|
+
using System;
|
|
3
4
|
using System.Collections;
|
|
4
5
|
using System.Collections.Generic;
|
|
5
6
|
using System.Runtime.CompilerServices;
|
|
@@ -8,7 +9,7 @@ namespace DxMessaging.Core.Helper
|
|
|
8
9
|
/// Sparse, type-indexed cache keyed by message type for fast lookups without dictionaries.
|
|
9
10
|
/// </summary>
|
|
10
11
|
/// <remarks>
|
|
11
|
-
/// Internally maintains a
|
|
12
|
+
/// Internally maintains a sparse array indexed by a compact, per-message-type integer (assigned via
|
|
12
13
|
/// <see cref="MessageHelperIndexer{TMessage}"/>). Used heavily by the bus to store handlers and interceptors
|
|
13
14
|
/// with minimal overhead.
|
|
14
15
|
/// </remarks>
|
|
@@ -39,8 +40,8 @@ namespace DxMessaging.Core.Helper
|
|
|
39
40
|
/// <returns><c>true</c> if another non-null value exists; otherwise <c>false</c>.</returns>
|
|
40
41
|
public bool MoveNext()
|
|
41
42
|
{
|
|
42
|
-
|
|
43
|
-
int count =
|
|
43
|
+
TValue[] values = _cache._values;
|
|
44
|
+
int count = _cache._count;
|
|
44
45
|
while (++_index < count)
|
|
45
46
|
{
|
|
46
47
|
_current = values[_index];
|
|
@@ -74,7 +75,8 @@ namespace DxMessaging.Core.Helper
|
|
|
74
75
|
public void Dispose() { }
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
private
|
|
78
|
+
private TValue[] _values = Array.Empty<TValue>();
|
|
79
|
+
private int _count;
|
|
78
80
|
|
|
79
81
|
/// <summary>
|
|
80
82
|
/// Retrieves the value associated with <typeparamref name="TMessage"/>, creating one if needed.
|
|
@@ -89,7 +91,7 @@ namespace DxMessaging.Core.Helper
|
|
|
89
91
|
int index = MessageHelperIndexer<TMessage>.SequentialId;
|
|
90
92
|
if (0 <= index)
|
|
91
93
|
{
|
|
92
|
-
|
|
94
|
+
EnsureIndex(index);
|
|
93
95
|
value = _values[index];
|
|
94
96
|
if (value != null)
|
|
95
97
|
{
|
|
@@ -101,11 +103,9 @@ namespace DxMessaging.Core.Helper
|
|
|
101
103
|
}
|
|
102
104
|
else
|
|
103
105
|
{
|
|
104
|
-
index =
|
|
105
|
-
MessageHelperIndexer<TMessage>.SequentialId = index;
|
|
106
|
-
FillToIndex(index - 1);
|
|
106
|
+
index = AssignIndex<TMessage>();
|
|
107
107
|
value = new TValue();
|
|
108
|
-
_values
|
|
108
|
+
_values[index] = value;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
111
|
return value;
|
|
@@ -123,15 +123,13 @@ namespace DxMessaging.Core.Helper
|
|
|
123
123
|
int index = MessageHelperIndexer<TMessage>.SequentialId;
|
|
124
124
|
if (0 <= index)
|
|
125
125
|
{
|
|
126
|
-
|
|
126
|
+
EnsureIndex(index);
|
|
127
127
|
_values[index] = value;
|
|
128
128
|
return;
|
|
129
129
|
}
|
|
130
130
|
|
|
131
|
-
index =
|
|
132
|
-
|
|
133
|
-
FillToIndex(index - 1);
|
|
134
|
-
_values.Add(value);
|
|
131
|
+
index = AssignIndex<TMessage>();
|
|
132
|
+
_values[index] = value;
|
|
135
133
|
}
|
|
136
134
|
|
|
137
135
|
/// <summary>
|
|
@@ -145,7 +143,7 @@ namespace DxMessaging.Core.Helper
|
|
|
145
143
|
where TMessage : IMessage
|
|
146
144
|
{
|
|
147
145
|
int index = MessageHelperIndexer<TMessage>.SequentialId;
|
|
148
|
-
if (0 <= index && index < _values.
|
|
146
|
+
if (0 <= index && index < _values.Length)
|
|
149
147
|
{
|
|
150
148
|
value = _values[index];
|
|
151
149
|
return value != null;
|
|
@@ -164,7 +162,7 @@ namespace DxMessaging.Core.Helper
|
|
|
164
162
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
165
163
|
internal bool TryGetValueAtIndex(int index, out TValue value)
|
|
166
164
|
{
|
|
167
|
-
if (0 <= index && index < _values.
|
|
165
|
+
if (0 <= index && index < _values.Length)
|
|
168
166
|
{
|
|
169
167
|
value = _values[index];
|
|
170
168
|
return value != null;
|
|
@@ -183,7 +181,7 @@ namespace DxMessaging.Core.Helper
|
|
|
183
181
|
where TMessage : IMessage
|
|
184
182
|
{
|
|
185
183
|
int index = MessageHelperIndexer<TMessage>.SequentialId;
|
|
186
|
-
if (0 <= index && index < _values.
|
|
184
|
+
if (0 <= index && index < _values.Length)
|
|
187
185
|
{
|
|
188
186
|
_values[index] = null;
|
|
189
187
|
}
|
|
@@ -196,7 +194,7 @@ namespace DxMessaging.Core.Helper
|
|
|
196
194
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
197
195
|
internal void RemoveAtIndex(int index)
|
|
198
196
|
{
|
|
199
|
-
if (0 <= index && index < _values.
|
|
197
|
+
if (0 <= index && index < _values.Length)
|
|
200
198
|
{
|
|
201
199
|
_values[index] = null;
|
|
202
200
|
}
|
|
@@ -224,17 +222,52 @@ namespace DxMessaging.Core.Helper
|
|
|
224
222
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
225
223
|
internal void Clear()
|
|
226
224
|
{
|
|
227
|
-
_values.
|
|
225
|
+
_values = Array.Empty<TValue>();
|
|
226
|
+
_count = 0;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
230
|
+
private int AssignIndex<TMessage>()
|
|
231
|
+
where TMessage : IMessage
|
|
232
|
+
{
|
|
233
|
+
int index = MessageHelperIndexer.TotalMessages;
|
|
234
|
+
EnsureIndex(index);
|
|
235
|
+
MessageHelperIndexer<TMessage>.SequentialId = index;
|
|
236
|
+
MessageHelperIndexer.TotalMessages = index + 1;
|
|
237
|
+
return index;
|
|
228
238
|
}
|
|
229
239
|
|
|
230
240
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
231
|
-
private void
|
|
241
|
+
private void EnsureIndex(int index)
|
|
232
242
|
{
|
|
233
|
-
|
|
234
|
-
|
|
243
|
+
if (index < 0)
|
|
244
|
+
{
|
|
245
|
+
throw new InvalidOperationException("Message type indices cannot be negative.");
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (index < _values.Length)
|
|
249
|
+
{
|
|
250
|
+
if (_count <= index)
|
|
251
|
+
{
|
|
252
|
+
_count = index + 1;
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
int capacity = _values.Length == 0 ? 4 : _values.Length;
|
|
258
|
+
while (capacity <= index)
|
|
235
259
|
{
|
|
236
|
-
|
|
260
|
+
if (capacity > int.MaxValue >> 1)
|
|
261
|
+
{
|
|
262
|
+
throw new InvalidOperationException(
|
|
263
|
+
"The message type index exceeds the cache's supported capacity."
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
capacity <<= 1;
|
|
237
267
|
}
|
|
268
|
+
|
|
269
|
+
Array.Resize(ref _values, capacity);
|
|
270
|
+
_count = index + 1;
|
|
238
271
|
}
|
|
239
272
|
}
|
|
240
273
|
}
|
|
@@ -68,6 +68,23 @@ namespace DxMessaging.Core.Internal
|
|
|
68
68
|
/// </summary>
|
|
69
69
|
internal abstract class FlatDispatchArray
|
|
70
70
|
{
|
|
71
|
+
internal abstract int Count { get; }
|
|
72
|
+
|
|
73
|
+
/// <summary>
|
|
74
|
+
/// Physical length of the currently rented entry array. Exposed only for internal
|
|
75
|
+
/// storage benchmarks; dispatch continues to use <see cref="Count"/> as its bound.
|
|
76
|
+
/// </summary>
|
|
77
|
+
internal abstract int Capacity { get; }
|
|
78
|
+
|
|
79
|
+
/// <summary>
|
|
80
|
+
/// Number of released holders currently retained by this holder shape's pool. Released
|
|
81
|
+
/// holders have already returned their rented arrays and hold <c>Array.Empty</c>,
|
|
82
|
+
/// so this is empty-holder pool topology, not retained array-memory evidence. Array-pool
|
|
83
|
+
/// retained bytes require external memory measurement. This benchmark telemetry does not
|
|
84
|
+
/// participate in rent/release decisions.
|
|
85
|
+
/// </summary>
|
|
86
|
+
internal abstract int EmptyHolderPoolCount { get; }
|
|
87
|
+
|
|
71
88
|
internal abstract void Release();
|
|
72
89
|
}
|
|
73
90
|
|
|
@@ -108,6 +125,21 @@ namespace DxMessaging.Core.Internal
|
|
|
108
125
|
internal TEntry[] entries = Array.Empty<TEntry>();
|
|
109
126
|
internal int count;
|
|
110
127
|
|
|
128
|
+
internal override int Count => count;
|
|
129
|
+
|
|
130
|
+
internal override int Capacity => entries.Length;
|
|
131
|
+
|
|
132
|
+
internal override int EmptyHolderPoolCount
|
|
133
|
+
{
|
|
134
|
+
get
|
|
135
|
+
{
|
|
136
|
+
lock (HolderPoolLock)
|
|
137
|
+
{
|
|
138
|
+
return HolderPool.Count;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
111
143
|
// True while the holder is parked in (or eligible for) the pool;
|
|
112
144
|
// false while it is owned by a live DispatchSnapshot. Guards the
|
|
113
145
|
// rent/release lifecycle against double-release and rent-of-live.
|