From 4922f7cafe12ee80edcd70ea1245d974df229c14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lera=20Elvo=C3=A9?= Date: Mon, 18 Dec 2023 21:10:58 +0000 Subject: [PATCH] disconnect existing incoming connection when connecting another and refuse duplicate connections (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes #17 Reviewed-on: https://codeberg.org/Eroax/StreamGraph/pulls/22 Co-authored-by: Lera ElvoƩ Co-committed-by: Lera ElvoƩ --- classes/deck/deck.gd | 16 +++++++++++++- classes/deck/deck_node.gd | 21 +++++++++++++++++++ .../deck_renderer_graph_edit.gd | 17 ++++++++++++++- 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/classes/deck/deck.gd b/classes/deck/deck.gd index 7d0e320..703b718 100644 --- a/classes/deck/deck.gd +++ b/classes/deck/deck.gd @@ -42,6 +42,8 @@ var emit_node_added_signal: bool = true signal node_added(node: DeckNode) ## Emitted when a node has been removed from this deck. signal node_removed(node: DeckNode) +## Emitted when nodes have been disconnected +signal nodes_disconnected(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int) #region group signals signal node_added_to_group(node: DeckNode, assign_id: String, assign_to_self: bool, deck: Deck) @@ -124,7 +126,17 @@ func connect_nodes(from_node_id: String, to_node_id: String, from_output_port: i ) return false - # TODO: prevent duplicate connections + # refuse duplicate connections + if from_node.has_outgoing_connection_exact(from_output_port, to_node_id, to_input_port): + print("no duplicates") + return false + + if to_node.has_incoming_connection(to_input_port): + var connection: Dictionary = to_node.incoming_connections[to_input_port] + var node_id: String = connection.keys()[0] + var node_out_port: int = connection.values()[0] + disconnect_nodes(node_id, to_node_id, node_out_port, to_input_port) + if is_group && emit_group_signals: nodes_connected_in_group.emit(from_node_id, to_node_id, from_output_port, to_input_port, self) @@ -141,6 +153,8 @@ func disconnect_nodes(from_node_id: String, to_node_id: String, from_output_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) + + nodes_disconnected.emit(from_node_id, to_node_id, from_output_port, to_input_port) ## Returns true if this deck has no nodes and no variables. diff --git a/classes/deck/deck_node.gd b/classes/deck/deck_node.gd index 3c39a07..7c0b43c 100644 --- a/classes/deck/deck_node.gd +++ b/classes/deck/deck_node.gd @@ -202,6 +202,27 @@ func remove_incoming_connection(to_port: int) -> void: incoming_connection_removed.emit(to_port) +## Returns [code]true[/code] if the exact connection from this node exists. +func has_outgoing_connection_exact(from_port: int, to_node: String, to_port: int) -> bool: + if !outgoing_connections.has(from_port): + return false + + var connection: Dictionary = outgoing_connections[from_port] + if !connection.has(to_node): + return false + + var connections_to_node: Array = connection[to_node] + if !(to_port in connections_to_node): + return false + + return true + + +## Returns [code]true[/code] if the node has an incoming connection at input port [param on_port]. +func has_incoming_connection(on_port: int) -> bool: + return incoming_connections.has(on_port) + + func rename(new_name: String) -> void: name = new_name renamed.emit(new_name) diff --git a/graph_node_renderer/deck_renderer_graph_edit.gd b/graph_node_renderer/deck_renderer_graph_edit.gd index 9d3962d..6b44b95 100644 --- a/graph_node_renderer/deck_renderer_graph_edit.gd +++ b/graph_node_renderer/deck_renderer_graph_edit.gd @@ -29,6 +29,7 @@ var deck: Deck: deck = v deck.node_added.connect(_on_deck_node_added) deck.node_removed.connect(_on_deck_node_removed) + deck.nodes_disconnected.connect(_on_deck_nodes_disconnected) ## Emits when Group creation is requested. Ex. Hitting the "group_nodes" Hotkey. signal group_enter_requested(group_id: String) @@ -125,7 +126,6 @@ func initialize_from_deck() -> void: i.queue_free() scroll_offset = deck.get_meta("offset", Vector2()) - is_group = deck.is_group for node_id in deck.nodes: var node_renderer: DeckNodeRendererGraphNode = NODE_SCENE.instantiate() @@ -263,6 +263,21 @@ func _on_add_node_menu_node_selected(type: String) -> void: search_popup_panel.hide() +func _on_deck_nodes_disconnected(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int) -> void: + print("1") + var from_node: DeckNodeRendererGraphNode = get_children().filter( + func(x: DeckNodeRendererGraphNode): + return x.node._id == from_node_id + )[0] + var to_node: DeckNodeRendererGraphNode = get_children().filter( + func(x: DeckNodeRendererGraphNode): + return x.node._id == to_node_id + )[0] + + print(is_node_connected(from_node.name, from_output_port, to_node.name, to_input_port)) + disconnect_node(from_node.name, from_output_port, to_node.name, to_input_port) + + func _on_delete_nodes_request(nodes: Array[StringName]) -> void: var node_ids := nodes.map( func(n: StringName):