98 lines
3.2 KiB
GDScript
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)
|