### MessagingComponentInstaller Scene Setup Example (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MessageBusProviders.md Example of using MessagingComponentInstaller to configure all MessagingComponent descendants within a hierarchy. It involves setting a provider handle on the installer and then applying the configuration to child components. ```csharp using DxMessaging.Core.MessageBus; using DxMessaging.Unity; using UnityEngine; public class SceneSetup : MonoBehaviour { [SerializeField] private MessagingComponentInstaller installer; [SerializeField] private CurrentGlobalMessageBusProvider provider; private void Awake() { // Configure installer with provider installer.SetProvider(MessageBusProviderHandle.FromProvider(provider)); // Apply to all child MessagingComponents installer.ApplyConfiguration(); } } ``` -------------------------------- ### SceneBus Setup (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/EndToEndSceneTransitions.md Sets up a static MessageBus for scene-scoped message handling. It provides a way to get the current bus and create a new one for each scene, ensuring isolation of scene-specific messages. ```csharp using DxMessaging.Core; using DxMessaging.Core.MessageBus; using UnityEngine; public static class SceneBus { public static MessageBus Current { get; private set; } = new MessageBus(); public static void NewScene() => Current = new MessageBus(); } ``` -------------------------------- ### Basic DxMessaging Setup and Usage in Unity Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MigrationGuide.md Demonstrates the fundamental setup for sending and receiving untargeted messages using DxMessaging. It includes defining a message struct, creating a listener component, and emitting a message from another script. This is suitable for initial experimentation. ```csharp using UnityEngine; using DxMessaging; [DxUntargetedMessage] [DxAutoConstructor] public readonly partial struct TestMessage { public readonly int value; } public class TestListener : MessageAwareComponent { protected override void RegisterMessageHandlers() { base.RegisterMessageHandlers(); _ = Token.RegisterUntargeted(OnTest); } void OnTest(ref TestMessage m) => Debug.Log($"Got {m.value}"); } // In another script: // var msg = new TestMessage(42); // msg.Emit(); ``` -------------------------------- ### Simple MessageBroker Setup (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Comparisons.md Demonstrates a basic publisher-subscriber pattern using UniRx's MessageBroker. This setup allows different components to communicate without direct coupling, ideal for simple event notifications. ```csharp using UniRx; using UnityEngine; public struct EnemySpawned { public int EnemyId; public Vector3 Position; } // Publisher - extremely simple, no setup required public class EnemySpawner : MonoBehaviour { void SpawnEnemy(int id) { MessageBroker.Default.Publish(new EnemySpawned { EnemyId = id, Position = transform.position }); } } // Subscriber - also extremely simple public class AchievementSystem : MonoBehaviour { void Start() { MessageBroker.Default.Receive() .Subscribe(msg => Debug.Log($"Enemy {msg.EnemyId} spawned!")) .AddTo(this); // Automatic cleanup on destroy } } ``` -------------------------------- ### DI Container Integration Example in C# Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MessageBusProviders.md Demonstrates how to integrate a ContainerMessageBusProvider into a Dependency Injection (DI) setup. It shows registering an IMessageBus instance and then using the provider to resolve it for global use. Assumes a DI framework is in place. ```csharp // In your DI installer container.RegisterInstance(new MessageBus()); // In a bootstrap script var provider = new ContainerMessageBusProvider(container); MessageHandler.SetGlobalMessageBus(provider.Resolve()); // Now all components use the container bus ``` -------------------------------- ### Register and Emit dxmessaging Messages in C# Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/GettingStarted.md Demonstrates how to register listeners for broadcast and targeted messages, and how to emit these messages using the dxmessaging system. This involves using helper methods for registration and creating message instances for emission. ```csharp // Listen _ = Token.RegisterBroadcastWithoutSource(OnAnyDamage); _ = Token.RegisterGameObjectTargeted(playerGO, OnPlayerHealed); // Emit new TookDamage(25).EmitBroadcastWithoutSource(); new Heal(10).EmitGameObjectTargeted(playerGO); ``` -------------------------------- ### Zenject Signals: Define, Install, Fire, and Subscribe Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Comparisons.md Demonstrates the complete lifecycle of using Zenject Signals for decoupled communication in Unity. This involves defining a signal, setting it up in a Zenject installer, firing the signal from a source, and subscribing to it in a receiver. ```csharp // 1. Define signal public class EnemyKilledSignal { public string EnemyType; public int Score; } // 2. Install and declare in installer public class GameInstaller : MonoInstaller { public override void InstallBindings() { SignalBusInstaller.Install(Container); Container.DeclareSignal(); Container.BindSignal() .ToMethod(x => x.OnEnemyKilled) .FromResolve(); } } // 3. Fire signal public class Enemy : MonoBehaviour { [Inject] private SignalBus _signalBus; void Die() { _signalBus.Fire(new EnemyKilledSignal { EnemyType = "Orc", Score = 100 }); } } // 4. Subscribe to signal public class AchievementSystem { [Inject] private SignalBus _signalBus; public void Initialize() { _signalBus.Subscribe(OnEnemyKilled); } void OnEnemyKilled(EnemyKilledSignal signal) { Debug.Log($"Killed {signal.EnemyType} for {signal.Score} points!"); } } ``` -------------------------------- ### Quick Start: Define and Emit Messages with DxMessaging Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/EmitShorthands.md This example demonstrates defining various message types (SceneLoaded, Heal, TookDamage) using DxMessaging attributes and then emitting them globally, to a target, and from a source. It requires DxMessaging core and extensions. ```csharp using DxMessaging.Core; // InstanceId using DxMessaging.Core.Attributes; // Dx* attributes using DxMessaging.Core.Extensions; // Emit/EmitAt/EmitFrom // Define your messages [DxUntargetedMessage] [DxAutoConstructor] public readonly partial struct SceneLoaded { public readonly int buildIndex; } [DxTargetedMessage] [DxAutoConstructor] public readonly partial struct Heal { public readonly int amount; } [DxBroadcastMessage] [DxAutoConstructor] public readonly partial struct TookDamage { public readonly int amount; } // Emit them var scene = new SceneLoaded(1); scene.Emit(); // Global: everyone listening receives this var heal = new Heal(10);heal.EmitAt(player); // Targeted: only the player receives this var damage = new TookDamage(5); damage.EmitFrom(enemy); // Broadcast: listeners interested in enemy damage receive this ``` -------------------------------- ### Send DxMessaging Messages Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/GettingStarted.md Demonstrates how to emit a targeted message in DxMessaging. This example shows creating a 'Heal' message instance and sending it to a specific game object. ```csharp var heal = new Heal(10); heal.EmitGameObjectTargeted(playerGameObject); ``` -------------------------------- ### Batching Updates: C# Example Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Patterns.md Demonstrates how to batch related updates into a single message to reduce traffic and registration overhead, contrasting with an anti-pattern of separate messages per UI element. ```csharp // ❌ DON'T: Separate message per UI element (too granular) [DxUntargetedMessage] public struct HealthChanged { public int health; } [DxUntargetedMessage] public struct ManaChanged { public int mana; } [DxUntargetedMessage] public struct GoldChanged { public int gold; } // This creates 3x message traffic and registration overhead // ✅ DO: Batch related updates into one message [DxUntargetedMessage] public struct PlayerStatsChanged { public int health; public int mana; public int gold; } ``` -------------------------------- ### Unity: Complete Example of Messaging with Shorthand Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/EmitShorthands.md This C# example shows how to define various message types, send (emit) messages, and receive (handle) them. It illustrates the use of untargeted, targeted, and broadcast messages within a Unity context, including producers, consumers, and listeners. ```csharp ```csharp using DxMessaging.Core; using DxMessaging.Core.Attributes; using DxMessaging.Core.Extensions; using UnityEngine; // Message definitions [DxUntargetedMessage] [DxAutoConstructor] public readonly partial struct WaveStarted { public readonly int waveNumber; } [DxTargetedMessage] [DxAutoConstructor] public readonly partial struct SpawnEnemy { public readonly string enemyType; } [DxBroadcastMessage] [DxAutoConstructor] public readonly partial struct EnemyDied { public readonly int score; } // Producer public class GameManager : MonoBehaviour { void StartWave(int wave) { // Global broadcast: everyone should know var waveMsg = new WaveStarted(wave); waveMsg.Emit(); // Targeted: tell specific spawner what to spawn var spawnMsg = new SpawnEnemy("Goblin"); spawnMsg.EmitGameObjectTargeted(spawnerObject); } } // Consumer public class Enemy : MonoBehaviour { void Die() { // Broadcast from this enemy: anyone watching can react var deathMsg = new EnemyDied(100); deathMsg.EmitGameObjectBroadcast(gameObject); } } // Listeners public class UIManager : MessageAwareComponent { protected override void RegisterMessageHandlers() { _ = Token.RegisterUntargeted(OnWaveStarted); } void OnWaveStarted(ref WaveStarted msg) { Debug.Log($"Wave {msg.waveNumber} started!"); } } public class AchievementTracker : MessageAwareComponent { protected override void RegisterMessageHandlers() { // Listen to ALL enemy deaths (no specific source) _ = Token.RegisterBroadcastWithoutSource(OnAnyEnemyDied); } void OnAnyEnemyDied(ref InstanceId source, ref EnemyDied msg) { Debug.Log($"Enemy {source} died for {msg.score} points"); } } ``` ``` -------------------------------- ### Migration Rollback Plan Example (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MigrationGuide.md This C# code snippet illustrates a rollback plan for migration. It shows how to keep old event subscriptions commented out but preserved for a defined period (until a specific date). This allows for easy reversion if issues arise after switching to DxMessaging. ```csharp // OLD (keep until 2024-02-01) // player.OnHealthChanged += UpdateBar; // NEW _ = Token.RegisterBroadcast(...); ``` -------------------------------- ### Install and Run Pre-commit Hooks Source: https://github.com/wallstop/dxmessaging/blob/master/CONTRIBUTING.md Installs and runs pre-commit hooks and linters locally to catch issues before committing. Requires Python and pip or pipx. ```bash pip install pre-commit pre-commit install pre-commit run --all-files ``` -------------------------------- ### Define Messages for Game Events Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/EndToEnd.md Defines the core message structures for different types of game events: video settings changes (Untargeted), healing a player (Targeted), and enemies reporting damage taken (Broadcast). These use DxMessaging attributes for automatic setup. ```csharp using DxMessaging.Core.Attributes; [DxUntargetedMessage][DxAutoConstructor] public readonly partial struct VideoSettingsChanged { public readonly int width; public readonly int height; } [DxTargetedMessage][DxAutoConstructor] public readonly partial struct Heal { public readonly int amount; } [DxBroadcastMessage][DxAutoConstructor] public readonly partial struct TookDamage { public readonly int amount; } ``` -------------------------------- ### Manual DxMessaging Installation via manifest.json Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Install.md This method manually adds the DxMessaging package to your Unity project by editing the `manifest.json` file, providing the Git URL as a dependency. ```json { "dependencies": { "com.wallstop-studios.dxmessaging": "https://github.com/wallstop/DxMessaging.git" } } ``` -------------------------------- ### MessageBusProviderHandle Runtime Override Example (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MessageBusProviders.md Illustrates how to dynamically configure a MessageAwareComponent with a runtime message bus provider using MessageBusProviderHandle. This enables runtime flexibility by creating a provider from an existing IMessageBus. ```csharp using DxMessaging.Core.MessageBus; using DxMessaging.Unity; public class DynamicConfigurator { public void ConfigureWithRuntimeBus(MessageAwareComponent component, IMessageBus runtimeBus) { // Create a runtime provider var provider = new RuntimeMessageBusProvider(runtimeBus); // Wrap it in a handle var handle = MessageBusProviderHandle.FromProvider(provider); // Configure the component component.ConfigureMessageBus(handle, MessageBusRebindMode.RebindActive); } } // Simple runtime provider implementation public class RuntimeMessageBusProvider : IMessageBusProvider { private readonly IMessageBus _bus; public RuntimeMessageBusProvider(IMessageBus bus) { _bus = bus; } public IMessageBus Resolve() => _bus; } ``` -------------------------------- ### Install DxMessaging via Git URL in Unity UPM Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Install.md This method involves adding the DxMessaging package to your Unity project directly from its Git repository URL using the Unity Package Manager. ```bash # Unity UPM: Add package from git URL... https://github.com/wallstop/DxMessaging.git ``` -------------------------------- ### DxMessaging Message Type Examples Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/GettingStarted.md Illustrates the definition of different DxMessaging message types: untargeted, targeted, and broadcast. Each example shows the appropriate attribute and struct definition. ```csharp // Untargeted: "Everyone, the game paused!" [DxUntargetedMessage] public struct GamePaused { } // Targeted: "Player, heal yourself by 50!" [DxTargetedMessage] public struct Heal { public int amount; } // Broadcast: "I (Enemy #3) just died!" [DxBroadcastMessage] public struct EnemyDied { public string enemyName; } ``` -------------------------------- ### Define DxMessaging Messages Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/GettingStarted.md Defines custom message structs for DxMessaging, specifying their target and automatic constructor generation. These messages can be broadcast or targeted. ```csharp using DxMessaging.Core.Attributes; [DxTargetedMessage] [DxAutoConstructor] public readonly partial struct Heal { public readonly int amount; } [DxBroadcastMessage] [DxAutoConstructor] public readonly partial struct TookDamage { public readonly int amount; } ``` -------------------------------- ### Priority-Ordered Execution: C# Example Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Patterns.md Illustrates how to ensure systems execute in a specific order by assigning priorities to message handlers. Lower priority numbers execute first, preventing race conditions in complex scenarios like game exit. ```csharp [DxUntargetedMessage] [DxAutoConstructor] public readonly partial struct GameExit { } public class SaveSystem : MessageAwareComponent { protected override void RegisterMessageHandlers() { // Priority 0 = runs FIRST _ = Token.RegisterUntargeted(OnExit, priority: 0); } void OnExit(ref GameExit msg) { SaveGame(); // Must complete before audio fades } } public class AudioSystem : MessageAwareComponent { protected override void RegisterMessageHandlers() { // Priority 5 = runs AFTER SaveSystem _ = Token.RegisterUntargeted(OnExit, priority: 5); } void OnExit(ref GameExit msg) { FadeOutMusic(); // Runs after save } } public class UISystem : MessageAwareComponent { protected override void RegisterMessageHandlers() { // Priority 10 = runs LAST _ = Token.RegisterUntargeted(OnExit, priority: 10); } void OnExit(ref GameExit msg) { ShowExitAnimation(); // Runs after audio fade starts } } // Emit once, all systems execute in priority order var msg = new GameExit(); msg.Emit(); ``` -------------------------------- ### C# MessageAwareComponent Example Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Glossary.md Illustrates how to create a custom component in Unity by inheriting from DxMessaging's 'MessageAwareComponent'. This base class automatically handles the lifecycle management for message tokens, simplifying setup and cleanup. ```csharp public class MyComponent : MessageAwareComponent { // Token is created automatically! } ``` -------------------------------- ### Post-Processing for Analytics: C# Example Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Patterns.md Demonstrates using post-processors to log analytics and metrics without modifying existing gameplay code. This pattern isolates concerns, allowing analytics systems to be added or removed without impacting core game logic. ```csharp public class GameAnalytics : MessageAwareComponent { protected override void RegisterMessageHandlers() { // Post-processors run AFTER all handlers _ = Token.RegisterBroadcastWithoutSourcePostProcessor(LogDamage, priority: 100); _ = Token.RegisterUntargetedPostProcessor(LogLevelComplete, priority: 100); } void LogDamage(InstanceId source, EntityDamaged msg) { // Analytics code is completely isolated from gameplay SendAnalyticsEvent("damage_dealt", new { source = source.ToString(), amount = msg.amount, type = msg.damageType }); } void LogLevelComplete(ref LevelCompleted msg) { SendAnalyticsEvent("level_complete", new { level = msg.levelIndex }); } } ``` -------------------------------- ### Listen to DxMessaging Messages in Unity Component Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/GettingStarted.md Implements message handling within a Unity component by inheriting from MessageAwareComponent and registering listeners for targeted and broadcast messages. It shows how to update UI based on received messages. ```csharp using DxMessaging.Core; using DxMessaging.Core.Extensions; using DxMessaging.Unity; public class GameUI : MessageAwareComponent { // Assume this references a Player GameObject public UnityEngine.GameObject playerGO; protected override void RegisterMessageHandlers() { base.RegisterMessageHandlers(); _ = Token.RegisterGameObjectTargeted(playerGO, OnPlayerHealed); _ = Token.RegisterBroadcastWithoutSource(OnAnyDamage); } private void OnPlayerHealed(ref Heal m) => UpdateHealthBar(m.amount); private void OnAnyDamage(InstanceId source, TookDamage m) => ShowDamageEffect(source); } ``` -------------------------------- ### Publish Untargeted Message - C# Source: https://github.com/wallstop/dxmessaging/blob/master/Samples~/Mini Combat/Walkthrough.md Demonstrates how the Boot script publishes an untargeted message, `VideoSettingsChanged`, to the message hub. This type of message is intended for global consumption by any interested listener. ```csharp // In Boot.cs MessageHub.Publish(new VideoSettingsChanged()) ``` -------------------------------- ### DxMessaging Scene Transition Example Source: https://github.com/wallstop/dxmessaging/blob/master/README.md Demonstrates how to define a scene transition message and have multiple systems (AudioSystem, SaveSystem) react to it independently using DxMessaging. It utilizes attributes like `[DxUntargetedMessage]` and `[DxAutoConstructor]` for message definition and `MessageAwareComponent` for handler registration. ```csharp ```csharp [DxUntargetedMessage] [DxAutoConstructor] public readonly partial struct SceneTransition { public readonly string sceneName; } // Multiple systems react independently public class AudioSystem : MessageAwareComponent { protected override void RegisterMessageHandlers() { base.RegisterMessageHandlers(); _ = Token.RegisterUntargeted(OnScene, priority: 0); } void OnScene(ref SceneTransition m) => FadeOutMusic(); } public class SaveSystem : MessageAwareComponent { protected override void RegisterMessageHandlers() { base.RegisterMessageHandlers(); _ = Token.RegisterUntargeted(OnScene, priority: 0); } void OnScene(ref SceneTransition m) => SaveGame(); } ``` ``` -------------------------------- ### Battle Royale Game: DxMessaging Example Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Patterns.md Illustrates a real-world implementation of DxMessaging for a battle royale game. Shows message definitions and UI component implementations for player health, kill feeds, and match stats, demonstrating targeted, selective, and global observations. ```csharp // Messages [DxBroadcastMessage] [DxAutoConstructor] public readonly partial struct PlayerDamaged { public readonly int playerId; public readonly int newHealth; public readonly int newArmor; } [DxBroadcastMessage] [DxAutoConstructor] public readonly partial struct PlayerKilled { public readonly int victimId; public readonly int killerId; } // YOUR health bar (targeted observation) public class SelfHealthUI : MessageAwareComponent { [SerializeField] private GameObject localPlayerObject; protected override void RegisterMessageHandlers() { _ = Token.RegisterGameObjectBroadcast(localPlayerObject, OnDamage); } void OnDamage(ref PlayerDamaged msg) => UpdateHealthBar(msg.newHealth, msg.newArmor); } // TEAMMATE health bars (selective observation) public class TeamHealthUI : MessageAwareComponent { [SerializeField] private List teammateObjects; protected override void RegisterMessageHandlers() { foreach (var teammate in teammateObjects) { _ = Token.RegisterGameObjectBroadcast(teammate, OnTeammateDamage); } } void OnTeammateDamage(ref PlayerDamaged msg) => UpdateTeammateBar(msg.playerId, msg.newHealth); } // KILL FEED (global observation) public class KillFeedUI : MessageAwareComponent { protected override void RegisterMessageHandlers() { _ = Token.RegisterBroadcastWithoutSource(OnAnyKill); } void OnAnyKill(InstanceId source, PlayerKilled msg) { ShowKillFeedEntry(msg.killerId, msg.victimId); } } // MATCH STATS (analytics) public class MatchStats : MessageAwareComponent { private Dictionary damageByPlayer = new(); protected override void RegisterMessageHandlers() { _ = Token.RegisterBroadcastWithoutSourcePostProcessor(TrackDamage); } void TrackDamage(InstanceId source, PlayerDamaged msg) { // Track for post-game stats } } ``` -------------------------------- ### Simulate Message Sequence - Mermaid Source: https://github.com/wallstop/dxmessaging/blob/master/Samples~/Mini Combat/Walkthrough.md Illustrates the complete message flow of the Mini Combat demo using a sequence diagram. It shows how Boot initiates events like settings updates, healing, and damage broadcasts, and how UIOverlay and Player respond. ```mermaid sequenceDiagram participant Boot participant UIOverlay participant Player participant Enemy Note over Boot: STEP 1: Boot starts Boot->>UIOverlay: VideoSettingsChanged (Untargeted) Note over UIOverlay: Rebuilds UI Note over Boot: STEP 2: Boot sends Heal Boot->>Player: Heal (Targeted) Note over Player: Increases HP by heal amount Note over Enemy: STEP 3: Enemy broadcasts Enemy->>UIOverlay: TookDamage (Broadcast) Note over UIOverlay: Shows damage notification ``` -------------------------------- ### Message-to-Event Bridge Example (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MigrationGuide.md This C# code demonstrates the Message-to-Event Bridge pattern. It shows how a DxMessage (NewMessage) can trigger an old-style C# event (LegacyEvent). This is useful when existing code still relies on traditional events, and you need to bridge them to the new DxMessaging system. ```csharp public class ModernBridge : MessageAwareComponent { public event Action LegacyEvent; // For old code that needs events protected override void RegisterMessageHandlers() { base.RegisterMessageHandlers(); _ = Token.RegisterUntargeted(OnMessage); } void OnMessage(ref NewMessage msg) { LegacyEvent?.Invoke(msg.value); // Fire old event } } ``` -------------------------------- ### Unit Test Message Emission with VContainer in C# Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Integrations/VContainer.md Provides a unit test example for verifying message emission using DxMessaging and VContainer. It sets up a `ContainerBuilder`, registers an `IMessageBus` instance, and resolves the `GameInitializer` to test its `Start` method. Message handling is set up to assert that a message was received. ```csharp using DxMessaging.Core.MessageBus; using VContainer; using VContainer.Unity; using NUnit.Framework; [TestFixture] public class GameInitializerTests { [Test] public void Initialize_EmitsGameStarted() { // Arrange var builder = new ContainerBuilder(); var bus = new MessageBus(); builder.RegisterInstance(bus); builder.RegisterEntryPoint(); var container = builder.Build(); bool messageReceived = false; var handler = new MessageHandler(new InstanceId(1), bus) { active = true }; var token = MessageRegistrationToken.Create(handler, bus); _ = token.RegisterUntargeted(ref msg => messageReceived = true); token.Enable(); // Act container.Resolve().Start(); // Assert Assert.IsTrue(messageReceived); } } ``` -------------------------------- ### Event-to-Message Bridge Example (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MigrationGuide.md This C# code illustrates the Event-to-Message Bridge pattern. An old system's event (OnSomethingHappened) is subscribed to, and its arguments are used to create and emit a new DxMessage (SomethingHappened). This allows old event sources to trigger new message-based systems. ```csharp public class LegacyBridge : MonoBehaviour { [SerializeField] private LegacySystem legacySystem; void Awake() { // Old system fires event, we convert to message legacySystem.OnSomethingHappened += (args) => { var msg = new SomethingHappened(args); msg.Emit(); }; } } ``` -------------------------------- ### Gradual GameObject Migration - Phase 1 (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MigrationGuide.md This C# code snippet shows Phase 1 of the Gradual GameObject Migration. It keeps old inspector references (like HealthBar) but starts emitting new DxMessages (HealthChanged) in parallel with old direct calls. This allows for incremental migration without breaking existing functionality. ```csharp // Phase 1: Keep old inspector references, emit messages public class Player : MonoBehaviour { [SerializeField] private HealthBar healthBar; // OLD - will remove later void TakeDamage(int amount) { health -= amount; healthBar.UpdateHealth(health); // OLD direct call var msg = new HealthChanged(health); msg.EmitGameObjectBroadcast(gameObject); // NEW message } } ``` -------------------------------- ### Runtime Provider Override Example in C# Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MessageBusProviders.md A Unity MonoBehaviour demonstrating how to initially use a design-time message bus provider and then switch to a runtime-provided bus. This allows for dynamic reconfiguration of message bus handling. Requires Unity engine and specific DxMessaging components. ```csharp using DxMessaging.Core.MessageBus; using UnityEngine; public class RuntimeReconfiguration : MonoBehaviour { [SerializeField] private MessageAwareComponent component; [SerializeField] private MessageBusProviderHandle designTimeHandle; // Set in Inspector private void Start() { // Use design-time provider initially component.ConfigureMessageBus(designTimeHandle, MessageBusRebindMode.RebindActive); } public void SwitchToRuntimeBus(IMessageBus runtimeBus) { // Override with runtime provider var runtimeProvider = new RuntimeMessageBusProvider(runtimeBus); var handle = MessageBusProviderHandle.FromProvider(runtimeProvider); component.ConfigureMessageBus(handle, MessageBusRebindMode.RebindActive); } } ``` -------------------------------- ### MessageBusProviderHandle Key Methods (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MessageBusProviders.md Demonstrates how to create, associate runtime providers with, and resolve message bus providers using MessageBusProviderHandle. Runtime providers take precedence over ScriptableObject assets for resolution. ```csharp using DxMessaging.Unity; using DxMessaging.Core.MessageBus; // Create from a runtime provider MessageBusProviderHandle handle = MessageBusProviderHandle.FromProvider(myProvider); // Associate a runtime provider with an existing handle handle = handle.WithRuntimeProvider(myRuntimeProvider); // Resolve the provider (runtime takes precedence over asset) if (handle.TryGetProvider(out IMessageBusProvider provider)) { IMessageBus bus = provider.Resolve(); } // Or resolve the bus directly IMessageBus bus = handle.ResolveBus(); ``` -------------------------------- ### Install DxMessaging and Reflex Bindings (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Integrations/Reflex.md Sets up Reflex to bind DxMessaging's IMessageBus and optionally the IMessageRegistrationBuilder. This installer should be added to your scene's Context component. ```csharp using DxMessaging.Core.MessageBus; using Reflex.Core; public sealed class DxMessagingInstaller : Installer { public override void InstallBindings(ContainerDescriptor descriptor) { // Bind MessageBus as both concrete and interface descriptor.AddSingleton(typeof(MessageBus), typeof(MessageBus)); descriptor.AddSingleton(typeof(IMessageBus), c => c.Resolve()); // Optional: Enable automatic IMessageRegistrationBuilder binding // Requires REFLEX_PRESENT define (auto-added by DxMessaging when Reflex detected) #if REFLEX_PRESENT descriptor.AddMessageRegistrationBuilder(); #endif } } ``` -------------------------------- ### C# Player Class: Coupled vs. DxMessaging Source: https://github.com/wallstop/dxmessaging/blob/master/Samples~/Mini Combat/README.md Demonstrates the difference between a traditional coupled Player class and one utilizing DxMessaging. The coupled version manually calls UI and AudioManager, while the DxMessaging version emits a broadcast message, achieving zero coupling. This highlights how DxMessaging simplifies event handling and reduces dependencies. ```csharp public class Player { [SerializeField] private UI ui; // Coupling! [SerializeField] private AudioManager audio; // More coupling! void Heal(int amount) { health += amount; ui.UpdateHealth(health); // Manual call audio.PlayHealSound(); // Manual call } } ``` ```csharp public class Player : MessageAwareComponent { void Heal(int amount) { health += amount; new PlayerHealed(amount).EmitBroadcast(this); // Done! UI, audio, analytics all react automatically. } } ``` -------------------------------- ### Global Accept-All Handlers for Tools and Inspectors Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Patterns.md Shows how to set up global handlers that accept all untargeted, targeted, and broadcast messages. This is particularly useful for debugging tools and inspectors that need to observe all message activity within the system. It emphasizes preferring specific registrations for gameplay code. ```csharp _ = token.RegisterGlobalAcceptAll( (ref IUntargetedMessage m) => Debug.Log($"Untargeted {m.MessageType}"), (ref InstanceId target, ref ITargetedMessage m) => Debug.Log($"Targeted {m.MessageType} to {target}"), (ref InstanceId source, ref IBroadcastMessage m) => Debug.Log($"Broadcast {m.MessageType} from {source}") ); ``` -------------------------------- ### Direct Method Call vs. Over-Messaging in C# Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MigrationGuide.md Demonstrates the difference between an overly verbose message-based approach and a direct method call for simple operations. This highlights the importance of keeping simple tasks simple and avoiding unnecessary message overhead. ```csharp // L OVERKILL - Just call the method! var msg = new CloseDoorMessage(doorId); msg.Emit(); // BETTER - Direct reference is fine door.Close(); ``` -------------------------------- ### Adding New Features with DxMessaging in Unity Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/MigrationGuide.md Illustrates how to integrate DxMessaging into a new feature, such as an achievement system, without altering existing code. It shows defining a broadcast message, creating a listening system, and bridging from old code to emit the new message. This minimizes risk and demonstrates value. ```csharp // 1. Define messages for interesting events (don't touch existing code yet) [DxBroadcastMessage] [DxAutoConstructor] public readonly partial struct EnemyKilled { public readonly string enemyType; public readonly int playerLevel; } // 2. Make your NEW achievement system listen public class AchievementSystem : MessageAwareComponent { protected override void RegisterMessageHandlers() { base.RegisterMessageHandlers(); _ = Token.RegisterBroadcastWithoutSource(OnEnemyKilled); } void OnEnemyKilled(InstanceId source, EnemyKilled msg) { // Track kills, unlock achievements if (msg.enemyType == "Boss") UnlockAchievement("BossSlayer"); } } // 3. Bridge from existing code (minimal change) public class Enemy : MonoBehaviour { public event Action OnDied; // OLD - keep for now void Die() { OnDied?.Invoke(); // OLD code still works // NEW: Emit DxMessage too var msg = new EnemyKilled(enemyType, PlayerStats.Level); msg.EmitGameObjectBroadcast(gameObject); } } ``` -------------------------------- ### Emit DxMessaging Messages with Unity Helpers (C#) Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/QuickReference.md Shows how to emit messages using Unity-specific helper extensions provided by DxMessaging. Includes examples for targeted, broadcast, and string-based messages with various targeting options. ```csharp using DxMessaging.Core.Extensions; var scene = new SceneLoaded(1); scene.Emit(); var heal = new Heal(10); heal.EmitGameObjectTargeted(gameObject); var hit = new TookDamage(5); hit.EmitComponentBroadcast(this); // String shorthands "Saved".Emit(); // GlobalStringMessage "Hello".EmitAt(gameObject); // StringMessage to GO (or .Emit(instanceId)) "Hit".EmitFrom(gameObject); // SourcedStringMessage from GO ``` -------------------------------- ### Bind MessageBus with Zenject Installer Source: https://github.com/wallstop/dxmessaging/blob/master/Docs/Integrations/Zenject.md This C# code snippet demonstrates how to create a Zenject installer to bind the DxMessaging's MessageBus as a singleton dependency within the Zenject container. It also shows how to conditionally register the IMessageRegistrationBuilder if Zenject is present. ```csharp using DxMessaging.Core.MessageBus; using Zenject; public sealed class DxMessagingInstaller : MonoInstaller { public override void InstallBindings() { // Bind MessageBus as a singleton and expose IMessageBus interface Container.BindInterfacesAndSelfTo().AsSingle(); // Optional: Enable automatic IMessageRegistrationBuilder binding // Requires ZENJECT_PRESENT define (auto-added by DxMessaging when Zenject detected) #if ZENJECT_PRESENT Container.RegisterMessageRegistrationBuilder(); #endif } } ```