Dispatch
Purpose
Dispatch transfers owned work to the platform/graphics or simulation owner. Use it when an operation requires that owner, rather than running arbitrary CPU work through an owner queue or calling a thread-affine adapter directly.
Interface
Types below are in CE::Runtime unless another namespace is shown.
Types and operations
API and purpose |
|---|
|
|
|
|
Submission and completion
Operation |
Purpose and details |
|---|---|
|
Decay-own work/captures and retain its future; borrowed pointees still need a lifetime. Ownership and future results. |
|
Retain queue state independently of the borrowed service facade. Endpoint lifetime. |
Future readiness / result |
Consume accepted results/errors without waiting on the owner needed to produce them. Dependency progress. |
Runtime closure |
Settle required accepted dependencies, then cancel unexecuted work before game cleanup. Shutdown order. |
Usage
Save a copyable submission endpoint during initialization. Producers submit owned inputs through that endpoint and retain the returned future; a later update adopts the result after readiness is observed.
---
config:
theme: base
themeVariables:
fontFamily: system-ui, sans-serif
fontSize: 14px
flowchart:
htmlLabels: true
curve: linear
nodeSpacing: 22
rankSpacing: 38
padding: 12
---
flowchart LR
accTitle: Dispatch · application owner requests
accDescr: Local names omit Runtime::; ambiguous nested namespaces remain qualified. Arrows point toward the API or type used, not call order or data flow. Methods beneath type names are selected application entry points; Implement hooks marks engine-invoked overrides. Dashed arrows mark optional choices.
k0(["Application<br/>init_platform()"]):::app
k1["<b>Context</b><br/><br/>platform_dispatcher(): PlatformDispatcher<br/><br/>resources(): Rendering::Resources::Provider"]:::neighbor
k2["<b>PlatformDispatcher</b><br/><br/>submission(): PlatformDispatcher::Submission"]:::focal
k3["<b>PlatformDispatcher::<br/>Submission</b><br/><br/>submit(Work): Result"]:::focal
k4(["Application<br/>producer"]):::app
k5(["Application<br/>platform-owner work"]):::app
k6["<b>Rendering::Resources::<br/>Provider</b><br/><br/>create_image(Assets::Images::Decoded):<br/>Rendering::Resources::Image<br/><br/>upload_geometry(<br/>Rendering::Geometry::Vertex2D[],<br/>Rendering::Geometry::Topology):<br/>Rendering::Geometry::Buffer2D"]:::neighbor
k7(["Application<br/>composition"]):::app
k8["<b>GameRuntime</b><br/><br/>simulation_dispatcher(): SimulationDispatcher"]:::neighbor
k9["<b>SimulationDispatcher</b><br/><br/>submission(): SimulationDispatcher::Submission"]:::focal
k10["<b>SimulationDispatcher::<br/>Submission</b><br/><br/>submit(Work): Result"]:::focal
k11(["Application<br/>simulation-owner work"]):::app
k12["Game::<br/>TickContext"]:::neighbor
k0 --> k1
k1 --> k2
k2 --> k3
k4 --> k3
k5 --> k1
k1 --> k6
k7 --> k8
k8 --> k9
k9 --> k10
k4 --> k10
k11 --> k12
classDef focal fill:#e7f3ef,stroke:#387d6b,color:#153d33,stroke-width:1.2px
classDef neighbor fill:#f0f3f8,stroke:#8c9bb1,color:#35445b,stroke-width:1px
classDef app fill:#fff2df,stroke:#c09452,color:#674515,stroke-dasharray:5 3
classDef system fill:#eaf0fc,stroke:#617fab,color:#263f69,stroke-width:1.2px
linkStyle default stroke:#7e8fa7,stroke-width:1.2px
Local names omit Runtime:: where unambiguous. Explore this diagram and its other views →
Explore dispatcher ownership and engine consumers.
Choose the destination
Work |
Queue or service |
Execution boundary |
|---|---|---|
Upload resources, mutate/query a native window, perform graphics operations |
|
|
Apply an owned result to simulation state |
|
|
Decode, shape or otherwise prepare CPU data |
Independent CPU capacity; the application arranges later owner upload/adoption. Workers. |
|
Observe an event on a selected owner |
Adapt a saved endpoint into event delivery; retain a registration and independent error sink. Events. |
Submission always queues, even when the producer is already on the destination owner. Capture owned values, keep borrowed targets alive through execution or cancellation, and avoid waiting on work that needs the current owner. The complete result-adoption example shows endpoint storage, readiness checking and error handling.
Uses
Dependency |
Dispatch’s use |
|---|---|
Supply the platform callback’s live adapter/resource access. Simulation callbacks receive no Context argument. Runtime. |
|
Observe accepted, queued, running, completed and cancelled work. These counters do not replace the request’s future. Diagnostics. |
|
Report queue lifecycle and high-water observations; callback failures remain with their futures. |
GameRuntime controls opening, owner binding, draining and closure. A saved
endpoint retains queue state, without retaining Context or native adapters.
Used by
Consumer |
What it submits |
|---|---|
Service owner batches and settle/cancel outstanding work in the session shutdown order. |
|
Upload owned prepared scene data to the graphics owner. GUI. |
|
Prepare away from graphics, submit upload and adopt a ready generation on simulation. |
|
Transfer optional callbacks through a saved platform/simulation endpoint; the bus itself does not own a dispatcher. |
|
Application asset preparation or jobs |
Submit owner-affine follow-up using saved endpoints. A Loader or worker pool does not automatically schedule that orchestration. Assets. |
Contracts
Each drain detaches one FIFO batch. New/nested posts wait for another drain; submission never executes inline. Captures are decay-owned, but references and reference-valued results still borrow targets. Accepted exceptions reach the future; unexecuted cancellation breaks its promise. Never wait on a future from the owner needed to complete it.
Endpoints retain queue state rather than borrowed service pointers. They reject
before opening, after closing and after destruction. has_pending() only sees
queued work; an empty queue does not establish completion of a detached batch.
Lifecycle
Runtime opens queues during initialization and binds simulation to its selected owner. Save endpoints for longer-lived adapters without extending backend lifetime. During shutdown, runtime services accepted dependencies while joining simulation and settling tracked CPU work, then cancels remaining requests before game cleanup. Borrowed captures must survive either execution or cancellation.
Execution
Platform requests run with the runtime’s selected graphics context on platform. Simulation batches drain before scheduled updates without consuming input merely because mailbox work ran. Cross-domain ordering follows explicit dependencies; there is no total order between independent platform, simulation and worker work.
Integration
During init_platform(), obtain a copyable endpoint and retain it in the producer that
will submit requests. During the live session that producer can request a window
observation on its owner:
auto platform_requests = engine_.platform_dispatcher().submission(); // Save during init_platform().
// Later, the producer uses its saved endpoint:
auto pending = platform_requests.submit([](CE::Runtime::Context& owner) {
return owner.window().framebuffer_size();
});
The endpoint and pending are retained values, not temporary service pointers.
The complete readiness example
shows their member storage and adoption during update. Inspect future readiness
from later updates; do not block simulation while it
depends on platform progress. Ordinary game layout should use tick dimensions
directly; the example shows where an explicitly requested live observation runs.
Limits and further reading
Dispatch is not a general executor, a completion barrier based on queue emptiness or automatic lifetime extension for captured raw pointers. Read thread dispatch, runtime shutdown and the platform interface.