Files
open-wc/docs/modules/m2-raw-model-repository.md
T

10 KiB

M2 Raw Model Repository

Metadata

Field Value
Status Implemented extraction
Target/work package M03 / M03-RND-M2-RAW-MODEL-REPOSITORY-001
Owners Native M2Loader availability, file existence and raw Dictionary loading
Last verified Worktree work/sindo-main-codex/m03-m2-raw-model-repository, 2026-07-17
Profiles/capabilities Static and native-animated raw M2 reads

Purpose

Provide one stateless boundary between renderer orchestration and the optional native M2Loader. The repository resolves an extracted path and returns the raw static or animated Dictionary consumed by existing builders and classifiers.

Non-goals

  • Normalize relative paths or choose .tscn/.glb cache fallbacks.
  • Cache successful data, missing paths, Meshes, Nodes or animation decisions.
  • Build geometry/materials, own queues or attach renderer objects.
  • Change native parsing, cache formats, retry policy or visible behavior.

Context and boundaries

flowchart LR
    Loader[StreamingWorldLoader] --> Repository[M2RawModelRepository]
    Repository --> File[Extracted M2 file]
    Repository --> Native[ClassDB M2Loader]
    Native --> Raw[Raw Dictionary]
    Raw --> Loader
    Loader --> Builder[Existing M2 builders/finalizer]

Allowed dependencies are ProjectSettings, FileAccess and ClassDB for the native file boundary. Resource caches, builders, SceneTree types, worker pools, renderer policy and other application layers are forbidden.

Public API

Symbol Kind Purpose Thread/lifetime Errors
load_static_model_data(extracted_directory, normalized_relative_path) Query Invoke native load_m2 for one existing extracted file Synchronous; stateless Returns {} for rejected/unavailable/invalid result
load_animated_model_data(extracted_directory, normalized_relative_path) Query Invoke native load_m2_animated for one existing extracted file Synchronous; stateless Returns {} for rejected/unavailable/invalid result

Inputs and outputs

Direction Contract/data Producer Consumer Ownership Thread/lifetime
Input Extracted directory String Loader configuration Repository path resolution Copied value One call
Input Already-normalized relative M2 path String Loader normalization Repository Copied value One call
Input Extracted .m2 bytes Local legal extraction Native M2Loader File-owned Native call
Output Static raw M2 Dictionary Native load_m2 Loader/finalizer/M2Builder Fresh native result One caller operation
Output Animated raw M2 Dictionary Native load_m2_animated Loader/animated builder Fresh native result One caller operation
Output Empty Dictionary Repository guards Loader fallback and prototype outcome adapter Fresh value One failed call

Side effects are limited to file-existence inspection, synchronous native file parsing and creation of one temporary native loader instance per accepted call.

Data flow

flowchart TD
    Request[Directory plus normalized path] --> Empty{Path empty?}
    Empty -->|yes| Reject[Return empty Dictionary]
    Empty -->|no| Class{M2Loader registered?}
    Class -->|no| Reject
    Class -->|yes| Resolve[globalize directory/path join]
    Resolve --> Exists{File exists?}
    Exists -->|no| Reject
    Exists -->|yes| Instance[Instantiate M2Loader]
    Instance --> Method{Instance and method available?}
    Method -->|no| Reject
    Method -->|yes| Parse[Call static or animated method]
    Parse --> Type{Dictionary result?}
    Type -->|no| Reject
    Type -->|yes| Return[Return raw Dictionary]

Lifecycle/state

stateDiagram-v2
    [*] --> Ready: construct repository
    Ready --> Resolving: load request
    Resolving --> Ready: rejected input/unavailable dependency
    Resolving --> Parsing: file and native method available
    Parsing --> Ready: Dictionary or empty result returned
    Ready --> [*]: caller releases reference

No request, result or failure state survives a call.

Main sequence

sequenceDiagram
    participant Loader as StreamingWorldLoader
    participant Repo as M2RawModelRepository
    participant File as FileAccess
    participant Native as M2Loader
    Loader->>Repo: load static/animated(directory, path)
    Repo->>File: file_exists(globalized joined path)
    alt dependency or file unavailable
        Repo-->>Loader: empty Dictionary
    else available
        Repo->>Native: instantiate and call exact native method
        Native-->>Repo: Variant
        Repo-->>Loader: Dictionary or empty Dictionary
    end

Dependency diagram

flowchart TB
    Loader[StreamingWorldLoader] --> Repository[M2RawModelRepository]
    Repository --> ProjectSettings
    Repository --> FileAccess
    Repository --> ClassDB
    ClassDB --> Native[M2Loader extension]
    Loader --> Finalizer[M2RuntimeMeshFinalizer]
    Loader --> StaticBuilder[M2Builder]
    Loader --> AnimatedBuilder[M2NativeAnimatedBuilder]
    Repository -. no dependency .-> Finalizer
    Repository -. no dependency .-> StaticBuilder
    Repository -. no dependency .-> Cache[Renderer caches/queues]

Ownership, threading and resources

  • The repository owns only call-local path, native instance and result values.
  • The loader owns path normalization and fallback selection; M2PrototypeCacheState owns prototype/negative adoption.
  • Native M2Loader owns parsing behavior and returns a new Dictionary value.
  • Calls are synchronous on the caller's thread; current renderer callers use the main thread. The module starts no tasks and touches no SceneTree objects.
  • No file handle, native instance, Dictionary or engine Resource is retained.

Errors, cancellation and recovery

Failure Detection Behavior Diagnostic Recovery
Empty normalized path String guard Return {} Dedicated verifier Correct caller normalization
Native extension absent ClassDB.class_exists Return {} Existing renderer fallback Install/load extension and retry
Extracted file absent FileAccess.file_exists Return {} Prototype cache records historical missing state through loader Restore extraction and start a new loader session
Instance/method absent Null/has_method guard Return {} Source contract verifier Repair extension registration
Parse/non-Dictionary result Result type check Return {} Existing loader fallback Repair asset/parser and retry
Cancellation requested Not supported inside synchronous native call Call completes None Caller controls whether to start call

Configuration and capabilities

Setting/capability Default Profile Runtime mutable Effect
Native class name M2Loader All No Exact GDExtension registration
Static method load_m2 All No Existing static parser path
Animated method load_m2_animated Experimental animated path No Existing native animation parser
Extracted directory Loader extracted_dir Scene configuration Yes, caller-owned Root used for path join

Persistence, cache and migration

The module adds no persistence or cache. Native methods, normalized relative paths and .tscn/.glb/material versions are unchanged, so no migration or rebake is required.

Diagnostics and observability

  • Logs: none; loader retains existing fallback and debug output.
  • Metrics: none; rejected-input timing is verifier-only.
  • Debug views: none.
  • Correlation ID: normalized relative M2 path in the caller.

Verification

  • verify_m2_raw_model_repository.gd covers empty/missing/repeated failures, exact static/animated method ownership, three loader delegations, forbidden dependencies and 10,000 empty-path rejects under one second.
  • Adjacent finalizer/extractor/cache/pipeline/animation/material/shutdown tests protect caller behavior and ownership.
  • Fidelity evidence is structural: exact path join/globalization and native method names are preserved. No proprietary M2 or original-client visual claim is made by this extraction.

Extension points

Future asset-backed verification may add a legal fixture around these value contracts. Caching, asynchronous I/O and parser replacement require separate measured work packages rather than expansion of this repository.

Capability status

Capability Status Evidence Gap/next step
Static raw M2 read Implemented extraction Source/invalid/missing verifier Legal success fixture pending
Native animated raw M2 read Implemented extraction Exact method/source contract Legal animated fixture pending
Stateless failure behavior Verified synthetic Repeated missing call and source boundary Asset-backed corrupt input pending

Known gaps and risks

  • Native parsing remains synchronous and has no mid-call cancellation.
  • The repository deliberately does not distinguish missing dependency, missing file and parser failure; loader fallback behavior historically treats them alike.
  • Proprietary asset traversal, descriptor pressure, p95/p99 and visual comparison remain outside this structural extraction.

Source map

Path Responsibility
src/render/m2/m2_raw_model_repository.gd Stateless native class/file/method boundary
src/render/m2/m2_prototype_cache_state.gd Prototype and negative-result retention
src/scenes/streaming/streaming_world_loader.gd Path normalization, fallback decisions and result consumers
src/native/src/m2_loader.cpp Native static/animated parsing implementation
src/tools/verify_m2_raw_model_repository.gd Rejected-input/source/dependency/timing regression