Files
open-wc/docs/modules/m2-mesh-resource-finalizer.md
T

11 KiB

M2 Mesh Resource Finalizer

Metadata

Field Value
Status Implemented extraction
Target/work package M03 / M03-RND-M2-MESH-RESOURCE-FINALIZER-001
Owners Static M2 terminal Resource I/O, Mesh preparation and cache outcome
Last verified Worktree work/sindo-main-codex/m03-m2-mesh-resource-finalizer, 2026-07-18
Profiles/capabilities Existing cached/static MultiMesh M2 path

Purpose

Drain static M2 ResourceLoader work and publish a prepared Mesh or missing-model outcome without keeping terminal I/O and refresh logic in StreamingWorldLoader. The same preparation method serves threaded and synchronous Mesh consumers.

Non-goals

  • Select cache candidates or admit threaded ResourceLoader requests.
  • Own scheduler permits, prototype Nodes, MultiMeshes or SceneTree roots.
  • Change first-Mesh traversal, refresh version, rebuild rules or raw parser.
  • Merge static and animated terminal services through callbacks/frameworks.
  • Change cache formats, profiles or visible output.

Context and boundaries

flowchart LR
    Observer[M2StaticBuildResourceObserver] --> Pipeline[M2MeshLoadPipelineState]
    Loader[StreamingWorldLoader] --> Finalizer[M2MeshResourceFinalizer]
    Pipeline --> Finalizer
    ResourceLoader --> Finalizer
    Finalizer --> Extractor[M2MeshResourceExtractor]
    Finalizer --> Runtime[M2RuntimeMeshFinalizer]
    Finalizer --> Raw[M2RawModelRepository]
    Finalizer --> MeshCache[M2MeshResourceCacheState]
    Finalizer --> Prototype[M2PrototypeCacheState]

Public API

Symbol Kind Purpose Failure behavior
poll_terminal_requests(pipeline, prototype_cache) I/O command Move LOADED/FAILED records into completion FIFO Invalid composition returns zero
finalize_next_resource(pipeline, mesh_cache, prototype_cache, extracted_dir) I/O command Pop one record and publish Mesh/missing outcome Empty/invalid composition returns false
prepare_mesh_for_runtime(path, mesh, extracted_dir) I/O preparation Preserve current Mesh or load raw data and refresh stale Mesh Null returns null
load_threaded_get_status(path) I/O adapter Production status query with injectable test seam Returns ResourceLoader status
load_threaded_get(path) I/O adapter Production terminal Resource retrieval with injectable test seam May return null

Inputs and outputs

Direction Data Producer Consumer Ownership/lifetime
Input Pending/finalize records Mesh pipeline Finalizer Pipeline-owned copied Dictionaries
Input Terminal Resource ResourceLoader Mesh extractor Borrowed one operation
Input Extracted/cached Mesh Mesh extractor/loader consumer Runtime preparation Borrowed Resource reference
Input Raw M2 Dictionary Raw repository Runtime finalizer Call-local value
Output Prepared Mesh Runtime finalizer Mesh cache/loader consumer Resource reference
Output Missing-model outcome Finalizer Prototype cache Copied path; loader session
Output Processed-record flag Finalizer Loader permit loop/tests Boolean value

Data flow

flowchart TD
    Poll[Poll pending records in insertion order] --> Path{Resource path empty?}
    Path -->|yes| Discard[Discard and mark missing]
    Path -->|no| Status{LOADED or FAILED?}
    Status -->|no| Pending[Keep pending]
    Status -->|yes| Complete[Append completion FIFO]
    Complete --> Permit[Loader consumes M2_MESH_FINALIZE permit]
    Permit --> Pop[Pop oldest terminal record]
    Pop --> Cached{Empty path or Mesh cached?}
    Cached -->|yes| Skip[Finish one permit operation]
    Cached -->|no| Loaded{Status LOADED?}
    Loaded -->|no| Missing[Mark model missing]
    Loaded -->|yes| Get[Get terminal Resource]
    Get --> Extract[Extract first Mesh]
    Extract --> Found{Mesh found?}
    Found -->|no| Missing
    Found -->|yes| Current{Refresh version current?}
    Current -->|yes| Store[Store exact Mesh]
    Current -->|no| Raw[Read raw M2 data]
    Raw --> Refresh[Finalize/rebuild/fallback Mesh]
    Refresh --> Store

Lifecycle/state

stateDiagram-v2
    [*] --> Polling
    Polling --> Pending: nonterminal status
    Polling --> TerminalQueued: LOADED or FAILED
    Polling --> Missing: empty Resource path
    TerminalQueued --> Skipped: empty/cached record
    TerminalQueued --> Missing: failed load or no Mesh
    TerminalQueued --> Extracted: Mesh found
    Extracted --> Current: refresh version current
    Extracted --> Refreshing: stale Mesh
    Refreshing --> Prepared: rebuild or fallback
    Current --> Cached
    Prepared --> Cached
    Pending --> [*]
    Skipped --> [*]
    Missing --> [*]
    Cached --> [*]

Main sequence

sequenceDiagram
    participant L as StreamingWorldLoader
    participant F as M2MeshResourceFinalizer
    participant P as M2MeshLoadPipelineState
    participant R as ResourceLoader
    participant E as M2MeshResourceExtractor
    participant N as M2RuntimeMeshFinalizer
    participant C as M2MeshResourceCacheState
    L->>F: poll_terminal_requests(P, prototype cache)
    F->>R: load_threaded_get_status(path)
    F->>P: complete terminal request
    L->>L: consume M2_MESH_FINALIZE permit
    L->>F: finalize_next_resource(...)
    F->>P: pop oldest record
    F->>R: load_threaded_get(path)
    F->>E: extract_first_mesh(Resource)
    F->>N: requires_raw_data_for_refresh(Mesh)
    opt stale Mesh
        F->>F: read raw M2 data
        F->>N: finalize_mesh(...)
    end
    F->>C: store prepared Mesh

Dependency diagram

flowchart TB
    Finalizer[M2MeshResourceFinalizer] --> ResourceLoader
    Finalizer --> Pipeline[M2MeshLoadPipelineState]
    Finalizer --> Extractor[M2MeshResourceExtractor]
    Finalizer --> Runtime[M2RuntimeMeshFinalizer]
    Finalizer --> Raw[M2RawModelRepository]
    Finalizer --> MeshCache[M2MeshResourceCacheState]
    Finalizer --> Prototype[M2PrototypeCacheState]
    Loader[StreamingWorldLoader] --> Finalizer
    Loader --> Scheduler[RenderBudgetScheduler]
    Finalizer -. no dependency .-> Scheduler
    Finalizer -. no dependency .-> MultiMesh
    Finalizer -. no dependency .-> SceneTree

Ownership, threading and resources

  • All operations run synchronously on the renderer main thread.
  • Pipeline owns pending/completion records; one permit pops one terminal record.
  • Extractor owns temporary PackedScene instance cleanup and returns a Mesh reference.
  • Runtime finalizer owns stale/current/rebuild/fallback rules; raw repository owns only call-local native I/O.
  • Mesh cache retains prepared Mesh references until final shutdown; prototype cache retains missing-model paths.
  • Service retains dependency references but no pending record, Resource, Mesh or raw Dictionary between calls. Loader retains permits and materialization.

Errors, cancellation and recovery

Failure/state Behavior Recovery
Missing composition dependency Return zero/false; preparation keeps Mesh where possible Correct composition
Empty Resource path Discard request and mark missing Repair cache and restart session
Nonterminal status Keep pending Poll next tick
FAILED status Pop and mark missing Repair cache and restart session
Existing cached Mesh Pop and skip terminal Resource get None
Null/unsupported/no-Mesh Resource Mark missing Repair imported cache
Raw read/rebuild unavailable Runtime finalizer marks/reuses original Mesh Existing fallback
Tile cancellation Shared cache work continues Loader queue remains authoritative
Shutdown Loader drains ResourceLoader before pipeline/cache clear New loader starts empty

Configuration and capabilities

The service consumes the existing extracted directory. The scheduler retains m2_mesh_finalize_ops_per_tick; material refresh version remains 2.

Persistence, cache and migration

No cache path, schema or version changes are introduced. Existing .tscn/.glb Resources and in-memory refresh metadata remain compatible; no rebake is required.

Diagnostics and observability

The service adds no log. Existing pending-plus-finalize metrics and refresh metadata remain unchanged. Normalized relative path remains the correlation key.

Verification

  • Dedicated verifier covers status insertion order, empty-path discard, FIFO, failed/cached/null outcomes, terminal get, exact Mesh identity, stale-only raw read, exact finalizer arguments, cache adoption, source ownership and timing.
  • Pipeline/cache/extractor/runtime-finalizer/raw-repository/prototype/shutdown, facade, internal-access and baseline regressions protect adjacent behavior.
  • Fidelity evidence is exact lifecycle/I/O extraction only; no private asset, original-client visual, leak-pressure or p95/p99 claim is made.

Extension points

Further extraction can move static prototype/material-source construction without changing this terminal Resource contract. Animated finalization remains separate because its candidate-before-material ordering and Node ownership differ.

Capability status

Capability Status Evidence Gap/next step
Static terminal polling/load Implemented extraction Status/FIFO/load/source verifier Asset-backed traversal pending
Mesh extraction/preparation/cache outcome Implemented extraction Identity/raw/finalizer/store verifier Private leak/p95/p99 pending
Static MultiMesh materialization Separate implemented service Materializer verifier GPU/asset-backed evidence pending

Known gaps and risks

  • Terminal Resource get, extraction and stale rebuild remain synchronous main-thread work.
  • Prepared Mesh cache remains unbounded until final shutdown.
  • Private asset traversal, descriptor pressure, leak and p95/p99 evidence is absent.

Source map

Path Responsibility
src/render/m2/m2_mesh_resource_finalizer.gd Poll/load/extract/prepare/cache/missing service
src/render/m2/m2_mesh_load_pipeline_state.gd Pending and completion FIFO ownership
src/render/m2/m2_mesh_resource_extractor.gd First-Mesh and temporary-instance ownership
src/render/m2/m2_runtime_mesh_finalizer.gd Refresh/rebuild/fallback rules
src/render/m2/m2_raw_model_repository.gd Optional native raw M2 boundary
src/render/m2/m2_mesh_resource_cache_state.gd Prepared Mesh ownership
src/render/m2/m2_prototype_cache_state.gd Missing-model outcome ownership
src/scenes/streaming/streaming_world_loader.gd Permit loop and materialization composition
src/tools/verify_m2_mesh_resource_finalizer.gd Polling/preparation/boundary/timing regression