refactor(M03): extract M2 mesh load pipeline state

Work-Package: M03-RND-M2-MESH-LOAD-PIPELINE-001
Agent: sindo-main-codex
Tests: 34 headless contract regressions pass; documentation and coordination gates pass; checkpoint dry-run 7/7
Fidelity: preserves request insertion polling order, terminal completion FIFO/statuses, metrics and clear/shutdown behavior; no visual parity claim
This commit is contained in:
2026-07-17 10:23:52 +04:00
parent 5f6287905c
commit 82df7a555d
9 changed files with 543 additions and 25 deletions
+18 -24
View File
@@ -63,6 +63,9 @@ const M2_BUILD_BATCH_PLANNER_SCRIPT := preload(
const M2_RUNTIME_MESH_REBUILD_CLASSIFIER_SCRIPT := preload(
"res://src/render/m2/m2_runtime_mesh_rebuild_classifier.gd"
)
const M2_MESH_LOAD_PIPELINE_STATE_SCRIPT := preload(
"res://src/render/m2/m2_mesh_load_pipeline_state.gd"
)
const STREAMING_TARGET_PLANNER_SCRIPT := preload("res://src/render/streaming/streaming_target_planner.gd")
const STREAMING_TARGET_POLICY_SCRIPT := preload("res://src/render/streaming/streaming_target_policy.gd")
const RENDER_BUDGET_SCHEDULER_SCRIPT := preload("res://src/render/streaming/render_budget_scheduler.gd")
@@ -254,8 +257,7 @@ var _m2_runtime_mesh_rebuild_classifier := (
M2_RUNTIME_MESH_REBUILD_CLASSIFIER_SCRIPT.new()
)
var _m2_mesh_cache: Dictionary = {}
var _m2_mesh_load_requests: Dictionary = {}
var _m2_mesh_finalize_queue: Array = []
var _m2_mesh_load_pipeline_state := M2_MESH_LOAD_PIPELINE_STATE_SCRIPT.new()
var _m2_animation_load_requests: Dictionary = {}
var _m2_animation_finalize_queue: Array = []
var _wmo_build_jobs: Dictionary = {}
@@ -1011,7 +1013,7 @@ func _log_hitch_profile(start_usec: int, timings: Array[String], did_refresh: bo
_detail_asset_queue.size(),
_m2_group_tasks.size(),
_m2_animation_finalize_queue.size() + _m2_animation_load_requests.size(),
_m2_mesh_finalize_queue.size() + _m2_mesh_load_requests.size(),
_m2_mesh_load_pipeline_state.total_work_count(),
_m2_build_queue.size(),
(
_wmo_build_queue.size()
@@ -1042,7 +1044,7 @@ func render_baseline_snapshot() -> Dictionary:
"detail": _detail_asset_queue.size(),
"m2_task": _m2_group_tasks.size(),
"m2_animation": _m2_animation_finalize_queue.size() + _m2_animation_load_requests.size(),
"m2_mesh": _m2_mesh_finalize_queue.size() + _m2_mesh_load_requests.size(),
"m2_mesh": _m2_mesh_load_pipeline_state.total_work_count(),
"m2_build": _m2_build_queue.size(),
"wmo_build": (
_wmo_build_queue.size()
@@ -1328,7 +1330,7 @@ func _tick_runtime_stats(delta: float) -> void:
_detail_asset_queue.size(),
_m2_group_tasks.size(),
_m2_animation_finalize_queue.size() + _m2_animation_load_requests.size(),
_m2_mesh_finalize_queue.size() + _m2_mesh_load_requests.size(),
_m2_mesh_load_pipeline_state.total_work_count(),
_m2_build_queue.size(),
(
_wmo_build_queue.size()
@@ -2338,15 +2340,14 @@ func _wait_for_tile_tasks() -> void:
_m2_group_result_queue.clear()
_m2_group_result_mutex.unlock()
for pending in _m2_mesh_load_requests.values():
for pending in _m2_mesh_load_pipeline_state.request_records_snapshot():
var path: String = String(pending.get("path", ""))
if path.is_empty():
continue
var status := ResourceLoader.load_threaded_get_status(path)
if status == ResourceLoader.THREAD_LOAD_IN_PROGRESS or status == ResourceLoader.THREAD_LOAD_LOADED:
ResourceLoader.load_threaded_get(path)
_m2_mesh_load_requests.clear()
_m2_mesh_finalize_queue.clear()
_m2_mesh_load_pipeline_state.clear()
_m2_runtime_mesh_rebuild_classifier.clear()
for pending in _m2_animation_load_requests.values():
@@ -2996,8 +2997,7 @@ func _clear_streamed_world() -> void:
_cancel_m2_build_job(String(key))
_m2_build_queue.clear()
_m2_unique_placement_registry.clear()
_m2_mesh_load_requests.clear()
_m2_mesh_finalize_queue.clear()
_m2_mesh_load_pipeline_state.clear()
_m2_runtime_mesh_rebuild_classifier.clear()
_m2_animation_load_requests.clear()
_m2_animation_finalize_queue.clear()
@@ -4247,24 +4247,21 @@ func _drain_m2_animation_loads() -> void:
func _drain_m2_mesh_loads() -> void:
for normalized_rel_variant in _m2_mesh_load_requests.keys():
var normalized_rel := String(normalized_rel_variant)
var pending: Dictionary = _m2_mesh_load_requests[normalized_rel]
for pending in _m2_mesh_load_pipeline_state.request_records_snapshot():
var normalized_rel := String(pending.get("normalized", ""))
var path: String = String(pending.get("path", ""))
if path.is_empty():
_m2_mesh_load_requests.erase(normalized_rel)
_m2_mesh_load_pipeline_state.discard_request(normalized_rel)
_m2_missing_cache[normalized_rel] = true
continue
var status := ResourceLoader.load_threaded_get_status(path)
if status != ResourceLoader.THREAD_LOAD_LOADED and status != ResourceLoader.THREAD_LOAD_FAILED:
continue
pending["status"] = status
_m2_mesh_load_requests.erase(normalized_rel)
_m2_mesh_finalize_queue.append(pending)
_m2_mesh_load_pipeline_state.complete_request(normalized_rel, status)
while not _m2_mesh_finalize_queue.is_empty() and _render_budget_scheduler.try_consume_permit(
while _m2_mesh_load_pipeline_state.has_finalize_record() and _render_budget_scheduler.try_consume_permit(
RENDER_BUDGET_SCHEDULER_SCRIPT.M2_MESH_FINALIZE):
var pending: Dictionary = _m2_mesh_finalize_queue.pop_front()
var pending: Dictionary = _m2_mesh_load_pipeline_state.pop_finalize_record()
var normalized_rel := String(pending.get("normalized", ""))
if normalized_rel.is_empty() or _m2_mesh_cache.has(normalized_rel):
continue
@@ -4620,7 +4617,7 @@ func _get_m2_mesh_or_request(rel_path: String) -> Mesh:
func _request_m2_mesh_load(normalized_rel: String) -> void:
if normalized_rel.is_empty() or _m2_mesh_load_requests.has(normalized_rel):
if normalized_rel.is_empty() or _m2_mesh_load_pipeline_state.has_request(normalized_rel):
return
for cache_res_path in _get_m2_cache_resource_paths(normalized_rel, [".tscn", ".glb"]):
@@ -4634,10 +4631,7 @@ func _request_m2_mesh_load(normalized_rel: String) -> void:
false,
ResourceLoader.CACHE_MODE_REUSE)
if err == OK or err == ERR_BUSY:
_m2_mesh_load_requests[normalized_rel] = {
"normalized": normalized_rel,
"path": cache_res_path,
}
_m2_mesh_load_pipeline_state.remember_request(normalized_rel, cache_res_path)
return
break