Async calls
fcdimitr opened this issue · comments
Thank you for this great package!
Is it possible to have async calls within actions? Perhaps I am missing something, but I was trying something like the following:
spinner = Spinner()
set_is_spinning!(spinner, false)
action = Action("example.test_spinner", app)
set_function!(action) do x::Action
set_is_spinning!(spinner, true)
Threads.@spawn begin
sleep!(2)
set_is_spinning!(spinner, false)
println("HEY")
end
return nothing
end
set_action!(button, action)
I would expect to see the spinner spinning for 2 seconds and then stop, but it never stops, and "After sleep" is never printed. If I remove the spawn, then the window freezes for 2 seconds (the spinner is never shown spinning).
Any ideas? Thank you!
Yeah this will cause undefined behavior, the GTK backend uses it's own multi-threaded system so mixing those with Julia threads is not currently supported.
You can get the same behavior by using tick callbacks, like so:
using Mousetrap
main() do app::Application
spinner = Spinner()
set_is_spinning!(spinner, false)
spinner_elapsed = 0 # in seconds
delay_spinner_action = Action("delay_spinner", app) do self::Action
println("starting spinner")
spinner_elapsed = 0
set_is_spinning!(spinner, true)
# connect tick callback, this function will be called once per frame
set_tick_callback!(spinner) do clock::FrameClock
spinner_elapsed += as_seconds(get_time_since_last_frame(clock))
if spinner_elapsed >= 2
# if 2 seconds elapsed, stop spinner and remove tick callback
set_is_spinning!(spinner, false)
println("stopping spinner")
return TICK_CALLBACK_RESULT_DISCONTINUE
else
# else wait until 2s have passed
return TICK_CALLBACK_RESULT_CONTINUE
end
end
end
add_shortcut!(delay_spinner_action, "<Ctrl>t")
window = Window(app)
set_title!(window, "Press Ctrl+T")
set_listens_for_shortcut_action!(spinner, delay_spinner_action)
set_child!(window, spinner)
present!(window)
end
Here we created at an action that when triggered using Ctrl + T
, will make the spinner start spinning. During each callback, the spinner_elapsed
upvalue is updated to keep track of how much time has passed. After 2s have passed, the spinner will automatically stop spinning and the tick callback is disconnected.