godot-plateformer/addons/reedscene/scene/ReedSceneIDInspector.gd

109 lines
3.2 KiB
GDScript3
Raw Permalink Normal View History

2026-01-01 16:33:32 +08:00
@tool
extends EditorInspectorPlugin
2026-01-02 18:37:09 +08:00
const DB_PATH := "res://addons/reedscene/demo/data_base/GLOBAL_SCENE_ID.tres"
2026-01-01 16:33:32 +08:00
func _can_handle(object) -> bool:
return object is ReedSceneID
2026-01-02 18:37:09 +08:00
func _parse_begin(object) -> void:
var comp := object as ReedSceneID
var parent := comp.get_parent()
var scene := parent if parent is ReedScene else null
var is_scene_valid := scene != null
var is_scene_saved := false
if scene != null:
is_scene_saved = not scene.scene_file_path.is_empty()
# ==============================
# 提示文本(状态说明)
# ==============================
if not is_scene_valid:
var warn := Label.new()
warn.text = "SceneID requires parent to be ReedScene."
warn.modulate = Color(1, 0.6, 0.4)
add_custom_control(warn)
elif not is_scene_saved:
var warn := Label.new()
warn.text = "Please save the scene (.tscn) before requesting a Scene ID."
warn.modulate = Color(1, 0.6, 0.4)
add_custom_control(warn)
# ==============================
# Request 按钮
# ==============================
var btn := Button.new()
btn.text = "Request Scene ID"
btn.disabled = not (is_scene_valid and is_scene_saved)
if not btn.disabled:
btn.pressed.connect(func():
_open_request_dialog(comp)
)
add_custom_control(btn)
func _open_request_dialog(comp: ReedSceneID) -> void:
var dialog := SceneIDRequestDialog.new()
EditorInterface.get_base_control().add_child(dialog)
dialog.request_confirmed.connect(func(prefix: int):
_request_with_prefix(comp, prefix)
dialog.queue_free()
2026-01-01 16:33:32 +08:00
)
2026-01-02 18:37:09 +08:00
dialog.popup_centered(Vector2i(420, 160))
func _request_with_prefix(comp: ReedSceneID, prefix: int) -> void:
var db := load(DB_PATH) as SceneIDDatabase
if not db:
push_error("SceneIDDatabase not found: %s" % DB_PATH)
return
# 1) SceneID 节点的父节点才是 Scene
var scene_node := comp.get_parent()
if scene_node == null:
push_error("Request Scene ID failed: ReedSceneID has no parent.")
return
# 2) 父节点必须是 ReedScene 或其子类
if not (scene_node is ReedScene):
push_error("Request Scene ID failed: parent must be ReedScene (or subclass). Got: %s" % scene_node.get_class())
2026-01-01 16:33:32 +08:00
return
2026-01-02 18:37:09 +08:00
# 3) 父节点必须是一个“保存过的场景”,否则拿不到稳定的 path
var scene_path := scene_node.scene_file_path
if scene_path.is_empty():
push_error("Request Scene ID failed: parent scene has no scene_file_path (scene not saved?).")
2026-01-01 16:33:32 +08:00
return
2026-01-02 18:37:09 +08:00
# 4) 获取 UID这里按你的要求用父节点的 uid
# 注意instance_id 不是跨会话稳定的,如果你未来需要“真正稳定 UID”建议换成 ResourceUID / GUID
var uid := ResourceUID.path_to_uid(scene_path)
# 5) 请求一个可用 ID
var new_id := db.request_new_id(prefix)
if new_id < 0:
push_error("Request Scene ID failed: invalid new_id.")
2026-01-01 16:33:32 +08:00
return
2026-01-02 18:37:09 +08:00
# 6) 注册到数据库(使用父节点的 path + uid + id
var ok: bool = db.register_scene_id(scene_path, uid, new_id)
if not ok:
push_error("Request Scene ID failed: register_scene_id returned false.")
return
# 7) 写回组件
comp.scene_id = new_id
comp.notify_property_list_changed()
# 8) 保存数据库资源
var err := ResourceSaver.save(db, DB_PATH)
if err != OK:
push_error("Failed to save SceneIDDatabase: %s (err=%d)" % [DB_PATH, err])