extends SceneTree ## Synthetic ownership/lifetime/boundary/timing regression for the prepared ## static M2 Mesh resource cache. const CACHE_SCRIPT := preload("res://src/render/m2/m2_mesh_resource_cache_state.gd") const CACHE_PATH := "res://src/render/m2/m2_mesh_resource_cache_state.gd" const LOADER_PATH := "res://src/scenes/streaming/streaming_world_loader.gd" const STATIC_OBSERVER_PATH := "res://src/render/m2/m2_static_build_resource_observer.gd" func _initialize() -> void: var failures: Array[String] = [] _verify_validation_store_lookup_and_replace(failures) _verify_clear_and_diagnostics(failures) _verify_ownership_boundaries(failures) var elapsed_milliseconds := _verify_bounded_timing(failures) if not failures.is_empty(): for failure in failures: push_error("M2_MESH_RESOURCE_CACHE_STATE: %s" % failure) quit(1) return print( "M2_MESH_RESOURCE_CACHE_STATE PASS cases=9 iterations=100 elapsed_ms=%.3f" % elapsed_milliseconds ) quit(0) func _verify_validation_store_lookup_and_replace(failures: Array[String]) -> void: var cache: RefCounted = CACHE_SCRIPT.new() var first_mesh := ArrayMesh.new() var replacement_mesh := ArrayMesh.new() _expect_false(cache.call("store_mesh", "", first_mesh), "empty path rejected", failures) _expect_false(cache.call("store_mesh", "world/a.m2", null), "null Mesh rejected", failures) _expect_true(cache.call("store_mesh", "world/a.m2", first_mesh), "first Mesh stored", failures) _expect_true(cache.call("has_mesh", "world/a.m2"), "stored Mesh observable", failures) _expect_same(cache.call("find_mesh", "world/a.m2"), first_mesh, "exact Mesh retained", failures) _expect_true( cache.call("store_mesh", "world/a.m2", replacement_mesh), "same-path Mesh replaced", failures ) _expect_same( cache.call("find_mesh", "world/a.m2"), replacement_mesh, "replacement Mesh retained", failures ) _expect_equal(int(cache.call("mesh_count")), 1, "replacement keeps one entry", failures) _expect_same(cache.call("find_mesh", "world/missing.m2"), null, "unknown path returns null", failures) func _verify_clear_and_diagnostics(failures: Array[String]) -> void: var cache: RefCounted = CACHE_SCRIPT.new() cache.call("store_mesh", "world/a.m2", ArrayMesh.new()) cache.call("store_mesh", "world/b.m2", ArrayMesh.new()) var normalized_paths: Array[String] = cache.call("normalized_paths_snapshot") _expect_equal(normalized_paths.size(), 2, "diagnostic path count", failures) _expect_string_equal(normalized_paths[0], "world/a.m2", "diagnostic insertion order first", failures) _expect_string_equal(normalized_paths[1], "world/b.m2", "diagnostic insertion order second", failures) normalized_paths.clear() _expect_equal(int(cache.call("mesh_count")), 2, "diagnostics detached", failures) cache.call("clear") cache.call("clear") _expect_equal(int(cache.call("mesh_count")), 0, "clear releases all entries", failures) func _verify_ownership_boundaries(failures: Array[String]) -> void: var cache_source := FileAccess.get_file_as_string(CACHE_PATH) var loader_source := FileAccess.get_file_as_string(LOADER_PATH) var observer_source := FileAccess.get_file_as_string(STATIC_OBSERVER_PATH) _expect_true( loader_source.contains("M2_MESH_RESOURCE_CACHE_STATE_SCRIPT.new()"), "loader composes Mesh cache state", failures ) _expect_false(loader_source.contains("var _m2_mesh_cache:"), "legacy Mesh cache removed", failures) _expect_equal( loader_source.count("_m2_mesh_resource_cache_state.store_mesh("), 2, "two existing stores delegate", failures ) _expect_equal( loader_source.count("_m2_mesh_resource_cache_state.find_mesh(") + observer_source.count("\"find_mesh\""), 2, "two existing lookups delegate", failures ) _expect_equal( loader_source.count("_m2_mesh_resource_cache_state.clear()"), 1, "final shutdown clear delegates", failures ) for retained_loader_rule in [ "ResourceLoader.load_threaded_get(path)", "_m2_mesh_resource_extractor.extract_first_mesh(resource)", "_prepare_m2_mesh_for_runtime(normalized_rel, mesh)", "_m2_prototype_cache_state.mark_model_missing(normalized_rel)", "_m2_prototype_cache_state.adopt_static_prototype(", ]: _expect_true(loader_source.contains(retained_loader_rule), "loader retains %s" % retained_loader_rule, failures) for forbidden_dependency in [ "ResourceLoader.", "FileAccess.", "WorkerThreadPool.", "PackedScene", "Node3D", "M2Builder", "_m2_prototype_cache_state", ]: _expect_false( cache_source.contains(forbidden_dependency), "cache omits %s ownership" % forbidden_dependency, failures ) func _verify_bounded_timing(failures: Array[String]) -> float: var cache: RefCounted = CACHE_SCRIPT.new() var meshes: Array[Mesh] = [] for _path_index in range(256): meshes.append(ArrayMesh.new()) var started_microseconds := Time.get_ticks_usec() for _iteration in range(100): for path_index in range(256): cache.call("store_mesh", "world/model_%d.m2" % path_index, meshes[path_index]) for path_index in range(256): cache.call("find_mesh", "world/model_%d.m2" % path_index) cache.call("clear") var elapsed_milliseconds := float(Time.get_ticks_usec() - started_microseconds) / 1000.0 _expect_true(elapsed_milliseconds < 1000.0, "100 by 256 store/lookups under 1 second", failures) return elapsed_milliseconds func _expect_true(condition: bool, label: String, failures: Array[String]) -> void: if not condition: failures.append(label) func _expect_false(condition: bool, label: String, failures: Array[String]) -> void: _expect_true(not condition, label, failures) func _expect_equal(actual: int, expected: int, label: String, failures: Array[String]) -> void: if actual != expected: failures.append("%s expected=%d actual=%d" % [label, expected, actual]) func _expect_string_equal(actual: String, expected: String, label: String, failures: Array[String]) -> void: if actual != expected: failures.append("%s expected=%s actual=%s" % [label, expected, actual]) func _expect_same(actual: Variant, expected: Variant, label: String, failures: Array[String]) -> void: if not is_same(actual, expected): failures.append(label)