miggor-StreamGraph/classes/deck/port.gd
Lera Elvoé 51652ef277 add port usage type to Port (#69)
first part of addressing #59

every `Port` now has a `usage_type` field that indicates whether it can be used for triggers (eg. sending and receiving events), value requests, or both. `Deck` has an additional method to validate if a potential connection is legal, which checks for the following in order:

1. the source and target nodes are not the same node;
2. the port usage is valid (trigger to trigger, value to value, both to any);
3. the port types are compatible
4. the connection doesn't already exist

all node ports by default use the "both" usage, since that will be the most common use case (especially in cases where an input port can accept either a trigger and a value request but the output can only send one type), but it can be specified as an optional argument in `add_[input|output]_port()`

usage types are represented in the renderer by different port icons:

![image](/attachments/28d3cfe9-c62c-4dd4-937d-64dbe87cb205)

there is a reference implementation in the Compare Values and Twitch Chat Received nodes, since those were used as examples in #59. other nodes will be added as a separate PR later if this is merged, since behavior will vary greatly per node.

Reviewed-on: https://codeberg.org/StreamGraph/StreamGraph/pulls/69
Co-authored-by: Lera Elvoé <yagich@poto.cafe>
Co-committed-by: Lera Elvoé <yagich@poto.cafe>
2024-02-21 04:08:36 +00:00

75 lines
2.3 KiB
GDScript

# (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)
class_name Port
## A data type representing a port of a [DeckNode].
##
## Ports are used for connections between [DeckNode]s and can contain data that is passed between
## them on a node.
enum UsageType {
TRIGGER, ## Port can send or receive events, not request values.
VALUE_REQUEST, ## Port can request values and respond to value requests, not send or receive events.
BOTH, ## Port can send or receive events [b]and[/b] request and respond to value requests.
}
## The type index of this port.
var type: DeckType.Types
## The label of this port. Used by the renderer to display. How it's displayed depends on the renderer
## and the [member descriptor].
var label: String
## Hints to the renderer on how to display this port.[br]
## Can be either one of these: [code]button textfield spinbox slider textblock codeblock checkbox singlechoice multichoice[/code].[br]
## Additional descriptor properties can be specified after the type, delimited by a colon ([code]:[/code]).[br]
## @experimental
var descriptor: String
## A callback to get this port's value. Intended usage is by renderers that show an input field of some kind.
var value_callback: Callable
## The type of this port (input, output or virtual)
var port_type: DeckNode.PortType
## The usage type of this port (see [enum UsageType]).
var usage_type: UsageType
## The local index of this port.
var index_of_type: int
## The global index of this port.
var index: int
## The value of this port.
var value: Variant
signal value_updated(new_value: Variant)
func _init(
p_type: DeckType.Types,
p_label: String,
p_index: int,
p_port_type: DeckNode.PortType,
p_index_of_type: int,
p_descriptor: String = "",
# p_value_callback: Callable = Callable(),
p_usage_type: UsageType = UsageType.BOTH,
) -> void:
type = p_type
label = p_label
descriptor = p_descriptor
# value_callback = p_value_callback
port_type = p_port_type
index_of_type = p_index_of_type
index = p_index
usage_type = p_usage_type
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()
return
value = v