render: add M2 build resource snapshot

This commit is contained in:
2026-07-18 02:47:10 +04:00
parent 0decd10e09
commit ec1b90f1e4
14 changed files with 655 additions and 52 deletions
+11 -10
View File
@@ -50,17 +50,14 @@ SceneTree, files, workers, mutexes, gameplay, network and Editor APIs are forbid
| `ACTION_WAIT_FOR_STATIC_MESH` | Constant | Static resource is unresolved and queue must rotate | Immutable | None |
| `ACTION_MATERIALIZE_STATIC` | Constant | Build the selected slice from prepared static Mesh | Immutable | None |
| `ACTION_ADVANCE_WITHOUT_MATERIALIZATION` | Constant | Empty or terminally missing slice advances without a Node | Immutable | None |
| `plan_step(batch_count, animation_pending, has_animated, has_static_mesh, static_missing)` | Pure query | Return action, queue-rotation and serial-transition values | Any thread; call-local result | Raw booleans/count are accepted; non-positive count advances |
| `plan_step(batch_count, resource_snapshot)` | Pure query | Return action, queue-rotation and serial-transition values | Any thread; call-local result | Null snapshot waits for static Mesh; non-positive count advances |
## Inputs and outputs
| Direction | Contract/data | Producer | Consumer | Ownership | Thread/lifetime |
|---|---|---|---|---|---|
| Input | Planned batch count | `M2BuildBatchPlanner` through loader | Dispatch planner | Integer copy | One call |
| Input | Animation request pending | Animation pipeline through loader | Dispatch planner | Boolean copy | One call |
| Input | Animated prototype available | Prototype cache/native loader adapter | Dispatch planner | Boolean copy; no Node reference | One call |
| Input | Static Mesh available | Mesh cache/request adapter | Dispatch planner | Boolean copy; no Mesh reference | One call |
| Input | Static model terminally missing | Prototype cache through loader | Dispatch planner | Boolean copy | One call |
| Input | Typed animated/static availability, pending and missing observations | Loader / `M2BuildResourceSnapshot` | Dispatch planner | Borrowed snapshot; engine references are not read | One call |
| Output | Action | Dispatch planner | Loader materializer/wait branch | Immutable StringName | One operation |
| Output | `rotate_queue` | Dispatch planner | Loader queue adapter | Detached boolean | One operation |
| Output | `increment_batch_serial` | Dispatch planner | Loader progress adapter | Detached boolean | One operation |
@@ -116,7 +113,7 @@ sequenceDiagram
L->>B: plan_batch
L->>L: lookup/request static Mesh when required
end
L->>D: plan_step(observed scalar state)
L->>D: plan_step(batch count, resource snapshot)
D-->>L: action, rotate flag, serial flag
alt wait action
L->>Q: rotate_front
@@ -138,6 +135,7 @@ flowchart TB
Loader --> Queue[M2BuildQueue]
Loader --> Caches[M2 cache/pipeline state]
Loader --> Materializers[M2 materializers]
Dispatch --> Snapshot[M2BuildResourceSnapshot accessors]
Dispatch --> Values[Integers + booleans + StringName]
Dispatch -. no dependency .-> Engine[Node / Mesh / ResourceLoader]
Dispatch -. no dependency .-> State[Queue / cache / scheduler state]
@@ -146,6 +144,8 @@ flowchart TB
## Ownership, threading and resources
- Planner owns call-local comparisons and the returned Dictionary only.
- `M2BuildResourceSnapshot` owns the typed call-local observation contract;
dispatch reads availability/pending/missing accessors but no engine references.
- Loader owns resource lookup/request order, action execution and permit use.
- `M2BuildQueue` owns pending jobs, FIFO keys and progress cursors.
- Materializers own main-thread scene construction under loader-owned roots.
@@ -190,9 +190,9 @@ remain unchanged.
## Extension points
A later package may move resource observation/request execution behind a typed
service while preserving this scalar action contract. Generic callbacks, signals
and a shared state-machine framework remain intentionally excluded.
A later package may move resource observation/request execution behind a service
that produces `M2BuildResourceSnapshot`. Generic callbacks, signals and a shared
state-machine framework remain intentionally excluded.
## Capability status
@@ -205,7 +205,6 @@ and a shared state-machine framework remain intentionally excluded.
## Known gaps and risks
- Planner consumes raw booleans rather than a typed resource snapshot.
- Loader still performs synchronous/native prototype attempts and static request I/O.
- Synthetic timing does not measure ResourceLoader, Node or GPU work.
- Private traversal, leak, visual and p95/p99 evidence remains unavailable.
@@ -215,6 +214,7 @@ and a shared state-machine framework remain intentionally excluded.
| Path | Responsibility |
|---|---|
| `src/render/m2/m2_build_dispatch_planner.gd` | Pure action priority and transition plan |
| `src/render/m2/m2_build_resource_snapshot.gd` | Typed per-step resource observation contract |
| `src/scenes/streaming/streaming_world_loader.gd` | Resource observation, action execution, permits and engine lifetime |
| `src/render/m2/m2_build_batch_planner.gd` | Batch count and cursor plan |
| `src/render/m2/m2_build_queue.gd` | Pending jobs, FIFO and cursor ownership |
@@ -223,6 +223,7 @@ and a shared state-machine framework remain intentionally excluded.
## Related decisions and references
- [`m2-build-batch-planner.md`](m2-build-batch-planner.md)
- [`m2-build-resource-snapshot.md`](m2-build-resource-snapshot.md)
- [`m2-build-queue.md`](m2-build-queue.md)
- [`m2-static-batch-materializer.md`](m2-static-batch-materializer.md)
- [`m2-animated-instance-materializer.md`](m2-animated-instance-materializer.md)