extends SceneTree
## Godot end of scripts/gate_undersea_bridge.py — the undersea scene in a REAL
## blender-bridge session, Godot leading (what "Open in Blender" does in the editor).
##
## -- <scratch> <socket> <shm>
## godot_ready the bridge is listening and expects a Godot-led Blender for
## UnderseaGeissGraph.SCENE (it pushes the scene on that bind)
## cmd_report <tag> -> undersea_state.json {clients, nodes, knobs}, ack_report_<tag>
## cmd_quit stop and exit
##
## The scene instance is never processed: ProcGeometryNode would otherwise evaluate a
## density graph every frame for nothing. The bridge writes its graph regardless.
var _dir := ""
var _bridge: Node
var _scene: Node
var _frames := 0
var _seen := ""
func _init() -> void:
var a := OS.get_cmdline_user_args()
if a.size() < 3:
push_error("undersea_bridge_driver: -- <scratch> <socket> <shm>")
quit(2)
return
_dir = a[0]
_scene = (load(UnderseaGeissGraph.SCENE) as PackedScene).instantiate()
_scene.process_mode = Node.PROCESS_MODE_DISABLED
get_root().add_child(_scene)
_bridge = ClassDB.instantiate("BlenderBridge")
_bridge.name = "BlenderBridge"
get_root().add_child(_bridge)
_bridge.set_shm_name(a[2])
_bridge.start_server(a[1])
_bridge.expect_godot_led(UnderseaGeissGraph.SCENE, _scene)
_bridge.auto_sync = true
process_frame.connect(_tick)
_write("godot_ready", "1")
func _tick() -> void:
_frames += 1
if _frames > 200000: # a driver that outlives its gate is a hung CI job
push_error("undersea_bridge_driver: no cmd_quit, giving up")
quit(3)
return
var tag := _read("cmd_report")
if tag != "" and tag != _seen:
_seen = tag
var holder := _scene.get_node_or_null(UnderseaGeissGraph.HOLDER)
var g := holder.get("graph") as ProcNodeGraph if holder != null else null
var knobs := {}
var kf := UnderseaGeissGraph.knobs_from(g)
for k: String in kf:
knobs[k] = var_to_str(kf[k])
_write("undersea_state.json", JSON.stringify({
"clients": _bridge.get_client_count(),
"nodes": g.get_node_count() if g != null else -1,
"knobs": knobs,
}))
_write("ack_report_" + tag, "1")
if FileAccess.file_exists(_dir.path_join("cmd_quit")):
_bridge.auto_sync = false
_bridge.stop_server()
quit(0)
func _read(name: String) -> String:
var p := _dir.path_join(name)
return FileAccess.get_file_as_string(p).strip_edges() if FileAccess.file_exists(p) else ""
func _write(name: String, text: String) -> void:
var f := FileAccess.open(_dir.path_join(name), FileAccess.WRITE)
f.store_string(text)
f.close()