render: extract WMO scene resource finalizer

This commit is contained in:
2026-07-18 14:16:49 +04:00
parent 9ba7ca3263
commit 7779e9e75f
12 changed files with 766 additions and 60 deletions
+21 -15
View File
@@ -14,8 +14,9 @@
Own mutually exclusive cached, missing and pending states for normalized WMO
scene paths. The state accepts only caller-validated `PackedScene` references and
records `.tscn` paths for threaded requests whose I/O, size limit and cache
metadata validation remain in `StreamingWorldLoader`.
records `.tscn` paths for threaded requests. Size admission remains in
`StreamingWorldLoader`; terminal I/O/probe validation belongs to
`WmoSceneResourceFinalizer`.
## Non-goals
@@ -33,8 +34,8 @@ flowchart LR
Loader --> State[WmoSceneResourceCacheState]
Loader --> Size[File existence and size limit]
Size --> ResourceLoader[Godot ResourceLoader]
ResourceLoader --> Loader
Loader --> Probe[Instantiate, metadata/version check, free]
ResourceLoader --> Finalizer[WmoSceneResourceFinalizer]
Finalizer --> Probe[Instantiate, metadata/version check, free]
Probe -->|accepted PackedScene or missing| State
Loader --> Live[Live-prototype fallback]
```
@@ -82,7 +83,7 @@ flowchart TD
Check -->|allowed| Request[Start threaded request]
Request -->|error| Mark
Request -->|accepted| Remember[remember_request]
Remember --> Poll[Loader polls snapshot]
Remember --> Poll[Scene Resource finalizer polls snapshot]
Poll -->|failure| CompleteMissing[complete as missing]
Poll -->|loaded| Validate[Instantiate and validate cache metadata]
Validate -->|valid| CompleteScene[complete with scene]
@@ -114,24 +115,27 @@ stateDiagram-v2
sequenceDiagram
participant Loader as StreamingWorldLoader
participant State as WmoSceneResourceCacheState
participant Finalizer as WmoSceneResourceFinalizer
participant RL as ResourceLoader
Loader->>State: cached/missing/pending queries
Loader->>Loader: exists and wmo_max_runtime_scene_mb check
Loader->>RL: load_threaded_request(.tscn)
Loader->>State: remember_request(normalized, path)
loop renderer tick
Loader->>State: request_paths_snapshot()
Loader->>RL: load_threaded_get_status(path)
Loader->>Finalizer: poll_terminal_requests(State)
Finalizer->>State: request_paths_snapshot()
Finalizer->>RL: load_threaded_get_status(path)
end
Loader->>RL: load_threaded_get(path)
Loader->>Loader: instantiate, validate WMO metadata, free probe
Loader->>State: complete with scene or as missing
Finalizer->>RL: load_threaded_get(path)
Finalizer->>Finalizer: instantiate, validate WMO metadata, free probe
Finalizer->>State: complete with scene or as missing
```
## Ownership, threading and resources
- State owns three Dictionaries and strong references to accepted PackedScenes.
- Loader owns paths, file measurement, requests, validation and all Node lifetime.
- Loader owns paths, file measurement, request admission and placed Nodes;
finalizer owns terminal I/O and call-local validation-probe lifetime.
- All mutation is serialized on the renderer main thread; no mutex is required.
- Detached request snapshots allow terminal removal while polling.
- Scene instantiation borrows the PackedScene and does not transfer cache ownership.
@@ -143,7 +147,7 @@ sequenceDiagram
| Missing `.tscn` | Loader ResourceLoader existence check | Direct missing state | Transient reset permits later retry |
| Oversize `.tscn` | Loader byte limit | Missing plus unchanged debug log | Raise limit/rebuild, then reset |
| Request-start/load failure | Loader error/status | Direct or terminal missing | Reset and retry later |
| Wrong type/stale metadata | Loader PackedScene/probe validation | Terminal missing; probe freed | Rebuild cache and reset |
| Wrong type/stale metadata | Finalizer PackedScene/probe validation | Terminal missing; probe freed | Rebuild cache and reset |
| Shutdown while pending | Loader drains snapshot | Clear transient, then full cache release | New loader starts absent |
## Configuration and capabilities
@@ -184,8 +188,9 @@ in the loader; the state emits no logs.
| Capability | Status | Evidence | Gap/next step |
|---|---|---|---|
| Cached WMO PackedScene state | Implemented extraction | Lifecycle/source/timing and shutdown verifiers | Asset-backed traversal/leak evidence pending |
| Size and cache metadata validation | Preserved in loader | Source boundary and WMO regressions | Oversize/stale asset fixtures could follow |
| ResourceLoader I/O and live fallback | Partial/loader-owned | Existing runtime behavior | Separate extraction if justified |
| Size admission | Preserved in loader | Source boundary and WMO regressions | Oversize asset fixture could follow |
| Terminal I/O and cache validation | Implemented extraction | Finalizer type/lifetime/source/timing verifier | Serialized stale fixture pending |
| Live fallback | Loader-owned | Existing runtime behavior | Separate extraction if justified |
## Known gaps and risks
@@ -199,7 +204,8 @@ in the loader; the state emits no logs.
| Path | Responsibility |
|---|---|
| `src/render/wmo/wmo_scene_resource_cache_state.gd` | Scene/missing/request state and resets |
| `src/scenes/streaming/streaming_world_loader.gd` | Paths, file limit, requests, validation, fallback and Node lifetime |
| `src/render/wmo/wmo_scene_resource_finalizer.gd` | Terminal I/O, probe validation/lifetime and publication |
| `src/scenes/streaming/streaming_world_loader.gd` | Paths, file limit, request admission, fallback and placed Nodes |
| `src/tools/verify_wmo_scene_resource_cache_state.gd` | State, boundary and timing regression |
| `src/tools/verify_render_runtime_cache_shutdown.gd` | Loader final cache ownership regression |