-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathscene_operations.ts
More file actions
145 lines (133 loc) · 4.75 KB
/
Copy pathscene_operations.ts
File metadata and controls
145 lines (133 loc) · 4.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// src/scene_runtime/protocol/scene_operations.ts
//
// Scene operations dispatcher. Routes typed SceneOperation primitives to
// the existing renderer and layout engine. Converts protocol state changes
// into imperative calls on the scene runtime.
//
// Five primitives per PRIMARY_SPEC.md:
// - ObjectStateChange: mutates object state (material, set_point fields)
// - CursorAttach: attaches/detaches cursor from object
// - SceneChange: transitions scene context
// - LayoutMove: repositions object to new zone
// - TimedWait: starts a timed phase with optional display
//
// Exhaustiveness is enforced at compile time via the 'never' type in the
// default case.
//
// Integration gaps (documented inline): if a renderer surface is missing
// for a primitive, the dep is a no-op stub with a console.warn.
//
// References:
// - src/shell/adapter/types.ts (SceneOperation discriminated union)
// - docs/specs/PROTOCOL_VOCABULARY.md (scene_operation primitives)
// - docs/PRIMARY_SPEC.md (scene operations section)
// - src/scene_runtime/renderer/index.ts (existing renderer exports)
import type {
SceneOperation,
ObjectStateChangeOp,
CursorAttachOp,
SceneChangeOp,
LayoutMoveOp,
TimedWaitOp,
} from "../../shell/adapter/types";
//============================================
// Dependency interface (injected, not hard-imported)
//============================================
/**
* Injected renderer-facing dependencies.
* Minimal call signatures to avoid hard import cycles.
* Each dep corresponds to one scene operation primitive.
*/
export interface SceneOpDeps {
/**
* Apply ObjectStateChange to a target object.
* Mutates object state fields: material_name, material_volume,
* held_material_name, held_material_volume, set_volume, set_temperature,
* set_rpm, etc. Called after the interaction is validated.
*/
apply_object_state(op: ObjectStateChangeOp): void;
/**
* Attach or detach cursor from a target object.
* CursorAttach is used to show that an object is "held" by the cursor.
* Integration gap: if renderer has no cursor attachment surface,
* this dep is a no-op stub with a console.warn.
*/
apply_cursor_attach(op: CursorAttachOp): void;
/**
* Transition scene context.
* Loads a new scene by name and renders it. Invalidates all
* target references; scene adapter resolves new targets.
*/
apply_scene_change(op: SceneChangeOp): void;
/**
* Move object to a new layout zone.
* Repositions a scene object within the layout grid.
* Integration gap: if layout engine is read-only from protocol,
* this dep is a no-op stub with a console.warn.
*/
apply_layout_move(op: LayoutMoveOp): void;
/**
* Start a timed phase.
* Begin a duration-based delay (e.g. incubation, aspiration).
* Optional display text (e.g. "Incubating...") may be shown.
* Integration gap: if no timed-wait display surface exists,
* this dep is a no-op stub with a console.warn.
*/
start_timed_wait(op: TimedWaitOp): void;
}
//============================================
// Handler factory
//============================================
/**
* Create a scene operation handler from injected dependencies.
* Returns a function that switches on op.type with compile-time exhaustiveness.
* Unknown types cause a TypeScript error (never type in default case).
*
* No DOM access. No event emission (that is the runtime's job).
*
* @param deps Injected renderer-facing dependency functions
* @returns Handler function that dispatches scene operations
*/
export function create_scene_op_handler(deps: SceneOpDeps): SceneOpHandler {
function handler(op: SceneOperation): void {
switch (op.type) {
case "ObjectStateChange": {
deps.apply_object_state(op);
break;
}
case "CursorAttach": {
deps.apply_cursor_attach(op);
break;
}
case "SceneChange": {
deps.apply_scene_change(op);
break;
}
case "LayoutMove": {
deps.apply_layout_move(op);
break;
}
case "TimedWait": {
deps.start_timed_wait(op);
break;
}
default: {
// Compile-time exhaustiveness: if a new SceneOperation type is added
// to the union, this default case will never be reached (TypeScript
// error). This ensures every primitive is routed explicitly.
const exhaustive_check: never = op;
throw new Error(
`Unknown scene operation type: ${String((exhaustive_check as SceneOperation).type)}`,
);
}
}
}
return handler;
}
//============================================
// Public handler type
//============================================
/**
* A scene operation handler routes a single SceneOperation to the renderer.
*/
export type SceneOpHandler = (op: SceneOperation) => void;