From 9b22f6b5c093ca1fa5fd9858d15bf6201d96cbb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Fri, 8 Dec 2023 09:56:01 +0000 Subject: [PATCH] new, new, new, NEW groups (#14) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit groups are now instanced allowing to call them like functions Reviewed-on: https://codeberg.org/Eroax/StreamGraph/pulls/14 Co-authored-by: Lera ElvoƩ Co-committed-by: Lera ElvoƩ --- classes/deck/deck.gd | 147 ++++++++++---- classes/deck/deck_holder.gd | 182 +++++++++++++++++- classes/deck/deck_node.gd | 14 ++ classes/deck/nodes/group_input_node.gd | 3 +- classes/deck/nodes/group_node.gd | 14 +- classes/deck/nodes/group_output_node.gd | 3 +- classes/deck/port.gd | 9 +- graph_node_renderer/debug_decks_list.gd | 26 +++ graph_node_renderer/debug_decks_list.tscn | 6 + graph_node_renderer/deck_holder_renderer.gd | 47 ++++- graph_node_renderer/deck_holder_renderer.tscn | 6 + .../deck_node_renderer_graph_node.gd | 8 +- .../deck_renderer_graph_edit.gd | 2 +- 13 files changed, 403 insertions(+), 64 deletions(-) create mode 100644 graph_node_renderer/debug_decks_list.gd create mode 100644 graph_node_renderer/debug_decks_list.tscn diff --git a/classes/deck/deck.gd b/classes/deck/deck.gd index 88ca228..425c203 100644 --- a/classes/deck/deck.gd +++ b/classes/deck/deck.gd @@ -16,11 +16,13 @@ var save_path: String = "" var is_group: bool = false ## List of groups belonging to this deck, in the format of[br] ## [code]Dictionary[String -> Deck.id, Deck][/code] -var groups: Dictionary = {} -## A unique identifier for this deck. +#var groups: Dictionary = {} +## A unique identifier for this deck, or an ID for the group this deck represents. var id: String = "" +## If this is a group, this is the local ID of this instance of the group. +var instance_id: String = "" ## The parent deck of this deck, if this is a group. -var _belonging_to: Deck # for groups +#var _belonging_to: Deck # for groups ## The ID of this group's input node. Used only if [member is_group] is [code]true[/code]. var group_input_node: String ## The ID of this group's input node. Used only if [member is_group] is [code]true[/code]. @@ -28,13 +30,24 @@ var group_output_node: String ## The ID of the group node this group is represented by, contained in this deck's parent deck. ## Used only if [member is_group] is [code]true[/code]. ## @experimental -var group_node: String +#var group_node: String + +var emit_group_signals: bool = true ## Emitted when a node has been added to this deck. signal node_added(node: DeckNode) ## Emitted when a node has been removed from this deck. signal node_removed(node: DeckNode) +#region group signals +signal node_added_to_group(node: DeckNode, assign_id: String, assign_to_self: bool, deck: Deck) +signal node_removed_from_group(node_id: String, remove_connections: bool, deck: Deck) +signal nodes_connected_in_group(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int, deck: Deck) +signal nodes_disconnected_in_group(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int, deck: Deck) +signal node_port_value_updated(node_id: String, port_idx: int, new_value: Variant, deck: Deck) +signal node_renamed(node_id: String, new_name: String, deck: Deck) +signal node_moved(node_id: String, new_position: Dictionary, deck: Deck) +#endregion ## Instantiate a node by its' [member DeckNode.node_type] and add it to this deck.[br] ## See [method add_node_inst] for parameter descriptions. @@ -62,6 +75,26 @@ func add_node_inst(node: DeckNode, assign_id: String = "", assign_to_self: bool node._id = assign_id node_added.emit(node) + if is_group && emit_group_signals: + node_added_to_group.emit(node, assign_id, assign_to_self, self) + + node.port_value_updated.connect( + func(port_idx: int, new_value: Variant): + if is_group && emit_group_signals: + node_port_value_updated.emit(node._id, port_idx, new_value, self) + ) + + node.renamed.connect( + func(new_name: String): + if is_group && emit_group_signals: + node_renamed.emit(node._id, new_name, self) + ) + + node.position_updated.connect( + func(new_position: Dictionary): + if is_group && emit_group_signals: + node_moved.emit(node._id, new_position, self) + ) return node @@ -84,6 +117,9 @@ func connect_nodes(from_node_id: String, to_node_id: String, from_output_port: i # TODO: prevent duplicate connections + if is_group && emit_group_signals: + nodes_connected_in_group.emit(from_node_id, to_node_id, from_output_port, to_input_port, self) + from_node.add_outgoing_connection(from_output_port, to_node._id, to_input_port) return true @@ -94,6 +130,8 @@ func disconnect_nodes(from_node_id: String, to_node_id: String, from_output_port var to_node := get_node(to_node_id) from_node.remove_outgoing_connection(from_output_port, to_node_id, to_input_port) to_node.remove_incoming_connection(to_input_port) + if is_group && emit_group_signals: + nodes_disconnected_in_group.emit(from_node_id, to_node_id, from_output_port, to_input_port, self) ## Returns true if this deck has no nodes and no variables. @@ -102,11 +140,14 @@ func is_empty() -> bool: ## Remove a node from this deck. -func remove_node(uuid: String, remove_connections: bool = false) -> void: +func remove_node(uuid: String, remove_connections: bool = false, keep_group_instances: bool = false) -> void: var node := get_node(uuid) if node == null: return + if node.node_type == "group_node" && !keep_group_instances: + DeckHolder.close_group_instance(node.group_id, node.group_instance_id) + if remove_connections: var outgoing_connections := node.outgoing_connections.duplicate(true) @@ -125,6 +166,9 @@ func remove_node(uuid: String, remove_connections: bool = false) -> void: node_removed.emit(node) + if is_group && emit_group_signals: + node_removed_from_group.emit(uuid, remove_connections, self) + ## Group the [param nodes_to_group] into a new deck and return it. ## Returns [code]null[/code] on failure.[br] @@ -138,20 +182,17 @@ func group_nodes(nodes_to_group: Array) -> Deck: return x._id ) - var group := Deck.new() - group.is_group = true - group._belonging_to = self - var group_id := UUID.v4() - group.id = group_id + var group := DeckHolder.add_empty_group() var midpoint := Vector2() + var temp := [] for node: DeckNode in nodes_to_group: - if node.node_type == "group_node": # for recursive grouping - var _group_id: String = node.group_id - var _group: Deck = groups[_group_id] - groups.erase(_group) - group.groups[_group_id] = _group - _group._belonging_to = group + #if node.node_type == "group_node": + #var _group_id: String = node.group_id + #var _group: Deck = groups[_group_id] + #groups.erase(_group) + #group.groups[_group_id] = _group + #_group._belonging_to = group var outgoing_connections := node.outgoing_connections.duplicate(true) @@ -169,35 +210,38 @@ func group_nodes(nodes_to_group: Array) -> Deck: disconnect_nodes(from_node, node._id, incoming_connections[to_port][from_node], to_port) midpoint += node.position_as_vector2() - remove_node(node._id) + remove_node(node._id, false, true) group.add_node_inst(node, node._id) midpoint /= nodes_to_group.size() var _group_node := add_node_type("group_node") - _group_node.group_id = group_id + _group_node.group_id = group.id + _group_node.group_instance_id = group.instance_id _group_node.position.x = midpoint.x _group_node.position.y = midpoint.y _group_node.position_updated.emit(_group_node.position) - group.group_node = _group_node._id + #group.group_node = _group_node._id var input_node := group.add_node_type("group_input") var output_node := group.add_node_type("group_output") group.group_input_node = input_node._id group.group_output_node = output_node._id - _group_node.input_node = input_node - _group_node.output_node = output_node - _group_node.setup_connections() + input_node.group_node = _group_node + output_node.group_node = _group_node - groups[group_id] = group + _group_node.input_node_id = input_node._id + _group_node.output_node_id = output_node._id + #_group_node.setup_connections() + _group_node.init_io() return group ## Get a group belonging to this deck by its ID. -func get_group(uuid: String) -> Deck: - return groups.get(uuid) +#func get_group(uuid: String) -> Deck: + #return groups.get(uuid) func copy_nodes(nodes_to_copy: Array[String]) -> Dictionary: @@ -276,6 +320,14 @@ func paste_nodes_from_dict(nodes: Dictionary, position: Vector2 = Vector2()) -> nodes.nodes[node_id].incoming_connections = incoming_connections_res var node := DeckNode.from_dict(nodes.nodes[node_id]) + if node.node_type == "group_node": + var group := DeckHolder.make_new_group_instance(node.group_id) + node.group_instance_id = group.instance_id + group.get_node(group.group_input_node).group_node = node + group.get_node(group.group_output_node).group_node = node + node.input_node = group.get_node(group.group_input_node) + node.output_node = group.get_node(group.group_output_node) + node.init_io() add_node_inst(node, ids_map[node_id]) @@ -298,7 +350,7 @@ func send_event(event_name: StringName, event_data: Dictionary = {}) -> void: ## Returns a [Dictionary] representation of this deck. -func to_dict(with_meta: bool = true) -> Dictionary: +func to_dict(with_meta: bool = true, group_ids: Array = []) -> Dictionary: var inner := { "nodes": {}, "variable_stack": variable_stack, @@ -306,14 +358,18 @@ func to_dict(with_meta: bool = true) -> Dictionary: "groups": {} } - for node_id in nodes.keys(): + for node_id: String in nodes.keys(): inner["nodes"][node_id] = nodes[node_id].to_dict(with_meta) + if (nodes[node_id] as DeckNode).node_type == "group_node": + if !(nodes[node_id].group_id in group_ids): + inner["groups"][nodes[node_id].group_id] = DeckHolder.get_deck(nodes[node_id].group_id).to_dict(with_meta, group_ids) + group_ids.append(nodes[node_id].group_id) - for group_id in groups.keys(): - inner["groups"][group_id] = groups[group_id].to_dict(with_meta) + #for group_id in groups.keys(): + #inner["groups"][group_id] = groups[group_id].to_dict(with_meta) if is_group: - inner["group_node"] = group_node + inner["instance_id"] = instance_id inner["group_input_node"] = group_input_node inner["group_output_node"] = group_output_node @@ -344,14 +400,27 @@ static func from_dict(data: Dictionary, path: String = "") -> Deck: var groups_data: Dictionary = data.deck.groups as Dictionary - for group_id: String in groups_data: - var group := Deck.from_dict(groups_data[group_id]) - group._belonging_to = deck - group.is_group = true - deck.groups[group_id] = group - group.group_node = groups_data[group_id]["deck"]["group_node"] - group.group_input_node = groups_data[group_id]["deck"]["group_input_node"] - group.group_output_node = groups_data[group_id]["deck"]["group_output_node"] - deck.get_node(group.group_node).init_io() + for node_id: String in deck.nodes: + var node := deck.get_node(node_id) + if node.node_type != "group_node": + continue + var group_id: String = node.group_id + var group_instance_id: String = node.group_instance_id + var group_data: Dictionary = groups_data[group_id] + var group := DeckHolder.add_group_from_dict(group_data, group_id, group_instance_id) + group.get_node(group.group_input_node).group_node = node + group.get_node(group.group_output_node).group_node = node + node.init_io() + + #for group_id: String in groups_data: + #var group := Deck.from_dict(groups_data[group_id]) + #group._belonging_to = deck + #group.is_group = true + #deck.groups[group_id] = group + #group.group_node = groups_data[group_id]["deck"]["group_node"] + #group.group_input_node = groups_data[group_id]["deck"]["group_input_node"] + #group.group_output_node = groups_data[group_id]["deck"]["group_output_node"] + #deck.get_node(group.group_node).init_io() + return deck diff --git a/classes/deck/deck_holder.gd b/classes/deck/deck_holder.gd index 86de789..b0b1688 100644 --- a/classes/deck/deck_holder.gd +++ b/classes/deck/deck_holder.gd @@ -3,14 +3,15 @@ class_name DeckHolder ## A static class holding references to all decks opened in the current session. ## List of decks opened this session. -static var decks: Array[Deck] +#static var decks: Array[Deck] +static var decks: Dictionary # Dictionary[String -> id, (Deck|Dictionary[String -> instance_id, Deck])] ## Returns a new empty deck and assigns a new random ID to it. static func add_empty_deck() -> Deck: var deck := Deck.new() - DeckHolder.decks.append(deck) var uuid := UUID.v4() + decks[uuid] = deck deck.id = uuid return deck @@ -21,17 +22,180 @@ static func open_deck_from_file(path: String) -> Deck: if f.get_error() != OK: return null - var deck := Deck.from_dict(JSON.parse_string(f.get_as_text()), path) - DeckHolder.decks.append(deck) - + var deck := open_deck_from_dict(JSON.parse_string(f.get_as_text()), path) return deck +static func open_deck_from_dict(data: Dictionary, path := "") -> Deck: + var deck := Deck.from_dict(data, path) + decks[deck.id] = deck + return deck + + +static func add_group_from_dict(data: Dictionary, deck_id: String, instance_id: String) -> Deck: + var group := Deck.from_dict(data) + group.instance_id = instance_id + group.is_group = true + group.group_input_node = data.deck.group_input_node + group.group_output_node = data.deck.group_output_node + var instances: Dictionary = decks.get(deck_id, {}) + instances[instance_id] = group + decks[deck_id] = instances + connect_group_signals(group) + return group + + +static func make_new_group_instance(group_id: String) -> Deck: + var group := get_deck(group_id) + var data := group.to_dict() + return add_group_from_dict(data, group_id, UUID.v4()) + + +static func add_empty_group() -> Deck: + var group := Deck.new() + group.is_group = true + group.id = UUID.v4() + group.instance_id = UUID.v4() + decks[group.id] = {group.instance_id: group} + connect_group_signals(group) + return group + + +static func connect_group_signals(group: Deck) -> void: + group.node_added_to_group.connect(DeckHolder._on_node_added_to_group) + group.node_removed_from_group.connect(DeckHolder._on_node_removed_from_group) + group.nodes_connected_in_group.connect(DeckHolder._on_nodes_connected_in_group) + group.nodes_disconnected_in_group.connect(DeckHolder._on_nodes_disconnected_in_group) + group.node_port_value_updated.connect(DeckHolder._on_node_port_value_updated) + group.node_renamed.connect(DeckHolder._on_node_renamed) + group.node_moved.connect(DeckHolder._on_node_moved) + + +static func get_deck(id: String) -> Deck: + if !decks.has(id): + return null + + if !(decks[id] is Dictionary): + return decks[id] + else: + return (decks[id] as Dictionary).values()[0] + + +static func get_group_instance(group_id: String, instance_id: String) -> Deck: + if !decks.has(group_id): + return null + + if decks[group_id] is Dictionary: + return (decks[group_id] as Dictionary).get(instance_id) + else: + return null + + +static func close_group_instance(group_id: String, instance_id: String) -> void: + var group_instances: Dictionary = decks.get(group_id, {}) as Dictionary + group_instances.erase(instance_id) + if group_instances.is_empty(): + decks.erase(group_id) + + ## Unloads a deck. -static func close_deck(deck: Deck) -> void: - DeckHolder.decks.erase(deck) +static func close_deck(deck_id: String) -> void: + if decks.get(deck_id) is Deck: + decks.erase(deck_id) static func send_event(event_name: StringName, event_data: Dictionary = {}) -> void: - for deck in decks: - deck.send_event(event_name, event_data) + for deck_id: String in decks: + if decks[deck_id] is Deck: + (decks[deck_id] as Deck).send_event(event_name, event_data) + else: + for deck_instance_id: String in decks[deck_id]: + (decks[deck_id][deck_instance_id] as Deck).send_event(event_name, event_data) + + +#region group signal callbacks +static func _on_node_added_to_group(node: DeckNode, assign_id: String, assign_to_self: bool, deck: Deck) -> void: + var group_id := deck.id + for instance_id: String in decks[group_id]: + if instance_id == deck.instance_id: + continue + + var instance: Deck = get_group_instance(group_id, instance_id) + instance.emit_group_signals = false + var node_duplicate := DeckNode.from_dict(node.to_dict()) + instance.add_node_inst(node_duplicate, assign_id, assign_to_self) + instance.emit_group_signals = true + + +static func _on_node_removed_from_group(node_id: String, remove_connections: bool, deck: Deck) -> void: + var group_id := deck.id + for instance_id: String in decks[group_id]: + if instance_id == deck.instance_id: + continue + + var instance: Deck = get_group_instance(group_id, instance_id) + instance.emit_group_signals = false + instance.remove_node(node_id, remove_connections) + instance.emit_group_signals = true + + +static func _on_nodes_connected_in_group(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int, deck: Deck) -> void: + var group_id := deck.id + for instance_id: String in decks[group_id]: + if instance_id == deck.instance_id: + continue + + var instance: Deck = get_group_instance(group_id, instance_id) + instance.emit_group_signals = false + instance.connect_nodes(from_node_id, to_node_id, from_output_port, to_input_port) + instance.emit_group_signals = true + + +static func _on_nodes_disconnected_in_group(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int, deck: Deck) -> void: + var group_id := deck.id + for instance_id: String in decks[group_id]: + if instance_id == deck.instance_id: + continue + + var instance: Deck = get_group_instance(group_id, instance_id) + instance.emit_group_signals = false + instance.disconnect_nodes(from_node_id, to_node_id, from_output_port, to_input_port) + instance.emit_group_signals = true + + +static func _on_node_port_value_updated(node_id: String, port_idx: int, new_value: Variant, deck: Deck) -> void: + var group_id := deck.id + for instance_id: String in decks[group_id]: + if instance_id == deck.instance_id: + continue + + var instance: Deck = get_group_instance(group_id, instance_id) + instance.emit_group_signals = false + instance.get_node(node_id).get_all_ports()[port_idx].set_value_no_signal(new_value) + instance.emit_group_signals = true + + +static func _on_node_renamed(node_id: String, new_name: String, deck: Deck) -> void: + var group_id := deck.id + for instance_id: String in decks[group_id]: + if instance_id == deck.instance_id: + continue + + var instance: Deck = get_group_instance(group_id, instance_id) + instance.emit_group_signals = false + instance.get_node(node_id).name = new_name + instance.emit_group_signals = true + + +static func _on_node_moved(node_id: String, new_position: Dictionary, deck: Deck) -> void: + var group_id := deck.id + for instance_id: String in decks[group_id]: + if instance_id == deck.instance_id: + continue + + var instance: Deck = get_group_instance(group_id, instance_id) + instance.emit_group_signals = false + instance.get_node(node_id).position = new_position.duplicate() + instance.emit_group_signals = true + +#endregion diff --git a/classes/deck/deck_node.gd b/classes/deck/deck_node.gd index 4f60b17..16aad1a 100644 --- a/classes/deck/deck_node.gd +++ b/classes/deck/deck_node.gd @@ -64,6 +64,10 @@ signal incoming_connection_added(from_port: int) ## Emitted when a connection to this node has been removed. signal incoming_connection_removed(from_port: int) +signal port_value_updated(port_idx: int, new_value: Variant) + +signal renamed(new_name: String) + ## Add an input port to this node. Usually only used at initialization. func add_input_port(type: DeckType.Types, label: String, descriptor: String = "") -> void: @@ -85,10 +89,15 @@ func add_port(type: DeckType.Types, label: String, port_type: PortType, index_of var port := Port.new(type, label, ports.size(), port_type, index_of_type, descriptor) ports.append(port) port_added.emit(ports.size() - 1) + port.value_updated.connect( + func(new_value: Variant) -> void: + port_value_updated.emit(port.index, new_value) + ) ports_updated.emit() ## Remove a port from this node. +## @deprecated func remove_port(port_idx: int) -> void: outgoing_connections.erase(port_idx) incoming_connections.erase(port_idx) @@ -186,6 +195,11 @@ func remove_incoming_connection(to_port: int) -> void: incoming_connection_removed.emit(to_port) +func rename(new_name: String) -> void: + name = new_name + renamed.emit(new_name) + + @warning_ignore("unused_parameter") func _event_received(event_name: StringName, event_data: Dictionary = {}) -> void: pass diff --git a/classes/deck/nodes/group_input_node.gd b/classes/deck/nodes/group_input_node.gd index e2f4dad..93c7f3d 100644 --- a/classes/deck/nodes/group_input_node.gd +++ b/classes/deck/nodes/group_input_node.gd @@ -4,6 +4,8 @@ var output_count: int: get: return get_all_ports().size() - 1 +var group_node: DeckNode + func _init() -> void: name = "Group input" @@ -68,5 +70,4 @@ func _post_load() -> void: func _value_request(from_port: int) -> Variant: - var group_node := _belonging_to._belonging_to.get_node(_belonging_to.group_node) return group_node.request_value(group_node.get_input_ports()[from_port].index_of_type) diff --git a/classes/deck/nodes/group_node.gd b/classes/deck/nodes/group_node.gd index 120c41b..c251003 100644 --- a/classes/deck/nodes/group_node.gd +++ b/classes/deck/nodes/group_node.gd @@ -1,16 +1,20 @@ extends DeckNode var group_id: String +var group_instance_id: String var input_node: DeckNode var output_node: DeckNode +var input_node_id: String +var output_node_id: String + var extra_ports: Array func _init() -> void: name = "Group" node_type = "group_node" - props_to_serialize = [&"group_id", &"extra_ports"] + props_to_serialize = [&"group_id", &"group_instance_id", &"extra_ports", &"input_node_id", &"output_node_id"] appears_in_search = false @@ -24,10 +28,16 @@ func _pre_connection() -> void: func init_io() -> void: - var group: Deck = _belonging_to.groups.get(group_id) as Deck + #var group: Deck = _belonging_to.groups.get(group_id) as Deck + var group := DeckHolder.get_group_instance(group_id, group_instance_id) if !group: return + if input_node && input_node.ports_updated.is_connected(recalculate_ports): + input_node.ports_updated.disconnect(recalculate_ports) + if output_node && output_node.ports_updated.is_connected(recalculate_ports): + output_node.ports_updated.disconnect(recalculate_ports) + input_node = group.get_node(group.group_input_node) output_node = group.get_node(group.group_output_node) diff --git a/classes/deck/nodes/group_output_node.gd b/classes/deck/nodes/group_output_node.gd index 477d90b..baeb7b4 100644 --- a/classes/deck/nodes/group_output_node.gd +++ b/classes/deck/nodes/group_output_node.gd @@ -4,6 +4,8 @@ var input_count: int: get: return get_all_ports().size() - 1 +var group_node: DeckNode + func _init() -> void: name = "Group output" @@ -69,5 +71,4 @@ func _post_load() -> void: func _receive(to_input_port: int, data: Variant, extra_data: Array = []) -> void: - var group_node := _belonging_to._belonging_to.get_node(_belonging_to.group_node) group_node.send(group_node.get_output_ports()[to_input_port].index_of_type, data, extra_data) diff --git a/classes/deck/port.gd b/classes/deck/port.gd index 000c822..4387780 100644 --- a/classes/deck/port.gd +++ b/classes/deck/port.gd @@ -25,7 +25,7 @@ var index_of_type: int var index: int ## The value of this port. -var value: Variant: set = set_value +var value: Variant signal value_updated(new_value: Variant) @@ -50,10 +50,13 @@ func _init( func set_value(v: Variant) -> void: + set_value_no_signal(v) + value_updated.emit(value) + + +func set_value_no_signal(v: Variant) -> void: if v is Callable: value = v.call() - value_updated.emit(value) return value = v - value_updated.emit(value) diff --git a/graph_node_renderer/debug_decks_list.gd b/graph_node_renderer/debug_decks_list.gd new file mode 100644 index 0000000..440754e --- /dev/null +++ b/graph_node_renderer/debug_decks_list.gd @@ -0,0 +1,26 @@ +extends VBoxContainer +class_name DebugDecksList + +signal item_pressed(deck_id: String, instance_id: String) + + +func _ready() -> void: + for i in get_children(): + i.queue_free() + + for deck_id: String in DeckHolder.decks: + if DeckHolder.decks[deck_id] is Deck: + var b := Button.new() + b.text = deck_id + b.pressed.connect(func(): + item_pressed.emit(deck_id, "") + ) + add_child(b) + else: + for instance_id: String in DeckHolder.decks[deck_id]: + var b := Button.new() + b.text = "%s::%s" % [deck_id, instance_id] + b.pressed.connect(func(): + item_pressed.emit(deck_id, instance_id) + ) + add_child(b) diff --git a/graph_node_renderer/debug_decks_list.tscn b/graph_node_renderer/debug_decks_list.tscn new file mode 100644 index 0000000..ef38b89 --- /dev/null +++ b/graph_node_renderer/debug_decks_list.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://dm7sc6364j84i"] + +[ext_resource type="Script" path="res://graph_node_renderer/debug_decks_list.gd" id="1_etp6v"] + +[node name="DebugDecksList" type="VBoxContainer"] +script = ExtResource("1_etp6v") diff --git a/graph_node_renderer/deck_holder_renderer.gd b/graph_node_renderer/deck_holder_renderer.gd index 670f108..15008b7 100644 --- a/graph_node_renderer/deck_holder_renderer.gd +++ b/graph_node_renderer/deck_holder_renderer.gd @@ -7,6 +7,7 @@ class_name DeckHolderRenderer ## Reference to the base scene for [DeckRendererGraphEdit] const DECK_SCENE := preload("res://graph_node_renderer/deck_renderer_graph_edit.tscn") +const DEBUG_DECKS_LIST := preload("res://graph_node_renderer/debug_decks_list.tscn") ## Reference to the main windows [TabContainerCustom] @onready var tab_container: TabContainerCustom = %TabContainerCustom as TabContainerCustom @@ -89,8 +90,8 @@ func add_empty_deck() -> void: var inst: DeckRendererGraphEdit = DECK_SCENE.instantiate() inst.deck = deck tab_container.add_content(inst, "Deck %s" % (tab_container.get_tab_count() + 1)) - tab_container.set_tab_metadata(tab_container.get_current_tab(), deck) - inst.group_enter_requested.connect(_on_deck_renderer_group_enter_requested.bind(deck)) + tab_container.set_tab_metadata(tab_container.get_current_tab(), deck.id) + inst.group_enter_requested.connect(_on_deck_renderer_group_enter_requested) ## Closes the current tab in [member tab_container] func close_current_tab() -> void: @@ -135,8 +136,9 @@ func _on_file_dialog_open_files(paths: PackedStringArray) -> void: var inst: DeckRendererGraphEdit = DECK_SCENE.instantiate() inst.deck = deck tab_container.add_content(inst, "Deck %s" % (tab_container.get_tab_count() + 1)) + tab_container.set_tab_metadata(tab_container.get_current_tab(), deck.id) inst.initialize_from_deck() - inst.group_enter_requested.connect(_on_deck_renderer_group_enter_requested.bind(deck)) + inst.group_enter_requested.connect(_on_deck_renderer_group_enter_requested) ## Gets the currently active [Deck] from [member tab_container] func get_active_deck() -> Deck: @@ -165,14 +167,15 @@ func disconnect_file_dialog_signals() -> void: ## Connected to [signal DeckRenderGraphEdit.group_entered_request] to allow entering ## groups based off the given [param group_id] and [param deck]. As well as adding ## a corresponding tab to [member tab_container] -func _on_deck_renderer_group_enter_requested(group_id: String, deck: Deck) -> void: - var group_deck := deck.get_group(group_id) +func _on_deck_renderer_group_enter_requested(group_id: String) -> void: + #var group_deck := deck.get_group(group_id) + var group_deck := DeckHolder.get_deck(group_id) var deck_renderer: DeckRendererGraphEdit = DECK_SCENE.instantiate() deck_renderer.deck = group_deck deck_renderer.initialize_from_deck() tab_container.add_content(deck_renderer, "Group %s" % (tab_container.get_tab_count() + 1)) - tab_container.set_tab_metadata(tab_container.get_current_tab(), group_deck) - deck_renderer.group_enter_requested.connect(_on_deck_renderer_group_enter_requested.bind(deck_renderer.deck)) + tab_container.set_tab_metadata(tab_container.get_current_tab(), group_id) + deck_renderer.group_enter_requested.connect(_on_deck_renderer_group_enter_requested) func _on_connections_id_pressed(id: int) -> void: @@ -194,3 +197,33 @@ func _on_obs_websocket_setup_dialog_connect_button_pressed(state: OBSWebsocketSe func _process(delta: float) -> void: DeckHolder.send_event(&"process", {"delta": delta}) + + +func _on_debug_id_pressed(id: int) -> void: + var d := AcceptDialog.new() + var debug_decks: DebugDecksList = DEBUG_DECKS_LIST.instantiate() + d.add_child(debug_decks) + d.canceled.connect(d.queue_free) + d.confirmed.connect(d.queue_free) + debug_decks.item_pressed.connect(_on_debug_decks_viewer_item_pressed) + add_child(d) + d.popup_centered() + + +func _on_debug_decks_viewer_item_pressed(deck_id: String, instance_id: String) -> void: + if instance_id == "": + var deck := DeckHolder.get_deck(deck_id) + var inst: DeckRendererGraphEdit = DECK_SCENE.instantiate() + inst.deck = deck + tab_container.add_content(inst, "" % [deck_id.left(8)]) + tab_container.set_tab_metadata(tab_container.get_current_tab(), deck.id) + inst.initialize_from_deck() + inst.group_enter_requested.connect(_on_deck_renderer_group_enter_requested) + else: + var deck := DeckHolder.get_group_instance(deck_id, instance_id) + var inst: DeckRendererGraphEdit = DECK_SCENE.instantiate() + inst.deck = deck + tab_container.add_content(inst, "" % [deck_id.left(8), instance_id.left(8)]) + tab_container.set_tab_metadata(tab_container.get_current_tab(), deck.id) + inst.initialize_from_deck() + inst.group_enter_requested.connect(_on_deck_renderer_group_enter_requested) diff --git a/graph_node_renderer/deck_holder_renderer.tscn b/graph_node_renderer/deck_holder_renderer.tscn index ab3e0e4..0b66c03 100644 --- a/graph_node_renderer/deck_holder_renderer.tscn +++ b/graph_node_renderer/deck_holder_renderer.tscn @@ -122,6 +122,11 @@ item_0/id = 0 item_1/text = "Twitch.." item_1/id = 1 +[node name="Debug" type="PopupMenu" parent="MarginContainer/VSplitContainer/VBoxContainer/MenuBar"] +item_count = 1 +item_0/text = "Decks..." +item_0/id = 0 + [node name="TabContainerCustom" parent="MarginContainer/VSplitContainer/VBoxContainer" instance=ExtResource("1_s3ug2")] unique_name_in_owner = true layout_mode = 2 @@ -153,4 +158,5 @@ visible = false [connection signal="id_pressed" from="MarginContainer/VSplitContainer/VBoxContainer/MenuBar/File" to="." method="_on_file_id_pressed"] [connection signal="id_pressed" from="MarginContainer/VSplitContainer/VBoxContainer/MenuBar/Connections" to="." method="_on_connections_id_pressed"] +[connection signal="id_pressed" from="MarginContainer/VSplitContainer/VBoxContainer/MenuBar/Debug" to="." method="_on_debug_id_pressed"] [connection signal="connect_button_pressed" from="OBSWebsocketSetupDialog" to="." method="_on_obs_websocket_setup_dialog_connect_button_pressed"] diff --git a/graph_node_renderer/deck_node_renderer_graph_node.gd b/graph_node_renderer/deck_node_renderer_graph_node.gd index 0d690bc..a79f2d0 100644 --- a/graph_node_renderer/deck_node_renderer_graph_node.gd +++ b/graph_node_renderer/deck_node_renderer_graph_node.gd @@ -18,12 +18,14 @@ func _ready() -> void: for port in node.get_all_ports(): update_port(port) position_offset_changed.connect(_on_position_offset_changed) + node.renamed.connect(_on_node_renamed) ## Connected to [signal GraphElement.position_offset_updated] and updates the ## [member node]s properties func _on_position_offset_changed() -> void: node.position.x = position_offset.x node.position.y = position_offset.y + node.position_updated.emit(node.position) ## Connected to [member node]s [signal position_updated] to keep parity with the ## data position. @@ -32,7 +34,7 @@ func _on_node_position_updated(new_position: Dictionary) -> void: position_offset.x = new_position.x position_offset.y = new_position.y position_offset_changed.connect(_on_position_offset_changed) - print("PO: ", position_offset) + ## Connected to [member node]s [signal port_added] handles setting up the specified ## [member Port.descriptor] with it's required nodes/signals etc. + adding the port @@ -68,6 +70,10 @@ func _on_node_ports_updated() -> void: update_port(port) +func _on_node_renamed(new_name: String) -> void: + title = new_name + + func update_port(port: Port) -> void: var descriptor_split := port.descriptor.split(":") match descriptor_split[0]: diff --git a/graph_node_renderer/deck_renderer_graph_edit.gd b/graph_node_renderer/deck_renderer_graph_edit.gd index 113e9b9..fa75e69 100644 --- a/graph_node_renderer/deck_renderer_graph_edit.gd +++ b/graph_node_renderer/deck_renderer_graph_edit.gd @@ -211,7 +211,7 @@ func _input(event: InputEvent) -> void: func _on_rename_popup_rename_confirmed(new_name: String) -> void: var node: DeckNodeRendererGraphNode = get_selected_nodes()[0] node.title = new_name - node.node.name = new_name + node.node.rename(new_name) func _on_rename_popup_closed() -> void: