docs
Systems
Execution
FlowControllerSystem
Architecture and Design

FlowControllerSystem Architecture

Design patterns in use

  • Service Locator: FlowController gets the CommandBus through ServiceLocator.GetBusRegistry().CommandBus. The lookup happens on each access to the private commandBus property, not once at construction.
  • Base class with abstract hook (template-method style): The base class provides Init, which performs the registration step. Subclasses supply the domain identity (Domain) and the handler (HandleCommand). Subclasses can override Init, but they must call base.Init().
  • Routing by key: Registration is keyed by Domain. The CommandBus routes each command to the single handler registered for ICommand.TargetDomain. The flow controller does not check the domain itself.

Connections to other systems

  • InitializationManager and InitializationOrchestrator: Subclasses are created in the InitializationManager RegisterSystems method, usually through SafeRegister. Because FlowController implements IInitializable and is not an event receiver, it is placed in the sync initializables list. The orchestrator calls Init on it during Start, after the event receivers have run.
  • ServiceLocator: InitializationManager calls ServiceLocator.Initialize in Awake, before RegisterSystems. Init runs later, so the bus registry is available when CommandBus.Register is called.
  • CommandBus: Init calls Register(Domain, HandleCommand) on the bus. Commands sent with Send are routed by their TargetDomain. Per the CommandBus documentation, commands are queued until a handler is registered and ready.
  • ICommand: HandleCommand receives an ICommand. The controller uses its Verb and Params to decide what to do.
  • Domain enum: The Domain value identifies each controller. Each value in the Domain enum names one system, so each subclass should return a unique value.

Key concepts and terminology

  • Domain: The system that owns a group of commands. It is the routing key for both registration and dispatch.
  • Command: An ICommand addressed to a domain. It carries a verb and params.
  • Flow controller: A subclass of FlowController that owns one domain and handles its commands.
  • Registration: The Init step that connects a controller's HandleCommand to its domain on the command bus.

Event and data flow

  1. ServiceLocator is initialized with the bus registry during InitializationManager.Awake.
  2. RegisterSystems creates the flow controller instances.
  3. During Start, the orchestrator calls Init on each controller. Each controller registers its HandleCommand with the command bus for its Domain.
  4. A sender creates an ICommand and sends it on the command bus.
  5. The command bus uses TargetDomain to find the registered handler and calls HandleCommand on the matching controller.
  6. HandleCommand processes the command. The subclass decides how to act on Verb and Params.

Thread safety

Init runs on the main thread, during the synchronous part of initialization. FlowController has no thread-safety measures of its own, so send commands from the main thread.