setInterval, clearInterval, image tests

This commit is contained in:
Face
2025-08-09 14:57:29 +03:00
parent be9d9c17a6
commit d47f811670
6 changed files with 321 additions and 17 deletions

View File

@@ -11,12 +11,16 @@ class TimeoutInfo:
var vm: LuauVM
var timer: Timer
var timeout_manager: LuaTimeoutManager
var is_interval: bool = false
var delay_ms: int = 0
func _init(timeout_id: int, cb_ref: int, lua_vm: LuauVM, manager: LuaTimeoutManager):
func _init(timeout_id: int, cb_ref: int, lua_vm: LuauVM, manager: LuaTimeoutManager, interval: bool = false, delay: int = 0):
id = timeout_id
callback_ref = cb_ref
vm = lua_vm
timeout_manager = manager
is_interval = interval
delay_ms = delay
func set_timeout_handler(vm: LuauVM, parent_node: Node) -> int:
vm.luaL_checktype(1, vm.LUA_TFUNCTION)
@@ -59,10 +63,55 @@ func set_timeout_handler(vm: LuauVM, parent_node: Node) -> int:
vm.lua_pushinteger(timeout_id)
return 1
func set_interval_handler(vm: LuauVM, parent_node: Node) -> int:
vm.luaL_checktype(1, vm.LUA_TFUNCTION)
var delay_ms: int = vm.luaL_checkint(2)
var timeout_id = next_timeout_id
next_timeout_id += 1
# Store callback in isolated registry table
vm.lua_pushstring("GURT_TIMEOUTS")
vm.lua_rawget(vm.LUA_REGISTRYINDEX)
if vm.lua_isnil(-1):
vm.lua_pop(1)
vm.lua_newtable()
vm.lua_pushstring("GURT_TIMEOUTS")
vm.lua_pushvalue(-2)
vm.lua_rawset(vm.LUA_REGISTRYINDEX)
vm.lua_pushinteger(timeout_id)
vm.lua_pushvalue(1)
vm.lua_rawset(-3)
vm.lua_pop(1)
# Create interval info
var timeout_info = TimeoutInfo.new(timeout_id, timeout_id, vm, self, true, delay_ms)
# Create and configure timer for intervals
var timer = Timer.new()
timer.wait_time = delay_ms / 1000.0
timer.one_shot = false # This is the key difference - repeating timer
timer.timeout.connect(_on_timeout_triggered.bind(timeout_info))
timeout_info.timer = timer
active_timeouts[timeout_id] = timeout_info
# Add timer to scene tree
parent_node.add_child(timer)
timer.start()
vm.lua_pushinteger(timeout_id)
return 1
func set_threaded_timeout_handler(vm: LuauVM, parent_node: Node, threaded_vm_ref: ThreadedLuaVM) -> int:
threaded_vm = threaded_vm_ref
return set_timeout_handler(vm, parent_node)
func set_threaded_interval_handler(vm: LuauVM, parent_node: Node, threaded_vm_ref: ThreadedLuaVM) -> int:
threaded_vm = threaded_vm_ref
return set_interval_handler(vm, parent_node)
func _create_timer_on_main_thread(timeout_info: TimeoutInfo, delay_ms: int, parent_node: Node):
var timer = Timer.new()
timer.wait_time = delay_ms / 1000.0
@@ -76,6 +125,19 @@ func _create_timer_on_main_thread(timeout_info: TimeoutInfo, delay_ms: int, pare
func clear_timeout_handler(vm: LuauVM) -> int:
var timeout_id: int = vm.luaL_checkint(1)
# If we have a threaded VM, defer the cleanup to main thread
if threaded_vm:
call_deferred("_cleanup_timeout_on_main_thread", timeout_id)
else:
_cleanup_timeout_immediately(timeout_id)
return 0
func _cleanup_timeout_on_main_thread(timeout_id: int):
# This runs on the main thread - safe to access timers
_cleanup_timeout_immediately(timeout_id)
func _cleanup_timeout_immediately(timeout_id: int):
var timeout_info = active_timeouts.get(timeout_id, null)
if timeout_info:
# Stop and remove timer
@@ -83,11 +145,11 @@ func clear_timeout_handler(vm: LuauVM) -> int:
timeout_info.timer.stop()
timeout_info.timer.queue_free()
# Remove from active timeouts
active_timeouts.erase(timeout_id)
return 0
func clear_interval_handler(vm: LuauVM) -> int:
return clear_timeout_handler(vm)
func _on_timeout_triggered(timeout_info: TimeoutInfo) -> void:
if not active_timeouts.has(timeout_info.id):
@@ -96,8 +158,11 @@ func _on_timeout_triggered(timeout_info: TimeoutInfo) -> void:
if threaded_vm:
_execute_threaded_timeout_callback(timeout_info.id)
timeout_info.timer.queue_free()
active_timeouts.erase(timeout_info.id)
# For intervals, don't clean up - let them keep running
# For timeouts, clean up after execution
if not timeout_info.is_interval:
timeout_info.timer.queue_free()
active_timeouts.erase(timeout_info.id)
func cleanup_all_timeouts():
# Clean up all active timeouts