104 lines
2.4 KiB
GDScript
104 lines
2.4 KiB
GDScript
# id (int) -> WeakRef(ReedScene)
|
|
var _by_id: Dictionary = {}
|
|
|
|
signal registered(id: int, node: ReedScene)
|
|
signal unregistered(id: int)
|
|
signal conflict(id: int, existing: ReedScene, incoming: ReedScene)
|
|
|
|
# -------------------------
|
|
# 注册
|
|
# -------------------------
|
|
func register(id: int, node: ReedScene) -> bool:
|
|
if id < 0:
|
|
push_error("[SceneRegistry] register(): invalid id (<0): %d" % id)
|
|
return false
|
|
|
|
if node == null:
|
|
push_error("[SceneRegistry] register(): node is null for id=%d" % id)
|
|
return false
|
|
|
|
_cleanup_dead(id)
|
|
|
|
if _by_id.has(id):
|
|
var existing: ReedScene = _by_id[id].get_ref()
|
|
if existing == node:
|
|
return true # 重复注册同一个实例,忽略
|
|
|
|
emit_signal("conflict", id, existing, node)
|
|
push_error(
|
|
"[SceneRegistry] Duplicate id=%d existing=%s incoming=%s"
|
|
% [id, existing, node]
|
|
)
|
|
return false
|
|
|
|
_by_id[id] = weakref(node)
|
|
emit_signal("registered", id, node)
|
|
return true
|
|
|
|
# -------------------------
|
|
# 注销
|
|
# -------------------------
|
|
func unregister(id: int, node: ReedScene = null) -> void:
|
|
if not _by_id.has(id):
|
|
return
|
|
|
|
var existing: ReedScene = _by_id[id].get_ref()
|
|
if node != null and existing != node:
|
|
# 防止误删
|
|
return
|
|
|
|
_by_id.erase(id)
|
|
emit_signal("unregistered", id)
|
|
|
|
# -------------------------
|
|
# 查询
|
|
# -------------------------
|
|
func get_scene(id: int) -> ReedScene:
|
|
_cleanup_dead(id)
|
|
var ref: WeakRef = _by_id.get(id)
|
|
return ref.get_ref() if ref else null
|
|
|
|
func has(id: int) -> bool:
|
|
return get_scene(id) != null
|
|
|
|
# -------------------------
|
|
# 调用
|
|
# -------------------------
|
|
func call_scene(id: int, method: String, args: Array = []) -> Variant:
|
|
var n := get_scene(id)
|
|
if n == null:
|
|
push_warning("[SceneRegistry] call_scene(): id not found: %d" % id)
|
|
return null
|
|
|
|
if not n.has_method(method):
|
|
push_warning(
|
|
"[SceneRegistry] call_scene(): id=%d has no method '%s'"
|
|
% [id, method]
|
|
)
|
|
return null
|
|
|
|
return n.callv(method, args)
|
|
|
|
# -------------------------
|
|
# 列表
|
|
# -------------------------
|
|
func list_ids() -> PackedInt32Array:
|
|
for id in _by_id.keys():
|
|
_cleanup_dead(id)
|
|
|
|
var result := PackedInt32Array()
|
|
for id in _by_id.keys():
|
|
result.append(id)
|
|
return result
|
|
|
|
# -------------------------
|
|
# 内部:清理死引用
|
|
# -------------------------
|
|
func _cleanup_dead(id: int) -> void:
|
|
if not _by_id.has(id):
|
|
return
|
|
|
|
var ref: WeakRef = _by_id[id]
|
|
if ref == null or ref.get_ref() == null:
|
|
_by_id.erase(id)
|