extends SceneTree ## Asset-free terminal-I/O, probe validation/lifetime, adoption, boundary and ## timing regression for the cached WMO PackedScene finalizer. const FINALIZER_SCRIPT := preload("res://src/render/wmo/wmo_scene_resource_finalizer.gd") const CACHE_STATE_SCRIPT := preload("res://src/render/wmo/wmo_scene_resource_cache_state.gd") const FINALIZER_PATH := "res://src/render/wmo/wmo_scene_resource_finalizer.gd" const CACHE_STATE_PATH := "res://src/render/wmo/wmo_scene_resource_cache_state.gd" const LOADER_PATH := "res://src/scenes/streaming/streaming_world_loader.gd" class FakeSceneCacheValidator extends RefCounted: var validated_nodes: Array[Node] = [] func is_scene_cache_current(node: Node) -> bool: validated_nodes.append(node) return bool(node.get_meta("current_wmo_cache", false)) class FakeResourceLoaderAdapter extends RefCounted: var status_by_path: Dictionary = {} var resource_by_path: Dictionary = {} var status_paths: Array[String] = [] var loaded_paths: Array[String] = [] func load_threaded_get_status(resource_path: String) -> int: status_paths.append(resource_path) return int(status_by_path.get(resource_path, ResourceLoader.THREAD_LOAD_IN_PROGRESS)) func load_threaded_get(resource_path: String) -> Resource: loaded_paths.append(resource_path) return resource_by_path.get(resource_path) as Resource func _initialize() -> void: var failures: Array[String] = [] _verify_null_and_non_terminal_poll(failures) _verify_failed_and_loaded_poll_order(failures) _verify_loaded_resource_rejections(failures) _verify_current_scene_adoption_and_probe_lifetime(failures) _verify_validation_contract(failures) _verify_source_boundaries(failures) var elapsed_milliseconds := _verify_bounded_timing(failures) if not failures.is_empty(): for failure in failures: push_error("WMO_SCENE_RESOURCE_FINALIZER: %s" % failure) quit(1) return print( "WMO_SCENE_RESOURCE_FINALIZER PASS cases=26 iterations=1000 elapsed_ms=%.3f" % elapsed_milliseconds ) quit(0) func _verify_null_and_non_terminal_poll(failures: Array[String]) -> void: var validator := FakeSceneCacheValidator.new() var adapter := FakeResourceLoaderAdapter.new() var finalizer: RefCounted = FINALIZER_SCRIPT.new(validator, adapter) _expect_equal( int(finalizer.call("poll_terminal_requests", null)), 0, "null cache state rejected", failures ) var cache_state: RefCounted = CACHE_STATE_SCRIPT.new() cache_state.call("remember_request", "world/pending.wmo", "res://cache/pending.tscn") _expect_equal( int(finalizer.call("poll_terminal_requests", cache_state)), 0, "non-terminal request retained", failures ) _expect_true( bool(cache_state.call("has_request", "world/pending.wmo")), "pending state remains", failures ) _expect_string_array( adapter.status_paths, ["res://cache/pending.tscn"], "pending path polled once", failures ) _expect_equal(adapter.loaded_paths.size(), 0, "pending scene not loaded", failures) func _verify_failed_and_loaded_poll_order(failures: Array[String]) -> void: var validator := FakeSceneCacheValidator.new() var adapter := FakeResourceLoaderAdapter.new() var finalizer: RefCounted = FINALIZER_SCRIPT.new(validator, adapter) var current_scene := _packed_scene(true, true, failures) var cache_state: RefCounted = CACHE_STATE_SCRIPT.new() var requests := { "world/pending.wmo": "res://cache/pending.tscn", "world/failed.wmo": "res://cache/failed.tscn", "world/loaded.wmo": "res://cache/loaded.tscn", } for normalized_relative_path in requests: cache_state.call( "remember_request", normalized_relative_path, requests[normalized_relative_path] ) adapter.status_by_path = { "res://cache/failed.tscn": ResourceLoader.THREAD_LOAD_FAILED, "res://cache/loaded.tscn": ResourceLoader.THREAD_LOAD_LOADED, } adapter.resource_by_path["res://cache/loaded.tscn"] = current_scene _expect_equal( int(finalizer.call("poll_terminal_requests", cache_state)), 2, "failed and loaded scenes complete", failures ) _expect_string_array( adapter.status_paths, [ "res://cache/pending.tscn", "res://cache/failed.tscn", "res://cache/loaded.tscn", ], "detached insertion order preserved", failures ) _expect_string_array( adapter.loaded_paths, ["res://cache/loaded.tscn"], "only loaded terminal scene retrieved", failures ) _expect_true( bool(cache_state.call("is_missing", "world/failed.wmo")), "failed request publishes missing", failures ) _expect_true( cache_state.call("scene_for", "world/loaded.wmo") == current_scene, "loaded scene identity adopted", failures ) func _verify_loaded_resource_rejections(failures: Array[String]) -> void: var validator := FakeSceneCacheValidator.new() var adapter := FakeResourceLoaderAdapter.new() var finalizer: RefCounted = FINALIZER_SCRIPT.new(validator, adapter) var rejected_resources := { "null": null, "wrong_type": Resource.new(), "stale": _packed_scene(false, true, failures), "non_node_3d": _packed_scene(true, false, failures), } var cache_state: RefCounted = CACHE_STATE_SCRIPT.new() for rejection_name in rejected_resources: var normalized_relative_path := "world/%s.wmo" % rejection_name var cache_path := "res://cache/%s.tscn" % rejection_name cache_state.call("remember_request", normalized_relative_path, cache_path) adapter.status_by_path[cache_path] = ResourceLoader.THREAD_LOAD_LOADED adapter.resource_by_path[cache_path] = rejected_resources[rejection_name] _expect_equal( int(finalizer.call("poll_terminal_requests", cache_state)), 4, "all invalid loaded Resources complete", failures ) for rejection_name in rejected_resources: _expect_true( bool(cache_state.call("is_missing", "world/%s.wmo" % rejection_name)), "%s loaded Resource publishes missing" % rejection_name, failures ) _expect_equal( validator.validated_nodes.size(), 1, "only Node3D stale scene reaches validator", failures ) _expect_false( is_instance_valid(validator.validated_nodes[0]), "stale validation probe released", failures ) func _verify_current_scene_adoption_and_probe_lifetime(failures: Array[String]) -> void: var validator := FakeSceneCacheValidator.new() var adapter := FakeResourceLoaderAdapter.new() var finalizer: RefCounted = FINALIZER_SCRIPT.new(validator, adapter) var current_scene := _packed_scene(true, true, failures) var cache_state: RefCounted = CACHE_STATE_SCRIPT.new() cache_state.call("remember_request", "world/current.wmo", "res://cache/current.tscn") adapter.status_by_path["res://cache/current.tscn"] = ResourceLoader.THREAD_LOAD_LOADED adapter.resource_by_path["res://cache/current.tscn"] = current_scene finalizer.call("poll_terminal_requests", cache_state) _expect_true( cache_state.call("scene_for", "world/current.wmo") == current_scene, "current PackedScene exact identity adopted", failures ) _expect_equal( validator.validated_nodes.size(), 1, "current scene instantiated exactly once", failures ) _expect_false( is_instance_valid(validator.validated_nodes[0]), "accepted validation probe released", failures ) func _verify_validation_contract(failures: Array[String]) -> void: var validator := FakeSceneCacheValidator.new() var finalizer: RefCounted = FINALIZER_SCRIPT.new(validator) var current_scene := _packed_scene(true, true, failures) _expect_true( bool(finalizer.call("is_scene_cache_current", current_scene)), "current Node3D scene accepted", failures ) _expect_false( bool(finalizer.call("is_scene_cache_current", null)), "null scene rejected", failures ) var missing_validator_finalizer: RefCounted = FINALIZER_SCRIPT.new(null) _expect_false( bool(missing_validator_finalizer.call("is_scene_cache_current", current_scene)), "missing validator rejects scene without instantiation", failures ) func _verify_source_boundaries(failures: Array[String]) -> void: var loader_source := _read_text(LOADER_PATH, failures) var finalizer_source := _read_text(FINALIZER_PATH, failures) var cache_source := _read_text(CACHE_STATE_PATH, failures) _expect_true( loader_source.contains("WMO_SCENE_RESOURCE_FINALIZER_SCRIPT.new("), "loader composes scene finalizer", failures ) _expect_true( loader_source.contains("_wmo_scene_resource_finalizer.poll_terminal_requests("), "loader delegates scene terminal polling", failures ) _expect_false( loader_source.contains("func _is_wmo_scene_cache_current("), "loader releases PackedScene probe validation", failures ) for required_token in [ "ResourceLoader.load_threaded_get_status(resource_path)", "ResourceLoader.load_threaded_get(resource_path)", "scene.instantiate()", "is_scene_cache_current", "instance.free()", "complete_request_with_scene", "complete_request_as_missing", ]: _expect_true( finalizer_source.contains(required_token), "finalizer owns %s" % required_token, failures ) _expect_false( cache_source.contains("ResourceLoader."), "cache state remains free of ResourceLoader", failures ) func _verify_bounded_timing(failures: Array[String]) -> float: var adapter := FakeResourceLoaderAdapter.new() var finalizer: RefCounted = FINALIZER_SCRIPT.new( FakeSceneCacheValidator.new(), adapter ) var started_microseconds := Time.get_ticks_usec() for iteration in range(1000): var cache_state: RefCounted = CACHE_STATE_SCRIPT.new() var normalized_relative_path := "world/object_%d.wmo" % iteration var cache_path := "res://cache/object_%d.tscn" % iteration cache_state.call("remember_request", normalized_relative_path, cache_path) adapter.status_by_path[cache_path] = ResourceLoader.THREAD_LOAD_FAILED finalizer.call("poll_terminal_requests", cache_state) var elapsed_milliseconds := float(Time.get_ticks_usec() - started_microseconds) / 1000.0 if elapsed_milliseconds >= 1000.0: failures.append( "1000 terminal polls took %.3fms (budget < 1000ms)" % elapsed_milliseconds ) return elapsed_milliseconds func _packed_scene( is_current: bool, use_node_3d_root: bool, failures: Array[String] ) -> PackedScene: var root: Node = Node3D.new() if use_node_3d_root else Node.new() root.set_meta("current_wmo_cache", is_current) var scene := PackedScene.new() var pack_error := scene.pack(root) root.free() if pack_error != OK: failures.append("cannot pack synthetic scene: %d" % pack_error) return scene func _read_text(path: String, failures: Array[String]) -> String: var file := FileAccess.open(path, FileAccess.READ) if file == null: failures.append("cannot read %s" % path) return "" var source := file.get_as_text() file.close() return source func _expect_true(value: bool, label: String, failures: Array[String]) -> void: if not value: failures.append(label) func _expect_false(value: bool, label: String, failures: Array[String]) -> void: if value: failures.append(label) func _expect_equal(actual: int, expected: int, label: String, failures: Array[String]) -> void: if actual != expected: failures.append("%s: expected %d, got %d" % [label, expected, actual]) func _expect_string_array( actual: Array, expected: Array, label: String, failures: Array[String] ) -> void: if actual != expected: failures.append("%s: expected %s, got %s" % [label, expected, actual])