render: extract WMO scene resource finalizer
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
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)
|
||||
Reference in New Issue
Block a user