mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 22:54:36 +00:00
Fix recurring C++ timers
* sixtyfps_timer_start needs to *take* the timer id out of the Rust timer to avoid that the subsequent drop stops the timer again * For the Qt event loop, call `timer_event()` once before entering QCoreApplication::exec(), to schedule any timers that were started beforehand. * Added a way to quit the event loop gently, in order to use that from the C++ unit test.
This commit is contained in:
parent
f4ed0e333b
commit
4cbcf2611f
10 changed files with 50 additions and 2 deletions
|
@ -670,6 +670,11 @@ void run_event_loop()
|
|||
cbindgen_private::sixtyfps_run_event_loop();
|
||||
}
|
||||
|
||||
void quit_event_loop()
|
||||
{
|
||||
cbindgen_private::sixtyfps_quit_event_loop();
|
||||
}
|
||||
|
||||
/// Registers a font by the specified path. The path must refer to an existing
|
||||
/// TrueType font font.
|
||||
/// \returns an empty optional on success, otherwise an error string
|
||||
|
|
|
@ -37,6 +37,11 @@ pub unsafe extern "C" fn sixtyfps_run_event_loop() {
|
|||
crate::backend().run_event_loop();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sixtyfps_quit_event_loop() {
|
||||
crate::backend().quit_event_loop();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sixtyfps_register_font_from_path(
|
||||
path: &sixtyfps_corelib::SharedString,
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
Please contact info@sixtyfps.io for more information.
|
||||
LICENSE END */
|
||||
|
||||
#include <chrono>
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include "catch2/catch.hpp"
|
||||
|
||||
|
@ -64,3 +65,12 @@ TEST_CASE("Property Tracker")
|
|||
REQUIRE(tracker2.is_dirty());
|
||||
REQUIRE(!tracker1.is_dirty());
|
||||
}
|
||||
|
||||
TEST_CASE("C++ Timers")
|
||||
{
|
||||
using namespace sixtyfps;
|
||||
|
||||
Timer testTimer(std::chrono::milliseconds(16), []() { sixtyfps::quit_event_loop(); });
|
||||
|
||||
sixtyfps::run_event_loop();
|
||||
}
|
|
@ -24,6 +24,9 @@ pub trait Backend: Send + Sync {
|
|||
/// Spins an event loop and renders the visible windows.
|
||||
fn run_event_loop(&'static self);
|
||||
|
||||
/// Exits the event loop.
|
||||
fn quit_event_loop(&'static self);
|
||||
|
||||
/// This function can be used to register a custom TrueType font with SixtyFPS,
|
||||
/// for use with the `font-family` property. The provided slice must be a valid TrueType
|
||||
/// font.
|
||||
|
|
|
@ -340,7 +340,7 @@ pub(crate) mod ffi {
|
|||
timer.start(TimerMode::Repeated, core::time::Duration::from_millis(duration), move || {
|
||||
(wrap.callback)(wrap.user_data)
|
||||
});
|
||||
timer.id.get().map(|x| x as i64).unwrap_or(-1)
|
||||
timer.id.take().map(|x| x as i64).unwrap_or(-1)
|
||||
}
|
||||
|
||||
/// Execute a callback with a delay in milisecond
|
||||
|
|
|
@ -110,6 +110,7 @@ pub enum CustomEvent {
|
|||
#[cfg(target_arch = "wasm32")]
|
||||
WakeUpAndPoll,
|
||||
UpdateWindowProperties(Weak<Window>),
|
||||
Exit,
|
||||
}
|
||||
|
||||
/// Runs the event loop and renders the items in the provided `component` in its
|
||||
|
@ -400,6 +401,10 @@ pub fn run() {
|
|||
window.upgrade().map(|window| window.update_window_properties());
|
||||
}
|
||||
|
||||
winit::event::Event::UserEvent(CustomEvent::Exit) => {
|
||||
*control_flow = winit::event_loop::ControlFlow::Exit;
|
||||
}
|
||||
|
||||
_ => (),
|
||||
}
|
||||
|
||||
|
|
|
@ -1487,6 +1487,12 @@ impl sixtyfps_corelib::backend::Backend for Backend {
|
|||
crate::eventloop::run();
|
||||
}
|
||||
|
||||
fn quit_event_loop(&'static self) {
|
||||
crate::eventloop::with_window_target(|event_loop| {
|
||||
event_loop.event_loop_proxy().send_event(crate::eventloop::CustomEvent::Exit).ok();
|
||||
})
|
||||
}
|
||||
|
||||
fn register_font_from_memory(
|
||||
&'static self,
|
||||
data: &[u8],
|
||||
|
|
|
@ -59,4 +59,5 @@ fn main() {
|
|||
println!("cargo:rerun-if-changed=qt_window.rs");
|
||||
println!("cargo:rerun-if-changed=widgets.rs");
|
||||
println!("cargo:rerun-if-changed=qttypes.rs");
|
||||
println!("cargo:rerun-if-changed=lib.rs");
|
||||
}
|
||||
|
|
|
@ -114,6 +114,8 @@ impl sixtyfps_corelib::backend::Backend for Backend {
|
|||
fn run_event_loop(&'static self) {
|
||||
#[cfg(not(no_qt))]
|
||||
{
|
||||
// Schedule any timers with Qt that were set up before this event loop start.
|
||||
crate::qt_window::timer_event();
|
||||
use cpp::cpp;
|
||||
cpp! {unsafe [] {
|
||||
qApp->exec();
|
||||
|
@ -121,6 +123,16 @@ impl sixtyfps_corelib::backend::Backend for Backend {
|
|||
};
|
||||
}
|
||||
|
||||
fn quit_event_loop(&'static self) {
|
||||
#[cfg(not(no_qt))]
|
||||
{
|
||||
use cpp::cpp;
|
||||
cpp! {unsafe [] {
|
||||
qApp->quit();
|
||||
} }
|
||||
};
|
||||
}
|
||||
|
||||
fn register_font_from_memory(
|
||||
&'static self,
|
||||
_data: &[u8],
|
||||
|
|
|
@ -1080,7 +1080,7 @@ thread_local! {
|
|||
}
|
||||
|
||||
/// Called by C++'s TimerHandler::timerEvent, or everytime a timer might have been started
|
||||
fn timer_event() {
|
||||
pub(crate) fn timer_event() {
|
||||
sixtyfps_corelib::animations::update_animations();
|
||||
sixtyfps_corelib::timers::TimerList::maybe_activate_timers();
|
||||
|
||||
|
@ -1113,6 +1113,7 @@ fn timer_event() {
|
|||
};
|
||||
if let Some(timeout) = timeout {
|
||||
cpp! { unsafe [timeout as "int"] {
|
||||
ensure_initialized();
|
||||
TimerHandler::instance().timer.start(timeout, &TimerHandler::instance());
|
||||
}}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue