Initial Void Bastion 0.20 prototype
This commit is contained in:
commit
7362ca0f02
251 files changed
+29688
No files matched your search
@@ -0,0 +1,148 @@
|
||||
@tool
|
||||
extends RefCounted
|
||||
|
||||
# signal.connect — operates on the currently-edited scene.
|
||||
# Params: {from: "Player", signal: "died", to: ".", method: "_on_player_died"}
|
||||
# Uses CONNECT_PERSIST so the connection is serialized into the .tscn as a [connection] block.
|
||||
static func connect_signal(params: Dictionary) -> Dictionary:
|
||||
var from_path: String = params.get("from", "")
|
||||
var signal_name: String = params.get("signal", "")
|
||||
var to_path: String = params.get("to", "")
|
||||
var method_name: String = params.get("method", "")
|
||||
|
||||
for required in ["from", "signal", "to", "method"]:
|
||||
if params.get(required, "") == "":
|
||||
return _err(-32602, "missing '%s'" % required)
|
||||
|
||||
var root := EditorInterface.get_edited_scene_root()
|
||||
if root == null:
|
||||
return _err(-32001, "no scene open")
|
||||
|
||||
var source: Node = root if from_path == "." else root.get_node_or_null(from_path)
|
||||
if source == null:
|
||||
return _err(-32001, "source node not found: %s" % from_path)
|
||||
var target: Node = root if to_path == "." else root.get_node_or_null(to_path)
|
||||
if target == null:
|
||||
return _err(-32001, "target node not found: %s" % to_path)
|
||||
|
||||
if not source.has_signal(signal_name):
|
||||
return _err(-32602, "%s has no signal '%s'" % [source.get_class(), signal_name])
|
||||
if not target.has_method(method_name):
|
||||
return _err(-32602, "target has no method '%s' — attach a script with it first" % method_name)
|
||||
|
||||
# Arity check: number of non-default signal args must be <= target method arg count.
|
||||
var sig_info := _find_signal(source, signal_name)
|
||||
var method_info := _find_method(target, method_name)
|
||||
if sig_info and method_info:
|
||||
var sig_args: int = (sig_info.args as Array).size()
|
||||
var method_args: int = (method_info.args as Array).size()
|
||||
if method_args < sig_args:
|
||||
return _err(-32602, "arity mismatch: signal '%s' emits %d args, method '%s' accepts %d" %
|
||||
[signal_name, sig_args, method_name, method_args])
|
||||
|
||||
var callable := Callable(target, method_name)
|
||||
if source.is_connected(signal_name, callable):
|
||||
return _ok({"already_connected": true})
|
||||
|
||||
var err := source.connect(signal_name, callable, CONNECT_PERSIST)
|
||||
if err != OK:
|
||||
return _err(-32001, "connect() returned %d" % err)
|
||||
|
||||
EditorInterface.mark_scene_as_unsaved()
|
||||
return _ok({
|
||||
"from": from_path,
|
||||
"signal": signal_name,
|
||||
"to": to_path,
|
||||
"method": method_name,
|
||||
})
|
||||
|
||||
|
||||
# signal.disconnect — remove a specific wiring in the currently-edited scene.
|
||||
# Params: {from, signal, to, method} — same shape as signal.connect.
|
||||
static func disconnect_signal(params: Dictionary) -> Dictionary:
|
||||
for required in ["from", "signal", "to", "method"]:
|
||||
if params.get(required, "") == "":
|
||||
return _err(-32602, "missing '%s'" % required)
|
||||
|
||||
var root := EditorInterface.get_edited_scene_root()
|
||||
if root == null:
|
||||
return _err(-32001, "no scene open")
|
||||
|
||||
var from_path: String = params["from"]
|
||||
var to_path: String = params["to"]
|
||||
var source: Node = root if from_path == "." else root.get_node_or_null(from_path)
|
||||
var target: Node = root if to_path == "." else root.get_node_or_null(to_path)
|
||||
if source == null:
|
||||
return _err(-32001, "source not found: %s" % from_path)
|
||||
if target == null:
|
||||
return _err(-32001, "target not found: %s" % to_path)
|
||||
|
||||
var callable := Callable(target, params["method"])
|
||||
if not source.is_connected(params["signal"], callable):
|
||||
return _err(-32001, "no such connection")
|
||||
source.disconnect(params["signal"], callable)
|
||||
EditorInterface.mark_scene_as_unsaved()
|
||||
return _ok({"disconnected": true})
|
||||
|
||||
|
||||
# signal.list — list outgoing connections on a node in the currently-edited scene.
|
||||
# Params: {node_path, persistent_only?: false}
|
||||
# Returns connections with their flags so callers can distinguish editor-serialized
|
||||
# connections from runtime ones.
|
||||
static func list_signals(params: Dictionary) -> Dictionary:
|
||||
var node_path: String = params.get("node_path", "")
|
||||
var persistent_only: bool = params.get("persistent_only", false)
|
||||
if node_path == "":
|
||||
return _err(-32602, "missing 'node_path'")
|
||||
|
||||
var root := EditorInterface.get_edited_scene_root()
|
||||
if root == null:
|
||||
return _err(-32001, "no scene open")
|
||||
var node: Node = root if node_path == "." else root.get_node_or_null(node_path)
|
||||
if node == null:
|
||||
return _err(-32001, "node not found: %s" % node_path)
|
||||
|
||||
var outgoing: Array = []
|
||||
for sig in node.get_signal_list():
|
||||
var sig_name: String = sig.name
|
||||
for c in node.get_signal_connection_list(sig_name):
|
||||
var flags: int = c.flags
|
||||
var is_persistent: bool = bool(flags & CONNECT_PERSIST)
|
||||
if persistent_only and not is_persistent:
|
||||
continue
|
||||
var cb: Callable = c.callable
|
||||
var target: Object = cb.get_object()
|
||||
var target_path := ""
|
||||
if target is Node and (target == root or root.is_ancestor_of(target)):
|
||||
target_path = String(root.get_path_to(target))
|
||||
outgoing.append({
|
||||
"signal": sig_name,
|
||||
"to": target_path,
|
||||
"to_object": str(target) if target_path == "" else "",
|
||||
"method": cb.get_method(),
|
||||
"flags": flags,
|
||||
"persistent": is_persistent,
|
||||
})
|
||||
return _ok({"node_path": node_path, "outgoing": outgoing})
|
||||
|
||||
|
||||
static func _find_signal(obj: Object, name: String) -> Dictionary:
|
||||
for s in obj.get_signal_list():
|
||||
if s.name == name:
|
||||
return s
|
||||
return {}
|
||||
|
||||
|
||||
static func _find_method(obj: Object, name: String) -> Dictionary:
|
||||
for m in obj.get_method_list():
|
||||
if m.name == name:
|
||||
return m
|
||||
return {}
|
||||
|
||||
|
||||
static func _ok(data) -> Dictionary:
|
||||
return {"data": data}
|
||||
|
||||
|
||||
static func _err(code: int, msg: String) -> Dictionary:
|
||||
return {"error": {"code": code, "message": msg}}
|
||||
Reference in new issue
Block a user