From a89e744ed0e8c759caf041a580112365bbfe4303 Mon Sep 17 00:00:00 2001 From: radiohotline Date: Tue, 25 Aug 2026 16:33:56 +0300 Subject: escoria update --- .../gdUnit4/src/core/thread/GdUnitThreadManager.gd | 69 ++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd (limited to 'addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd') diff --git a/addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd b/addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd new file mode 100644 index 0000000..2e694e2 --- /dev/null +++ b/addons/gdUnit4/src/core/thread/GdUnitThreadManager.gd @@ -0,0 +1,69 @@ +## A manager to run new thread and crate a ThreadContext shared over the actual test run +class_name GdUnitThreadManager +extends Object + +## { = } +var _thread_context_by_id: Dictionary[int, GdUnitThreadContext] = {} +## holds the current thread id +var _current_thread_id :int = -1 + +func _init() -> void: + # add initail the main thread + _current_thread_id = OS.get_thread_caller_id() + _thread_context_by_id[OS.get_main_thread_id()] = GdUnitThreadContext.new() + + +static func instance() -> GdUnitThreadManager: + return GdUnitSingleton.instance("GdUnitThreadManager", func() -> GdUnitThreadManager: return GdUnitThreadManager.new()) + + +## Runs a new thread by given name and Callable.[br] +## A new GdUnitThreadContext is created, which is used for the actual test execution.[br] +## We need this custom implementation while this bug is not solved +## Godot issue https://github.com/godotengine/godot/issues/79637 +static func run(name :String, cb :Callable) -> Variant: + return await instance()._run(name, cb) + + +static func interrupt() -> void: + for thread_context: GdUnitThreadContext in instance()._thread_context_by_id.values(): + thread_context.terminate() + + +## Returns the current valid thread context +static func get_current_context() -> GdUnitThreadContext: + return instance()._get_current_context() + + +func _run(name :String, cb :Callable) -> Variant: + # we do this hack because of `OS.get_thread_caller_id()` not returns the current id + # when await process_frame is called inside the fread + var save_current_thread_id := _current_thread_id + var thread := Thread.new() + thread.set_meta("name", name) + @warning_ignore("return_value_discarded") + thread.start(cb) + _current_thread_id = thread.get_id() as int + _register_thread(thread, _current_thread_id) + var result :Variant = await thread.wait_to_finish() + _unregister_thread(_current_thread_id) + # restore original thread id + _current_thread_id = save_current_thread_id + return result + + +func _register_thread(thread :Thread, thread_id :int) -> void: + var context := GdUnitThreadContext.new(thread) + _thread_context_by_id[thread_id] = context + + +func _unregister_thread(thread_id :int) -> void: + var context: GdUnitThreadContext = _thread_context_by_id.get(thread_id) + if context: + @warning_ignore("return_value_discarded") + _thread_context_by_id.erase(thread_id) + context.dispose() + + +func _get_current_context() -> GdUnitThreadContext: + return _thread_context_by_id.get(_current_thread_id) -- cgit v1.3