Overview
The UISystem sits between UI MonoBehaviours and the SaffronLibrary message buses. It has two directions of traffic:
- Commands in: UI components register themselves, and other systems send UI-domain commands. These arrive at a
UIFlowControllerthrough the command bus, and the flow controller routes them to registered components. - Events out: UI components raise UI events describing what happened, such as a click or a page opening. These go to the event bus through
BusUtility.
Design patterns in the code
- Static factory classes.
UICommandFactoryandUIEventFactoryare static classes whose methods build a message and send it. Callers never constructCommandorEventobjects themselves for UI work.UIEventFactoryis declaredpartial, so it can be extended in other files. - Typed parameter keys.
UIParamKeysdeclares static readonlyParamKey<T>fields. Each key fixes the type of its value, so values are read back without casting. - Key-name constants.
UIParamKeyNamesholds the string names for every key.UIParamKeysbuilds its keys from those names, so the names are defined in one place. - Base class with abstract hooks.
UIFlowControllerextendsFlowController. It supplies theDomainvalue (Domain.UI) and overridesHandleCommand. The base class calls these from itsInit, which registers the controller on the command bus.UIRootis an abstract MonoBehaviour that requires aRegistrationKeyfrom each derived class. - Keyed registries.
UIFlowControllerkeeps two dictionaries keyed by registration string: one for all registeredIFlowControllablecomponents, and one for those that also implementICommandProcessor. - Verb enums. Each message family has its own verb enum:
UICommandVerbfor commands,UIEventVerbfor events, andUIRequestVerbfor requests. The receiving code switches on the verb to choose the action.
Connections to dependencies
- Contracts.
Domain.UIidentifies the UI domain.CoreParamKeyssupplies the sharedKey,Tag, andDomainContextkeys. The UI system usesCoreParamKeys.Keyas the routing key for both registration and processing. - Params. Every command and event carries a
Paramscontainer. The UI system writes values withSetand reads them withGet,TryGet, orHas. - Commands.
Command.Createbuilds the command envelope.ICommandexposesTargetDomain,Verb, andParams.IFlowControllableandICommandProcessorare the interfaces that registered components implement. - Events.
Eventis the envelope for UI events.UIEventFactorybuilds these and passes them to the bus. - Bus.
BusUtility.Senddelivers commands.BusUtility.Raisedelivers events. The UI system does not call the bus registry directly. - Flow.
FlowControllerowns the UI domain. ItsInitregistersHandleCommandon the command bus forDomain.UI.
Key concepts and terminology
- Domain: The owner of a set of commands. The UI system owns
Domain.UI. - Verb: An integer that says what a message asks for or reports. The UI system uses
UICommandVerbfor commands andUIEventVerbfor events. - Subject: A
UISubjectsvalue stored underUIParamKeys.UISubject. It says which kind of UI element an event concerns. - Registration key: A string that identifies a registered UI component. It is stored under
CoreParamKeys.Keywhen the component is registered, and it is used later to route commands to that component. - Flow controllable: A component that registers with the UI flow controller.
UIRootis the base class for these. - Command processor: A flow controllable that also implements
ICommandProcessor. The flow controller hands routed commands to it.
Event and command flow
- A
UIRootderived component'sStartruns. It callsRegister. RegistercallsUICommandFactory.RegisterFlowControllablewith the component'sRegistrationKey. This creates aRegistercommand with the key and the component attached as params.BusUtility.Senddelivers the command to the command bus, which passes it to theUIFlowControllerregistered forDomain.UI.UIFlowController.HandleCommandreturns early if the command has noKeyparam. If the verb isRegister, it stores the component in its registry. Otherwise it looks up the processor for the key and passes the command toProcessCommand.- When a UI element is clicked, a caller invokes a
UIEventFactorymethod. That method creates aUIEventVerbevent, sets its params, and callsBusUtility.Raise. - Listeners on the event bus receive the event and read its verb and params.
Thread safety
The code does not show any thread-safety measures. The registries are plain Dictionary instances with no locking, so UI commands should be sent and handled on the Unity main thread.