diff options
| author | radiohotline <radoihotline@disroot.rg> | 2026-08-25 16:33:56 +0300 |
|---|---|---|
| committer | radiohotline <radoihotline@disroot.rg> | 2026-08-25 16:33:56 +0300 |
| commit | a89e744ed0e8c759caf041a580112365bbfe4303 (patch) | |
| tree | dd61e320904176995727e86a857d00c90d4933ba /addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd | |
| parent | 6d53d8cac78250dc888aa49d5f9d4175c6652feb (diff) | |
Diffstat (limited to 'addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd')
| -rw-r--r-- | addons/gdUnit4/src/core/GdUnitSignalAwaiter.gd | 81 |
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) |
