Files
open-wc/src/render/wmo/wmo_scene_resource_finalizer.gd
T

98 lines
3.2 KiB
GDScript

class_name WmoSceneResourceFinalizer
extends RefCounted
## Polls cached WMO PackedScene requests and publishes validated outcomes.
## File-size admission, live fallback and attached Node lifetime remain caller-owned.
var _scene_cache_validator: Object
var _resource_loader_adapter: Object
func _init(
scene_cache_validator: Object,
resource_loader_adapter: Object = null
) -> void:
_scene_cache_validator = scene_cache_validator
_resource_loader_adapter = resource_loader_adapter
## Polls a detached pending snapshot in insertion order. Terminal requests are
## published as the exact validated PackedScene or the historical missing state.
func poll_terminal_requests(scene_resource_cache_state: RefCounted) -> int:
if scene_resource_cache_state == null:
return 0
var completed_request_count := 0
var request_paths: Dictionary = scene_resource_cache_state.call(
"request_paths_snapshot"
)
for normalized_relative_path_variant in request_paths.keys():
var normalized_relative_path := String(normalized_relative_path_variant)
var resource_path := String(request_paths[normalized_relative_path_variant])
var load_status := load_threaded_get_status(resource_path)
if (
load_status != ResourceLoader.THREAD_LOAD_LOADED
and load_status != ResourceLoader.THREAD_LOAD_FAILED
):
continue
if load_status != ResourceLoader.THREAD_LOAD_LOADED:
scene_resource_cache_state.call(
"complete_request_as_missing",
normalized_relative_path
)
completed_request_count += 1
continue
var loaded_resource := load_threaded_get(resource_path)
var loaded_scene := loaded_resource as PackedScene
if is_scene_cache_current(loaded_scene):
scene_resource_cache_state.call(
"complete_request_with_scene",
normalized_relative_path,
loaded_scene
)
else:
scene_resource_cache_state.call(
"complete_request_as_missing",
normalized_relative_path
)
completed_request_count += 1
return completed_request_count
## Instantiates one Node3D probe, delegates the existing WMOBuilder metadata
## check and synchronously releases the probe before returning.
func is_scene_cache_current(scene: PackedScene) -> bool:
if scene == null or _scene_cache_validator == null:
return false
var instantiated_node := scene.instantiate()
if not (instantiated_node is Node3D):
if instantiated_node != null:
instantiated_node.free()
return false
var instance := instantiated_node as Node3D
var is_current := bool(_scene_cache_validator.call(
"is_scene_cache_current",
instance
))
instance.free()
return is_current
## Production ResourceLoader status boundary; injectable for synthetic tests.
func load_threaded_get_status(resource_path: String) -> int:
if _resource_loader_adapter != null:
return int(_resource_loader_adapter.call(
"load_threaded_get_status",
resource_path
))
return ResourceLoader.load_threaded_get_status(resource_path)
## Production ResourceLoader result boundary; injectable for synthetic tests.
func load_threaded_get(resource_path: String) -> Resource:
if _resource_loader_adapter != null:
return _resource_loader_adapter.call(
"load_threaded_get",
resource_path
) as Resource
return ResourceLoader.load_threaded_get(resource_path)