Scene Services¶
SceneServices is an Advanced Stable, activation-scoped capability set. It is created, advanced and closed by ziviDomeLive, then supplied before each setupScene().
class ServiceScene implements Scene {
SceneServices services;
public void configure(SceneServices services) {
this.services = services;
}
public void sceneRender(PGraphicsOpenGL pg) {
services.camera().apply(pg);
// draw
}
}
Service map¶
| Accessor | Focus | Scene controls | Runtime owns |
|---|---|---|---|
applet() |
Processing host | Read/use ordinary applet facilities on the correct thread | Applet lifetime |
frameClock() |
Frame time | Maximum accepted delta | Tick and monotonic frame index |
timeline() |
Simulation | Rate, position, fixed step, catch-up policy, pause | None of the scene's step policy |
tasks() |
Background CPU/I/O | Bounded keyed submission, result/error callbacks | Shared executor, cancellation, frame-boundary publication |
assets() |
Images/shaders/shapes | Requests and retained shapes | Render-thread creation and cache shutdown |
actions() |
Named input | Bind, trigger, unregister | Dispatch order and activation cleanup |
camera() |
Scene-space navigation and opt-in view lighting | Pose, input, tracking, light-rig call | Once-per-frame update and stale-anchor reset |
environment() |
Background overrides | Image, visibility, intensity, longitude yaw, fixed source orientation | Conditional restoration on deactivation |
ports() |
Optional adapters | Connect bounded input/output ports | Drain limit, telemetry and closure |
requestReload() |
Lifecycle | Ask for reload | Execute at a safe frame boundary |
Ownership restrictions¶
Scenes cannot construct or close runtime-supplied service objects. parent, scene, raw render queues, arbitrary dispose hooks and service close() methods are intentionally absent.
Only SceneInputPort and SceneOutputPort extend AutoCloseable; that is an adapter-provider SPI. ScenePorts still retains activation ownership and closes connected adapters.
Background task contract¶
SceneTaskGroup.submitIfIdle(key, ...) is bounded and callback-based. It does not return Future, expose the executor or accept unbounded work.
services.tasks().submitIfIdle(
"mesh",
() -> buildCpuOnlyMeshData(),
data -> publishOnFrameBoundary(data),
error -> report(error));
- the callable/runnable must not call Processing/OpenGL;
- result and error consumers run only for the submitting activation;
- stale work from a disposed activation cannot publish into a later activation of the same
Sceneinstance; getInFlightCount()andgetMaxInFlight()expose bounded-state telemetry.
Ports contract¶
connectInput(port, consumer) accepts external-thread data into a bounded activation queue. The runtime delivers a bounded amount at a frame boundary. getPendingInputCount() and getDroppedInputCount() make backpressure observable.
connectOutput(port) retains the provider and its non-blocking offer(value) contract. Real MIDI, OSC or device adapters remain optional and outside the core library.
Environment restoration¶
The environment service restores only values it changed and only while facade state still matches the value it applied. A later owner is never overwritten by stale cleanup.
Camera-synchronized view lighting¶
camera().applyWithViewLighting(pg) is an explicit alternative to camera().apply(pg). It applies
the current orbit transform, clears the target's lights, and installs a neutral ambient light plus
a warm spotlight located at the scene-camera position and aimed at its current look-at target.
Additional lights may be added afterward.
The call only reads the already-updated camera pose. It does not advance interpolation, so every
cubemap face in the same Processing frame observes the same position and direction. Lighting is
never enabled automatically; use ordinary apply(pg) when a scene owns a different lighting
model or shader pipeline.
Ordinary scenes can stay on the root wildcard import: setDistanceLimits, setCollapseGuard,
setLerpFactor, setDragSensitivity, and snapToAxisAngle forward the common orbit operations.
The advanced orbit() accessor remains available when code intentionally works with
render.camera.OrbitCamera or render.Quaternion directly.
Reload¶
requestReload() defers the request. The next safe frame boundary performs stop-work → dispose() → service release → fresh services → configure() → setupScene().