140 lines
4.3 KiB
GDScript
140 lines
4.3 KiB
GDScript
class_name WmoRenderBuildQueue
|
|
extends RefCounted
|
|
|
|
## Owns pending lightweight-WMO job records and FIFO placement keys.
|
|
|
|
const JOB_SCRIPT := preload("res://src/render/wmo/wmo_render_build_job.gd")
|
|
|
|
var _jobs_by_placement_key: Dictionary = {}
|
|
var _queued_placement_keys: Array[String] = []
|
|
|
|
|
|
## Enqueues a new typed job. Duplicate placement keys replace the keyed job but
|
|
## append another FIFO entry, preserving the loader's historical behavior.
|
|
func enqueue(placement_key: String, root: Node3D, render_resource: Resource) -> bool:
|
|
if placement_key.is_empty() or root == null or render_resource == null:
|
|
return false
|
|
_jobs_by_placement_key[placement_key] = JOB_SCRIPT.new(
|
|
placement_key,
|
|
root,
|
|
render_resource
|
|
)
|
|
_queued_placement_keys.append(placement_key)
|
|
return true
|
|
|
|
|
|
## Returns whether at least one FIFO key, including a stale key, is pending.
|
|
func has_pending() -> bool:
|
|
return not _queued_placement_keys.is_empty()
|
|
|
|
|
|
## Returns the front FIFO key, or an empty String when the queue is empty.
|
|
func front_key() -> String:
|
|
if _queued_placement_keys.is_empty():
|
|
return ""
|
|
return _queued_placement_keys.front()
|
|
|
|
|
|
## Returns whether a FIFO placement key still has a current job record.
|
|
func has_job(placement_key: String) -> bool:
|
|
return _jobs_by_placement_key.has(placement_key)
|
|
|
|
|
|
## Returns the current job record as its engine base type, or null for a stale
|
|
## key. Runtime consumers should prefer the typed accessors below.
|
|
func job_for(placement_key: String) -> RefCounted:
|
|
return _jobs_by_placement_key.get(placement_key, null) as RefCounted
|
|
|
|
|
|
## Returns the borrowed root for a current job, or null for a stale key.
|
|
func root_for(placement_key: String) -> Node3D:
|
|
var job := job_for(placement_key)
|
|
if job == null:
|
|
return null
|
|
return job.call("root") as Node3D
|
|
|
|
|
|
## Returns the borrowed render resource for a current job, or null when stale.
|
|
func render_resource_for(placement_key: String) -> Resource:
|
|
var job := job_for(placement_key)
|
|
if job == null:
|
|
return null
|
|
return job.call("render_resource") as Resource
|
|
|
|
|
|
## Returns the current mesh cursor, or zero for a stale key.
|
|
func mesh_index_for(placement_key: String) -> int:
|
|
var job := job_for(placement_key)
|
|
if job == null:
|
|
return 0
|
|
return int(job.call("mesh_index"))
|
|
|
|
|
|
## Returns the current MultiMesh cursor, or zero for a stale key.
|
|
func multimesh_index_for(placement_key: String) -> int:
|
|
var job := job_for(placement_key)
|
|
if job == null:
|
|
return 0
|
|
return int(job.call("multimesh_index"))
|
|
|
|
|
|
## Adopts both cursors for a current job and returns whether it existed.
|
|
func adopt_cursors(
|
|
placement_key: String,
|
|
next_mesh_index: int,
|
|
next_multimesh_index: int
|
|
) -> bool:
|
|
var job := job_for(placement_key)
|
|
if job == null:
|
|
return false
|
|
job.call("adopt_cursors", next_mesh_index, next_multimesh_index)
|
|
return true
|
|
|
|
|
|
## Pops and returns the front FIFO key, or an empty String when already empty.
|
|
func pop_front() -> String:
|
|
if _queued_placement_keys.is_empty():
|
|
return ""
|
|
return _queued_placement_keys.pop_front()
|
|
|
|
|
|
## Cancels the keyed job and erases only the first matching FIFO key. Returns
|
|
## whether an active job record existed. Engine objects are never freed here.
|
|
func cancel(placement_key: String) -> bool:
|
|
var had_job := _jobs_by_placement_key.has(placement_key)
|
|
_jobs_by_placement_key.erase(placement_key)
|
|
_queued_placement_keys.erase(placement_key)
|
|
return had_job
|
|
|
|
|
|
## Releases all job/key references without freeing referenced engine objects.
|
|
func clear() -> void:
|
|
_jobs_by_placement_key.clear()
|
|
_queued_placement_keys.clear()
|
|
|
|
|
|
## Returns FIFO entry count, including duplicate and stale keys.
|
|
func pending_count() -> int:
|
|
return _queued_placement_keys.size()
|
|
|
|
|
|
## Returns active keyed job count, excluding stale FIFO keys.
|
|
func active_job_count() -> int:
|
|
return _jobs_by_placement_key.size()
|
|
|
|
|
|
## Returns detached FIFO order and placement-key-sorted scalar job diagnostics.
|
|
func diagnostic_snapshot() -> Dictionary:
|
|
var placement_keys: Array = _jobs_by_placement_key.keys()
|
|
placement_keys.sort()
|
|
var jobs: Array[Dictionary] = []
|
|
for placement_key_variant in placement_keys:
|
|
var placement_key := String(placement_key_variant)
|
|
var job: RefCounted = job_for(placement_key)
|
|
if job != null:
|
|
jobs.append(job.call("diagnostic_snapshot") as Dictionary)
|
|
return {
|
|
"queued_placement_keys": _queued_placement_keys.duplicate(),
|
|
"jobs": jobs,
|
|
}
|