diff --git a/classes/deck/deck.gd b/classes/deck/deck.gd index 094f6fb..f57299f 100644 --- a/classes/deck/deck.gd +++ b/classes/deck/deck.gd @@ -42,7 +42,9 @@ 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 +## Emitted when nodes have been connected. +signal nodes_connected(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int) +## 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) ## Emitted when the [member variable_stack] has been modified. signal variables_updated() @@ -57,6 +59,17 @@ signal node_renamed(node_id: String, new_name: String, deck: Deck) signal node_moved(node_id: String, new_position: Dictionary, deck: Deck) #endregion + +func connect_rpc_signals() -> void: + node_added.connect(RPCSignalLayer._on_deck_node_added) + node_removed.connect(RPCSignalLayer._on_deck_node_removed) + + nodes_connected.connect(RPCSignalLayer._on_deck_nodes_connected.bind(id)) + nodes_disconnected.connect(RPCSignalLayer._on_deck_nodes_disconnected.bind(id)) + + variables_updated.connect(RPCSignalLayer._on_deck_variables_updated.bind(id)) + + ## Instantiate a node by its' [member DeckNode.node_type] and add it to this deck.[br] ## See [method add_node_inst] for parameter descriptions. func add_node_type(type: String, assign_id: String = "", assign_to_self: bool = true) -> DeckNode: @@ -105,6 +118,8 @@ func add_node_inst(node: DeckNode, assign_id: String = "", assign_to_self: bool if is_group and emit_group_signals: node_moved.emit(node._id, new_position, self) ) + + node.connect_rpc_signals() return node @@ -161,6 +176,7 @@ func connect_nodes(from_node_id: String, to_node_id: String, from_output_port: i 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) + nodes_connected.emit(from_node_id, to_node_id, from_output_port, to_input_port) return true diff --git a/classes/deck/deck_holder.gd b/classes/deck/deck_holder.gd index 63fce6b..07e981a 100644 --- a/classes/deck/deck_holder.gd +++ b/classes/deck/deck_holder.gd @@ -9,10 +9,17 @@ class_name DeckHolder #static var decks: Array[Deck] static var decks: Dictionary # Dictionary[String -> id, (Deck|Dictionary[String -> instance_id, Deck])] +static var groups_emitted: Array[String] + static var logger := Logger.new() static var signals := Signals.new() +static func _static_init() -> void: + signals.deck_added.connect(RPCSignalLayer._on_deck_added) + signals.deck_closed.connect(RPCSignalLayer._on_deck_closed) + + ## Returns a new empty deck and assigns a new random ID to it. static func add_empty_deck() -> Deck: var deck := Deck.new() @@ -20,6 +27,7 @@ static func add_empty_deck() -> Deck: decks[uuid] = deck deck.id = uuid signals.deck_added.emit(uuid) + deck.connect_rpc_signals() return deck @@ -37,6 +45,7 @@ static func open_deck_from_dict(data: Dictionary, path := "") -> Deck: var deck := Deck.from_dict(data, path) decks[deck.id] = deck signals.deck_added.emit(deck.id) + deck.connect_rpc_signals() return deck @@ -50,7 +59,11 @@ static func add_group_from_dict(data: Dictionary, deck_id: String, instance_id: instances[instance_id] = group decks[deck_id] = instances connect_group_signals(group) - signals.deck_added.emit(deck_id) + + if deck_id not in groups_emitted: + signals.deck_added.emit(deck_id) + groups_emitted.append(deck_id) + return group @@ -67,7 +80,9 @@ static func add_empty_group() -> Deck: group.instance_id = UUID.v4() decks[group.id] = {group.instance_id: group} connect_group_signals(group) - signals.deck_added.emit(group.id) + if group.id not in groups_emitted: + signals.deck_added.emit(group.id) + groups_emitted.append(group.id) return group @@ -112,6 +127,8 @@ static func close_group_instance(group_id: String, instance_id: String) -> void: if group_instances.is_empty(): for group in dangling_groups: close_all_group_instances(group) + signals.deck_closed.emit(group_id) + groups_emitted.erase(group_id) decks.erase(group_id) @@ -128,9 +145,9 @@ static func close_deck(deck_id: String) -> Array: var groups := deck.get_referenced_groups() for group in groups: close_all_group_instances(group) + signals.deck_closed.emit(deck_id) decks.erase(deck_id) return groups - signals.deck_closed.emit(deck_id) return [] diff --git a/classes/deck/deck_node.gd b/classes/deck/deck_node.gd index d8d5a56..2ec6b4a 100644 --- a/classes/deck/deck_node.gd +++ b/classes/deck/deck_node.gd @@ -75,6 +75,13 @@ signal port_value_updated(port_idx: int, new_value: Variant) signal renamed(new_name: String) +func connect_rpc_signals() -> void: + port_added.connect(RPCSignalLayer._on_node_port_added.bind(self)) + ports_updated.connect(RPCSignalLayer._on_node_ports_updated.bind(self)) + port_value_updated.connect(RPCSignalLayer._on_node_port_value_updated.bind(self)) + renamed.connect(RPCSignalLayer._on_node_renamed.bind(self)) + + ## Add an input port to this node. Usually only used at initialization. func add_input_port( type: DeckType.Types, diff --git a/classes/deck/nodes/general/delay.gd b/classes/deck/nodes/general/delay.gd index 470090c..0fdafde 100644 --- a/classes/deck/nodes/general/delay.gd +++ b/classes/deck/nodes/general/delay.gd @@ -3,7 +3,6 @@ # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) extends DeckNode -var thread : Thread func _init(): name = "Delay" diff --git a/rpc_renderer/rpc_signal_layer.gd b/rpc_renderer/rpc_signal_layer.gd index be16f9f..f5d0dac 100644 --- a/rpc_renderer/rpc_signal_layer.gd +++ b/rpc_renderer/rpc_signal_layer.gd @@ -7,27 +7,58 @@ class_name RPCSignalLayer static var signals := Signals.new() -static func _static_init() -> void: - DeckHolder.signals.deck_added.connect(RPCSignalLayer._on_deck_added) - - DeckHolder.signals.deck_closed.connect( - func(deck_id: String): - signals.deck_closed.emit(deck_id) - ) - - +#region deck holder static func _on_deck_added(deck_id: String) -> void: signals.deck_added.emit(deck_id) - DeckHolder.get_deck(deck_id).node_added.connect(RPCSignalLayer._on_deck_node_added) +static func _on_deck_closed(deck_id: String) -> void: + signals.deck_closed.emit(deck_id) +#endregion + + +#region deck static func _on_deck_node_added(node: DeckNode) -> void: signals.deck_node_added.emit(node._belonging_to.id, node._id) - node.position_updated.connect(RPCSignalLayer._on_node_position_updated.bind(node._belonging_to.id, node._id)) -static func _on_node_position_updated(new_position: Dictionary, node_id: String, deck_id: String) -> void: - signals.node_position_updated.emit(deck_id, node_id, new_position) +static func _on_deck_node_removed(node: DeckNode) -> void: + signals.deck_node_removed.emit(node._belonging_to.id, node._id) + + +static func _on_deck_nodes_connected(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int, deck_id: String) -> void: + signals.deck_nodes_connected.emit(deck_id, from_node_id, to_node_id, from_output_port, to_input_port) + + +static func _on_deck_nodes_disconnected(from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int, deck_id: String) -> void: + signals.deck_nodes_disconnected.emit(deck_id, from_node_id, to_node_id, from_output_port, to_input_port) + + +static func _on_deck_variables_updated(deck_id: String) -> void: + signals.deck_variables_updated.emit(deck_id) +#endregion + + +#region node +static func _on_node_position_updated(new_position: Dictionary, node: DeckNode) -> void: + signals.node_position_updated.emit(node._belonging_to.id, node._id, new_position) + + +static func _on_node_port_added(port: int, node: DeckNode) -> void: + signals.node_port_added.emit(node._belonging_to.id, node._id, port, node) + + +static func _on_node_ports_updated(node: DeckNode) -> void: + signals.node_ports_updated.emit(node._belonging_to.id, node._id) + + +static func _on_node_port_value_updated(port_idx: int, new_value: Variant, node: DeckNode) -> void: + signals.node_port_value_updated.emit(node._belonging_to.id, node._id, port_idx, new_value) + + +static func _on_node_renamed(new_name: String, node: DeckNode) -> void: + signals.node_renamed.emit(node._belonging_to.id, node._id, new_name) +#endregion class Signals: @@ -38,8 +69,16 @@ class Signals: #region deck signal deck_node_added(deck_id: String, node_id: String) + signal deck_node_removed(deck_id: String, node_id: String) + signal deck_nodes_connected(deck_id: String, from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int) + signal deck_nodes_disconnected(deck_id: String, from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int) + signal deck_variables_updated(deck_id: String) #endregion #region node signal node_position_updated(deck_id: String, node_id: String, new_position: Dictionary) + signal node_port_added(deck_id: String, node_id: String, port: int) + signal node_ports_updated(deck_id: String, node_id: String) + signal node_port_value_updated(deck_id: String, node_id: String, port_idx: int, new_value: Variant) + signal node_renamed(deck_id: String, node_id: String, new_name: String) #endregion diff --git a/rpc_renderer/scopes/scope_deck.gd b/rpc_renderer/scopes/scope_deck.gd index ce7d758..3049009 100644 --- a/rpc_renderer/scopes/scope_deck.gd +++ b/rpc_renderer/scopes/scope_deck.gd @@ -12,6 +12,10 @@ func _init() -> void: } RPCSignalLayer.signals.deck_node_added.connect(_on_deck_node_added) + RPCSignalLayer.signals.deck_node_removed.connect(_on_deck_node_removed) + + RPCSignalLayer.signals.deck_nodes_connected.connect(_on_deck_nodes_connected) + RPCSignalLayer.signals.deck_nodes_disconnected.connect(_on_deck_nodes_disconnected) func add_node(r: RPCRequest) -> void: @@ -34,3 +38,29 @@ func add_node(r: RPCRequest) -> void: func _on_deck_node_added(deck_id: String, node_id: String) -> void: event.emit(create_event("node_added", {"node_id": node_id}, {"deck_id": deck_id})) + + +func _on_deck_node_removed(deck_id: String, node_id: String) -> void: + event.emit(create_event("node_removed", {"node_id": node_id}, {"deck_id": deck_id})) + + +func _on_deck_nodes_connected(deck_id: String, from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int) -> void: + var connection := RPCNodeConnection.new() + connection.from_node_id = from_node_id + connection.to_node_id = to_node_id + connection.from_output_port = from_output_port + connection.to_input_port = to_input_port + + var ev := create_event("nodes_connected", connection, {"deck_id": deck_id}) + event.emit(ev) + + +func _on_deck_nodes_disconnected(deck_id: String, from_node_id: String, to_node_id: String, from_output_port: int, to_input_port: int) -> void: + var connection := RPCNodeConnection.new() + connection.from_node_id = from_node_id + connection.to_node_id = to_node_id + connection.from_output_port = from_output_port + connection.to_input_port = to_input_port + + var ev := create_event("nodes_disconnected", connection, {"deck_id": deck_id}) + event.emit(ev) diff --git a/rpc_renderer/scopes/scope_deck_holder.gd b/rpc_renderer/scopes/scope_deck_holder.gd index 4ea95a9..ff2fba1 100644 --- a/rpc_renderer/scopes/scope_deck_holder.gd +++ b/rpc_renderer/scopes/scope_deck_holder.gd @@ -8,7 +8,7 @@ func _init() -> void: name = "deck_holder" operation_types = { - "new_deck": new_deck, # TODO: evaluate later + #"new_deck": new_deck, # TODO: evaluate later "get_deck": get_deck, "send_event": send_event, "error": error, @@ -21,6 +21,7 @@ func _init() -> void: func error(r: RPCRequest) -> void: response.emit(create_error(r, "random error")) + func new_deck(r: RPCRequest) -> void: reconnect( RPCSignalLayer.signals.deck_added, @@ -69,8 +70,8 @@ func send_event(r: RPCRequest) -> void: func _on_deck_holder_deck_added(deck_id: String) -> void: - event.emit(create_event("new_deck", {"deck_id": deck_id})) + event.emit(create_event("new_deck", RPCDeckPartial.new(DeckHolder.get_deck(deck_id)))) func _on_deck_holder_deck_closed(deck_id: String) -> void: - pass + event.emit(create_event("deck_closed", RPCDeckPartial.new(DeckHolder.get_deck(deck_id)))) diff --git a/rpc_renderer/scopes/scope_node.gd b/rpc_renderer/scopes/scope_node.gd index 49381ea..bbdf1a8 100644 --- a/rpc_renderer/scopes/scope_node.gd +++ b/rpc_renderer/scopes/scope_node.gd @@ -8,7 +8,28 @@ func _init() -> void: name = "node" RPCSignalLayer.signals.node_position_updated.connect(_on_node_position_updated) + RPCSignalLayer.signals.node_renamed.connect(_on_node_renamed) + RPCSignalLayer.signals.node_port_value_updated.connect(_on_node_port_value_updated) func _on_node_position_updated(deck_id: String, node_id: String, position: Dictionary) -> void: event.emit(create_event("position_updated", position, {"deck_id": deck_id, "node_id": node_id})) + + +func _on_node_renamed(deck_id: String, node_id: String, new_name: String) -> void: + event.emit(create_event("renamed", {"new_name": new_name}, {"deck_id": deck_id, "node_id": node_id})) + + +func _on_node_port_value_updated(deck_id: String, node_id: String, port_idx: int, new_value: Variant) -> void: + event.emit(create_event( + "port_value_updated", + { + "port": port_idx, + "new_value": new_value, + }, + { + "deck_id": deck_id, + "node_id": node_id, + } + ) + ) diff --git a/rpc_renderer/types/extended/connection.gd b/rpc_renderer/types/extended/connection.gd new file mode 100644 index 0000000..ec6bb78 --- /dev/null +++ b/rpc_renderer/types/extended/connection.gd @@ -0,0 +1,20 @@ +# (c) 2023-present Eroax +# (c) 2023-present Yagich +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) +extends RPCFrame +class_name RPCNodeConnection + +var from_node_id: String +var from_output_port: int +var to_node_id: String +var to_input_port: int + + +func _init() -> void: + frame_name = "node_connection" + _props = [ + &"from_node_id", + &"from_output_port", + &"to_node_id", + &"to_input_port", + ] diff --git a/rpc_renderer/types/extended/deck_partial.gd b/rpc_renderer/types/extended/deck_partial.gd index dc15ad0..2ebb841 100644 --- a/rpc_renderer/types/extended/deck_partial.gd +++ b/rpc_renderer/types/extended/deck_partial.gd @@ -5,8 +5,13 @@ extends RPCFrame class_name RPCDeckPartial var id: String +var is_group: bool -func _init() -> void: +func _init(from: Deck = null) -> void: frame_name = "deck_partial" _props = [&"id"] + + if from: + id = from.id + is_group = from.is_group diff --git a/rpc_renderer/types/extended/node_partial.gd b/rpc_renderer/types/extended/node_partial.gd index 5bd2638..1f97f6b 100644 --- a/rpc_renderer/types/extended/node_partial.gd +++ b/rpc_renderer/types/extended/node_partial.gd @@ -8,6 +8,10 @@ var id: String var deck_id: String -func _init() -> void: +func _init(from: DeckNode = null) -> void: frame_name = "node_partial" _props = [&"id", &"deck_id"] + + if from: + id = from._id + deck_id = from._belonging_to.id