title: Architecture and Design order: 2 source: generated
Design patterns in use
- Adapter.
IUpdateAdapteris the contract that bridges an engine heartbeat to the pure C# manager.UnityUpdateAdapteris the Unity implementation. - Template Method.
UpdateAdapter.Initializeperforms the null guard and then calls the abstractOnInitializedhook, which subclasses implement. - Command message. Registration is a
Commandenvelope with a verb fromUpdateCommandVerband typed params.UpdateManager.ProcessCommandswitches on the verb. - Static factory.
UpdateCommandFactorybuilds and sends commands so callers do not construct them directly.
How it connects to other systems
- Contracts.
UpdateCommandFactorycreates commands withDomain.Update.UpdateFlowControlleroverridesDomainto returnDomain.Update, so the bus routes Update-domain commands to it. - Params. The registration payload is stored under
UpdateKeys.UpdateableObject, aParamKeywhose name is built fromUpdateKeyNames.UpdateFlowController.HandleCommandchecks for that key withHasbefore forwarding the command. - Commands. Commands are created with
Command.Createand sent throughBusUtility.Send. - Flow.
UpdateFlowControllerinheritsFlowController. ItsInitcallsbase.Init(), which registersHandleCommandon the command bus for its domain.
Key concepts
- Tick. One invocation of the private
UpdateManager.Tick, which callsOnUpdateon every registered object in registration order. - Adapter binding. The link created by
SetUpdateAdapter, which callsInitializewith the manager'sTickas the callback. - Registry. The
updateableslist. Registration skips null and duplicate references. - PlayerLoop injection. The process by which
UpdateServicefinds the target phase node and appends a system node that runs the tick.
Data and control flow
Startup
UpdateFlowController.Initcallsbase.Init(), registeringHandleCommandforDomain.Update.- It creates an
UpdateManagerand aUnityUpdateAdapter, then callsSetUpdateAdapter. SetUpdateAdapterstores the adapter and callsInitialize(Tick).UpdateAdapter.InitializecallsOnInitialized(onTick).UnityUpdateAdapter.OnInitializedcallsUpdateService.InjectToPlayerLoop<UnityUpdateAdapter, UnityEngine.PlayerLoop.Update>.UpdateServicewraps the action in aPlayerLoopSystem.UpdateUtility.TryInsertSystemsearches the loop tree for theUpdatephase and appends the node. If the phase is found,PlayerLoop.SetPlayerLoopapplies the new loop.
Registration
- A caller invokes
UpdateCommandFactory.RegisterUpdatable(updateable). - The factory creates a
Registercommand forDomain.Update, setsUpdateKeys.UpdateableObjectin its params, and callsBusUtility.Send. - The command bus delivers the command to
UpdateFlowController.HandleCommand. - If the key is present,
UpdateManager.ProcessCommandruns. ForRegister, it callsAddUpdateable, which adds the object if it is not already in the list.
Tick
- Unity's Update phase runs the injected delegate.
- The delegate calls the manager's
Tick. Tickloops overupdateablesand callsOnUpdateon each.
Behaviour and limits visible in the code
- The registry is only added to.
Tickenumeratesupdateableswithforeach. Because the code has no guard, anOnUpdateimplementation that registers another object during a tick would modify the list while it is being enumerated.UpdateServiceappends each injected system to the PlayerLoop.
Initialization order
UpdateFlowController.Init calls base.Init() before it creates updateManager. The base method registers HandleCommand on the bus.
Adapter replacement
SetUpdateAdapter replaces the stored adapter and calls Initialize again. The code does not remove any earlier PlayerLoop injection.