mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 14:51:15 +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();
|
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
|
/// Registers a font by the specified path. The path must refer to an existing
|
||||||
/// TrueType font font.
|
/// TrueType font font.
|
||||||
/// \returns an empty optional on success, otherwise an error string
|
/// \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();
|
crate::backend().run_event_loop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn sixtyfps_quit_event_loop() {
|
||||||
|
crate::backend().quit_event_loop();
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn sixtyfps_register_font_from_path(
|
pub unsafe extern "C" fn sixtyfps_register_font_from_path(
|
||||||
path: &sixtyfps_corelib::SharedString,
|
path: &sixtyfps_corelib::SharedString,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
Please contact info@sixtyfps.io for more information.
|
Please contact info@sixtyfps.io for more information.
|
||||||
LICENSE END */
|
LICENSE END */
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
#define CATCH_CONFIG_MAIN
|
#define CATCH_CONFIG_MAIN
|
||||||
#include "catch2/catch.hpp"
|
#include "catch2/catch.hpp"
|
||||||
|
|
||||||
|
@ -63,4 +64,13 @@ TEST_CASE("Property Tracker")
|
||||||
prop.set(100);
|
prop.set(100);
|
||||||
REQUIRE(tracker2.is_dirty());
|
REQUIRE(tracker2.is_dirty());
|
||||||
REQUIRE(!tracker1.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.
|
/// Spins an event loop and renders the visible windows.
|
||||||
fn run_event_loop(&'static self);
|
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,
|
/// 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
|
/// for use with the `font-family` property. The provided slice must be a valid TrueType
|
||||||
/// font.
|
/// font.
|
||||||
|
|
|
@ -340,7 +340,7 @@ pub(crate) mod ffi {
|
||||||
timer.start(TimerMode::Repeated, core::time::Duration::from_millis(duration), move || {
|
timer.start(TimerMode::Repeated, core::time::Duration::from_millis(duration), move || {
|
||||||
(wrap.callback)(wrap.user_data)
|
(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
|
/// Execute a callback with a delay in milisecond
|
||||||
|
|
|
@ -110,6 +110,7 @@ pub enum CustomEvent {
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
WakeUpAndPoll,
|
WakeUpAndPoll,
|
||||||
UpdateWindowProperties(Weak<Window>),
|
UpdateWindowProperties(Weak<Window>),
|
||||||
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Runs the event loop and renders the items in the provided `component` in its
|
/// 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());
|
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();
|
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(
|
fn register_font_from_memory(
|
||||||
&'static self,
|
&'static self,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
|
|
|
@ -59,4 +59,5 @@ fn main() {
|
||||||
println!("cargo:rerun-if-changed=qt_window.rs");
|
println!("cargo:rerun-if-changed=qt_window.rs");
|
||||||
println!("cargo:rerun-if-changed=widgets.rs");
|
println!("cargo:rerun-if-changed=widgets.rs");
|
||||||
println!("cargo:rerun-if-changed=qttypes.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) {
|
fn run_event_loop(&'static self) {
|
||||||
#[cfg(not(no_qt))]
|
#[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;
|
use cpp::cpp;
|
||||||
cpp! {unsafe [] {
|
cpp! {unsafe [] {
|
||||||
qApp->exec();
|
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(
|
fn register_font_from_memory(
|
||||||
&'static self,
|
&'static self,
|
||||||
_data: &[u8],
|
_data: &[u8],
|
||||||
|
|
|
@ -1080,7 +1080,7 @@ thread_local! {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Called by C++'s TimerHandler::timerEvent, or everytime a timer might have been started
|
/// 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::animations::update_animations();
|
||||||
sixtyfps_corelib::timers::TimerList::maybe_activate_timers();
|
sixtyfps_corelib::timers::TimerList::maybe_activate_timers();
|
||||||
|
|
||||||
|
@ -1113,6 +1113,7 @@ fn timer_event() {
|
||||||
};
|
};
|
||||||
if let Some(timeout) = timeout {
|
if let Some(timeout) = timeout {
|
||||||
cpp! { unsafe [timeout as "int"] {
|
cpp! { unsafe [timeout as "int"] {
|
||||||
|
ensure_initialized();
|
||||||
TimerHandler::instance().timer.start(timeout, &TimerHandler::instance());
|
TimerHandler::instance().timer.start(timeout, &TimerHandler::instance());
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue