summaryrefslogtreecommitdiff
path: root/addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd
diff options
context:
space:
mode:
authorradiohotline <radoihotline@disroot.rg>2026-08-25 16:33:56 +0300
committerradiohotline <radoihotline@disroot.rg>2026-08-25 16:33:56 +0300
commita89e744ed0e8c759caf041a580112365bbfe4303 (patch)
treedd61e320904176995727e86a857d00c90d4933ba /addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd
parent6d53d8cac78250dc888aa49d5f9d4175c6652feb (diff)
escoria updateHEADmain
Diffstat (limited to 'addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd')
-rw-r--r--addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd81
1 files changed, 81 insertions, 0 deletions
diff --git a/addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd b/addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd
new file mode 100644
index 0000000..528e133
--- /dev/null
+++ b/addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd
@@ -0,0 +1,81 @@
+class_name GdUnitSignalAwaiter
+extends RefCounted
+
+signal signal_emitted(action :Variant)
+
+const NO_ARG :Variant = GdUnitConstants.NO_ARG
+
+var _wait_on_idle_frame := false
+var _interrupted := false
+var _time_left :float = 0
+var _timeout_millis :int
+
+
+func _init(timeout_millis :int, wait_on_idle_frame := false) -> void:
+ _timeout_millis = timeout_millis
+ _wait_on_idle_frame = wait_on_idle_frame
+
+
+func _on_signal_emmited(
+ arg0 :Variant = NO_ARG,
+ arg1 :Variant = NO_ARG,
+ arg2 :Variant = NO_ARG,
+ arg3 :Variant = NO_ARG,
+ arg4 :Variant = NO_ARG,
+ arg5 :Variant = NO_ARG,
+ arg6 :Variant = NO_ARG,
+ arg7 :Variant = NO_ARG,
+ arg8 :Variant = NO_ARG,
+ arg9 :Variant = NO_ARG) -> void:
+ var signal_args :Variant = GdArrayTools.filter_value([arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7,arg8,arg9], NO_ARG)
+ signal_emitted.emit(signal_args)
+
+
+func is_interrupted() -> bool:
+ return _interrupted
+
+
+func elapsed_time() -> float:
+ return _time_left
+
+
+func on_signal(source :Object, signal_name :String, expected_signal_args :Array) -> Variant:
+ # register checked signal to wait for
+ @warning_ignore("return_value_discarded")
+ source.connect(signal_name, _on_signal_emmited)
+ # install timeout timer
+ var scene_tree := Engine.get_main_loop() as SceneTree
+ var timer := Timer.new()
+ scene_tree.root.add_child(timer)
+ timer.add_to_group("GdUnitTimers")
+ timer.set_one_shot(true)
+ @warning_ignore("return_value_discarded")
+ timer.timeout.connect(_do_interrupt, CONNECT_DEFERRED)
+ timer.start(_timeout_millis * 0.001 * Engine.get_time_scale())
+
+ # holds the emited value
+ var value :Variant
+ # wait for signal is emitted or a timeout is happen
+ while true:
+ value = await signal_emitted
+ if _interrupted:
+ break
+ if not (value is Array):
+ value = [value]
+ if expected_signal_args.size() == 0 or GdObjects.equals(value, expected_signal_args):
+ break
+ await scene_tree.process_frame
+
+ source.disconnect(signal_name, _on_signal_emmited)
+ _time_left = timer.time_left
+ timer.queue_free()
+ await scene_tree.process_frame
+ @warning_ignore("unsafe_cast")
+ if value is Array and (value as Array).size() == 1:
+ return value[0]
+ return value
+
+
+func _do_interrupt() -> void:
+ _interrupted = true
+ signal_emitted.emit(null)