change all value requests and value resolutions in all nodes to be async (#57)

Reviewed-on: https://codeberg.org/StreamGraph/StreamGraph/pulls/57
Co-authored-by: Lera Elvoé <yagich@poto.cafe>
Co-committed-by: Lera Elvoé <yagich@poto.cafe>
This commit is contained in:
Lera Elvoé 2024-01-25 07:20:41 +00:00 committed by yagich
parent d0313b9697
commit fbcb04651c
26 changed files with 74 additions and 113 deletions

View file

@ -145,19 +145,9 @@ func add_incoming_connection(to_port: int, from_node: String, from_port: int) ->
incoming_connection_added.emit(to_port) incoming_connection_added.emit(to_port)
## Request a value from an incoming connection on this node's input port at [param on_port]. ## Asynchronously request a value from an incoming connection on this node's input port at [param on_port].
## Returns [code]null[/code] if no incoming connection exists on that port. ## Returns [code]null[/code] if no incoming connection exists on that port.
## The connected node may also return [code]null[/code]. ## The connected node may also return [code]null[/code].
func request_value(on_port: int) -> Variant:
if !incoming_connections.has(on_port):
return null
var connection: Dictionary = incoming_connections[on_port]
var node := get_node(connection.keys()[0])
return node._value_request(connection.values()[0])
## Asynchronous version of [method request_value].
func request_value_async(on_port: int) -> Variant: func request_value_async(on_port: int) -> Variant:
if !incoming_connections.has(on_port): if !incoming_connections.has(on_port):
return null return null
@ -305,29 +295,21 @@ func _post_load() -> void:
## A helper function to get a value on an input port. Returns the best match in the following ## A helper function to get a value on an input port. Returns the best match in the following
## order of priority:[br] ## order of priority:[br]
## 1. The direct result of [method request value]. [br] ## 1. The direct result of [method request value], called asynchronously. [br]
## 2. The result of [method Port.value_callback]. [br] ## 2. The result of [method Port.value_callback], if it's not equal to [param empty_value]. [br]
## 3. The input [Port] at index [param input_port]'s stored [member Port.value]. [br] ## 3. The input [Port] at index [param input_port]'s stored [member Port.value], if it's not equal to [param empty_value]. [br]
## 4. [code]null[/code]. ## 4. [code]null[/code].[br]
func resolve_input_port_value(input_port: int) -> Variant: func resolve_input_port_value_async(input_port: int, empty_value: Variant = null) -> Variant:
if request_value(input_port) != null: var request = await request_value_async(input_port)
return request_value(input_port) if request != null:
elif get_input_ports()[input_port].value_callback.get_object() && get_input_ports()[input_port].value_callback.call() != null: return request
elif get_input_ports()[input_port].value_callback.get_object() && get_input_ports()[input_port].value_callback.call() != empty_value:
return get_input_ports()[input_port].value_callback.call() return get_input_ports()[input_port].value_callback.call()
elif get_input_ports()[input_port].value != null: elif get_input_ports()[input_port].value != empty_value:
return get_input_ports()[input_port].value return get_input_ports()[input_port].value
else: else:
return null return null
func resolve_input_port_value_async(input_port: int) -> Variant:
if await request_value_async(input_port) != null:
return await request_value_async(input_port)
elif get_input_ports()[input_port].value_callback.get_object() && get_input_ports()[input_port].value_callback.call() != null:
return get_input_ports()[input_port].value_callback.call()
elif get_input_ports()[input_port].value != null:
return get_input_ports()[input_port].value
else:
return null
## Returns a [Dictionary] representation of this node. ## Returns a [Dictionary] representation of this node.
func to_dict(with_meta: bool = true) -> Dictionary: func to_dict(with_meta: bool = true) -> Dictionary:

View file

@ -27,12 +27,12 @@ func _init() -> void:
func _value_request(on_port: int) -> Variant: func _value_request(on_port: int) -> Variant:
var arr = request_value(0) var arr = await request_value_async(0)
if arr == null: if arr == null:
DeckHolder.logger.log_node("Array index: Input array is null. Returning null.", Logger.LogType.ERROR) DeckHolder.logger.log_node("Array index: Input array is null. Returning null.", Logger.LogType.ERROR)
return null return null
var idx := int(resolve_input_port_value(1)) var idx := int(await resolve_input_port_value_async(1))
if idx < 0: if idx < 0:
idx = (arr as Array).size() + idx idx = (arr as Array).size() + idx

View file

@ -27,11 +27,11 @@ func _init() -> void:
func _value_request(_on_port: int) -> Variant: func _value_request(_on_port: int) -> Variant:
var d = request_value(0) var d = await request_value_async(0)
if d == null: if d == null:
return null return null
var key = resolve_input_port_value(1) var key = await resolve_input_port_value_async(1)
if key == null: if key == null:
return null return null

View file

@ -40,7 +40,7 @@ func _value_request(_from_port : int) -> Variant:
return null return null
var res = expr.execute([_belonging_to.variable_stack, request_value(0)]) var res = expr.execute([_belonging_to.variable_stack, await request_value_async(0)])
if expr.has_execute_failed(): if expr.has_execute_failed():
DeckHolder.logger.log_node("Expression Execution Failed: %s" % text, Logger.LogType.ERROR) DeckHolder.logger.log_node("Expression Execution Failed: %s" % text, Logger.LogType.ERROR)

View file

@ -29,9 +29,5 @@ func _receive(to_input_port: int, data: Variant, extra_data: Array = []) -> void
if to_input_port != 1: if to_input_port != 1:
return return
if resolve_input_port_value(0): if await resolve_input_port_value_async(0):
send(0, data, extra_data) send(0, data, extra_data)
elif ports[0].value:
send(0, data, extra_data)

View file

@ -28,7 +28,7 @@ func _init() -> void:
func _value_request(on_port: int) -> Variant: func _value_request(on_port: int) -> Variant:
var a = resolve_input_port_value(0) var a = await resolve_input_port_value_async(0)
var b = resolve_input_port_value(1) var b = await resolve_input_port_value_async(1)
return a == b return a == b

View file

@ -36,7 +36,7 @@ func _receive(to_input_port: int, data: Variant, extra_data: Array = []) -> void
if to_input_port != 1: if to_input_port != 1:
return return
var data_to_print = str(resolve_input_port_value(0)) var data_to_print = str(await resolve_input_port_value_async(0))
if data_to_print == null: if data_to_print == null:
data_to_print = str(data) data_to_print = str(data)
if (data_to_print as String).is_empty(): if (data_to_print as String).is_empty():

View file

@ -32,7 +32,7 @@ func _event_received(event_name: StringName, event_data: Dictionary = {}) -> voi
if event_name != &"process": if event_name != &"process":
return return
var run = resolve_input_port_value(0) == true var run = await resolve_input_port_value_async(0) == true
if !run: if !run:
return return

View file

@ -38,21 +38,10 @@ func _receive(to_input_port: int, _data: Variant, _extra_data: Array = []) -> vo
if to_input_port != 2: if to_input_port != 2:
return return
var var_name: String = resolve_input_port_value(0) var var_name: String = await resolve_input_port_value_async(0)
var var_value: Variant = resolve_input_port_value(1) var var_value: Variant = await resolve_input_port_value_async(1)
#_belonging_to.variable_stack[var_name] = var_value #_belonging_to.variable_stack[var_name] = var_value
_belonging_to.set_variable(var_name, var_value) _belonging_to.set_variable(var_name, var_value)
send(0, var_value) send(0, var_value)
# this can probably go into DeckNode with a different name that makes it clear
# that it prioritizes call-time resolution
# EDIT: done, see DeckNode#resolve_input_port_value
func get_value_for_port(port: int) -> Variant:
if request_value(port) != null:
return request_value(port)
elif get_input_ports()[port].value_callback.get_object() && get_input_ports()[port].value_callback.call() != null:
return get_input_ports()[port].value_callback.call()
else:
return null

View file

@ -28,11 +28,11 @@ func _init() -> void:
func _value_request(on_port: int) -> Variant: func _value_request(on_port: int) -> Variant:
if !resolve_input_port_value(1): var delimiter = await resolve_input_port_value_async(1)
if !delimiter:
DeckHolder.logger.log_node("Split: could not resolve delimiter. Returning: []", Logger.LogType.ERROR) DeckHolder.logger.log_node("Split: could not resolve delimiter. Returning: []", Logger.LogType.ERROR)
return [] return []
var string := str(resolve_input_port_value(0)) var string = await resolve_input_port_value_async(0)
var del := str(resolve_input_port_value(1))
return Array(string.split(del)) return Array(string.split(delimiter))

View file

@ -77,4 +77,4 @@ func _post_load() -> void:
func _value_request(from_port: int) -> Variant: func _value_request(from_port: int) -> Variant:
return group_node.request_value(group_node.get_input_ports()[from_port].index_of_type) return await group_node.request_value_async(group_node.get_input_ports()[from_port].index_of_type)

View file

@ -78,4 +78,4 @@ func _receive(to_input_port: int, data: Variant, extra_data: Array = []):
func _value_request(from_port: int) -> Variant: func _value_request(from_port: int) -> Variant:
return output_node.request_value(from_port) return await output_node.request_value_async(from_port)

View file

@ -24,8 +24,8 @@ func _init() -> void:
func _value_request(_on_port: int) -> Variant: func _value_request(_on_port: int) -> Variant:
var va = request_value(0) var va = await request_value_async(0)
var vb = request_value(1) var vb = await request_value_async(1)
if !va || !vb: if !va || !vb:
DeckHolder.logger.log_node("Vector Add: one of the vectors is invalid.", Logger.LogType.ERROR) DeckHolder.logger.log_node("Vector Add: one of the vectors is invalid.", Logger.LogType.ERROR)

View file

@ -27,6 +27,6 @@ func _init() -> void:
func _value_request(_on_port: int) -> Dictionary: func _value_request(_on_port: int) -> Dictionary:
var x = float(resolve_input_port_value(0)) var x = float(await resolve_input_port_value_async(0))
var y = float(resolve_input_port_value(1)) var y = float(await resolve_input_port_value_async(1))
return {"x": x, "y": y} return {"x": x, "y": y}

View file

@ -25,7 +25,7 @@ func _init() -> void:
func _value_request(on_port: int) -> Variant: func _value_request(on_port: int) -> Variant:
var v = request_value(0) var v = await request_value_async(0)
if !v: if !v:
DeckHolder.logger.log_node("Vector Decompose: the vector is invalid.", Logger.LogType.ERROR) DeckHolder.logger.log_node("Vector Decompose: the vector is invalid.", Logger.LogType.ERROR)
return null return null

View file

@ -25,8 +25,8 @@ func _init() -> void:
func _value_request(_on_port: int) -> Variant: func _value_request(_on_port: int) -> Variant:
var va = request_value(0) var va = await request_value_async(0)
var vb = request_value(1) var vb = await request_value_async(1)
if !va || !vb: if !va || !vb:
DeckHolder.logger.log_node("Vector Dot: one of the vectors is invalid.", Logger.LogType.ERROR) DeckHolder.logger.log_node("Vector Dot: one of the vectors is invalid.", Logger.LogType.ERROR)

View file

@ -26,7 +26,7 @@ func _init() -> void:
func _value_request(_on_port: int) -> Variant: func _value_request(_on_port: int) -> Variant:
var v = request_value(0) var v = await request_value_async(0)
if !v: if !v:
DeckHolder.logger.log_node("Vector Mult: the vector is invalid.", Logger.LogType.ERROR) DeckHolder.logger.log_node("Vector Mult: the vector is invalid.", Logger.LogType.ERROR)
@ -36,6 +36,6 @@ func _value_request(_on_port: int) -> Variant:
DeckHolder.logger.log_node("Vector Mult: the vector is invalid.", Logger.LogType.ERROR) DeckHolder.logger.log_node("Vector Mult: the vector is invalid.", Logger.LogType.ERROR)
return null return null
var s = float(resolve_input_port_value(1)) var s = float(await resolve_input_port_value_async(1))
return {"x": v.x * s, "y": v.y * s} return {"x": v.x * s, "y": v.y * s}

View file

@ -21,7 +21,7 @@ func _init() -> void:
func _value_request(_on_port: int) -> Variant: func _value_request(_on_port: int) -> Variant:
var v = request_value(0) var v = await request_value_async(0)
if !v: if !v:
DeckHolder.logger.log_node("Vector Normalize: the vector is invalid.", Logger.LogType.ERROR) DeckHolder.logger.log_node("Vector Normalize: the vector is invalid.", Logger.LogType.ERROR)
return null return null

View file

@ -24,8 +24,8 @@ func _init() -> void:
func _value_request(_on_port: int) -> Variant: func _value_request(_on_port: int) -> Variant:
var va = request_value(0) var va = await request_value_async(0)
var vb = request_value(1) var vb = await request_value_async(1)
if !va || !vb: if !va || !vb:
DeckHolder.logger.log_node("Vector Sub: one of the vectors is invalid.", Logger.LogType.ERROR) DeckHolder.logger.log_node("Vector Sub: one of the vectors is invalid.", Logger.LogType.ERROR)

View file

@ -30,7 +30,7 @@ func _init() -> void:
func _value_request(on_port: int) -> Variant: func _value_request(on_port: int) -> Variant:
var t = request_value(0) var t = await request_value_async(0)
if t == null: if t == null:
return null return null

View file

@ -37,21 +37,16 @@ func _value_request(_on_output_port: int) -> Variant:
if noobs == null: if noobs == null:
noobs = Connections.obs_websocket noobs = Connections.obs_websocket
var scene_name: String var scene_name_req = await resolve_input_port_value_async(0, "")
if request_value(0) != null: if scene_name_req == null:
scene_name = request_value(0)
elif get_input_ports()[0].value_callback.get_object() && get_input_ports()[0].value_callback.call() != "":
scene_name = get_input_ports()[0].value_callback.call()
if scene_name.is_empty():
return null return null
var source_name: String var source_name_req = await resolve_input_port_value_async(1, "")
if request_value(1) != null: if source_name_req == null:
source_name = request_value(1)
elif get_input_ports()[1].value_callback.get_object() && get_input_ports()[1].value_callback.call() != "":
source_name = get_input_ports()[1].value_callback.call()
if source_name.is_empty():
return null return null
var scene_name: String = scene_name_req
var source_name: String = source_name_req
if cached_scene_name == scene_name && cached_source_name == scene_name: if cached_scene_name == scene_name && cached_source_name == scene_name:
return cached_id return cached_id

View file

@ -57,27 +57,26 @@ func _receive(to_input_port: int, _data: Variant, _extra_data: Array = []) -> vo
if lock: if lock:
return return
var scene_name_req = await resolve_input_port_value_async(InputPorts.SCENE_NAME, "")
if scene_name_req == null:
return
var scene_name: String var scene_name: String
if request_value(InputPorts.SCENE_NAME) != null:
scene_name = request_value(InputPorts.SCENE_NAME)
elif get_input_ports()[InputPorts.SCENE_NAME].value_callback.get_object() && get_input_ports()[InputPorts.SCENE_NAME].value_callback.call() != "":
scene_name = get_input_ports()[InputPorts.SCENE_NAME].value_callback.call()
if scene_name.is_empty(): if scene_name.is_empty():
return return
var source_id: float var source_id_req = await resolve_input_port_value_async(InputPorts.SOURCE_ID)
var res_as = await request_value_async(InputPorts.SOURCE_ID) if source_id_req == null:
if res_as != null: return
source_id = res_as
elif get_input_ports()[InputPorts.SOURCE_ID].value_callback.get_object() && get_input_ports()[InputPorts.SOURCE_ID].value_callback.call() != null: var source_id: float = source_id_req
source_id = get_input_ports()[InputPorts.SOURCE_ID].value_callback.call()
var xform: Dictionary var xform_req = await resolve_input_port_value_async(InputPorts.XFORM)
if request_value(InputPorts.XFORM) != null: if xform_req == null:
xform = request_value(InputPorts.XFORM) return
elif get_input_ports()[InputPorts.XFORM].value_callback.get_object() && get_input_ports()[InputPorts.XFORM].value_callback.call() != null:
xform = get_input_ports()[InputPorts.XFORM].value_callback.call() var xform: Dictionary = xform_req
if xform.is_empty(): if xform.is_empty():
return return

View file

@ -32,11 +32,11 @@ func _receive(on_input_port: int, _data: Variant, _extra_data: Array = []) -> vo
if noobs == null: if noobs == null:
noobs = Connections.obs_websocket noobs = Connections.obs_websocket
var scene_name: String var scene_name_req = await resolve_input_port_value_async(0, "")
if request_value(0) != null: if scene_name_req == null:
scene_name = request_value(0) return
elif get_input_ports()[0].value_callback.get_object() && get_input_ports()[0].value_callback.call() != "":
scene_name = get_input_ports()[0].value_callback.call() var scene_name: String = scene_name_req
if scene_name.is_empty(): if scene_name.is_empty():
return return

View file

@ -20,7 +20,7 @@ func _init() -> void:
func _value_request(_on_port: int) -> Variant: func _value_request(_on_port: int) -> Variant:
var v = request_value(0) var v = await request_value_async(0)
if !v: if !v:
return null return null

View file

@ -42,8 +42,8 @@ func switch_user_input_type(value):
func _value_request(from_port): func _value_request(from_port):
var user_input = resolve_input_port_value(0) var user_input = await resolve_input_port_value_async(0)
var as_id = resolve_input_port_value(1) var as_id = await resolve_input_port_value_async(1)
var req_url := "https://api.twitch.tv/helix/users?" var req_url := "https://api.twitch.tv/helix/users?"
if as_id: if as_id:

View file

@ -35,8 +35,8 @@ func _receive(to_input_port, data: Variant, extra_data: Array = []):
return return
var msg = resolve_input_port_value(0) var msg = await resolve_input_port_value_async(0)
var channel = resolve_input_port_value(1) var channel = await resolve_input_port_value_async(1)
if channel == null: if channel == null: