mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 06:11:16 +00:00
Timer in C++
This commit is contained in:
parent
7f04301bca
commit
a949570c57
3 changed files with 99 additions and 0 deletions
|
@ -18,6 +18,7 @@ LICENSE END */
|
|||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <iostream> // FIXME: remove: iostream always bring it lots of code so we should not have it in this header
|
||||
#include <chrono>
|
||||
|
||||
namespace sixtyfps::cbindgen_private {
|
||||
// Workaround https://github.com/eqrion/cbindgen/issues/43
|
||||
|
@ -248,6 +249,41 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
/// A Timer that can call a callback at repeated interval
|
||||
///
|
||||
/// Use the static single_shot function to make a single shot timer
|
||||
struct Timer {
|
||||
/// Construct a timer which will repeat the callback every `duration` milliseconds until
|
||||
/// the destructor of the timer is called.
|
||||
template<typename F>
|
||||
Timer(std::chrono::milliseconds duration, F callback)
|
||||
: id(cbindgen_private::sixtyfps_timer_start(
|
||||
duration.count(),
|
||||
[](void *data) { (*reinterpret_cast<F*>(data))(); },
|
||||
new F(std::move(callback)),
|
||||
[](void *data) { delete reinterpret_cast<F*>(data); }))
|
||||
{}
|
||||
Timer(const Timer&) = delete;
|
||||
Timer &operator=(const Timer&) = delete;
|
||||
~Timer() {
|
||||
cbindgen_private::sixtyfps_timer_stop(id);
|
||||
}
|
||||
|
||||
/// Call the callback after the given duration.
|
||||
template<typename F>
|
||||
static void single_shot(std::chrono::milliseconds duration, F callback) {
|
||||
cbindgen_private::sixtyfps_timer_singleshot(
|
||||
duration.count(),
|
||||
[](void *data) { (*reinterpret_cast<F*>(data))(); },
|
||||
new F(std::move(callback)),
|
||||
[](void *data) { delete reinterpret_cast<F*>(data); });
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t id;
|
||||
};
|
||||
|
||||
|
||||
// layouts:
|
||||
using cbindgen_private::box_layout_info;
|
||||
using cbindgen_private::BoxLayoutCellData;
|
||||
|
|
|
@ -85,4 +85,5 @@ pub fn use_modules() -> usize {
|
|||
+ string::ffi::sixtyfps_shared_string_bytes as usize
|
||||
+ eventloop::ffi::sixtyfps_component_window_drop as usize
|
||||
+ component::ffi::sixtyfps_component_init_items as usize
|
||||
+ timers::ffi::sixtyfps_timer_start as usize
|
||||
}
|
||||
|
|
|
@ -302,3 +302,65 @@ fn lower_bound<T>(vec: &Vec<T>, mut less_than: impl FnMut(&T) -> bool) -> usize
|
|||
|
||||
left
|
||||
}
|
||||
|
||||
pub(crate) mod ffi {
|
||||
use super::*;
|
||||
#[allow(non_camel_case_types)]
|
||||
type c_void = ();
|
||||
|
||||
struct WrapFn {
|
||||
callback: extern "C" fn(*mut c_void),
|
||||
user_data: *mut c_void,
|
||||
drop_user_data: Option<extern "C" fn(*mut c_void)>,
|
||||
}
|
||||
|
||||
impl Drop for WrapFn {
|
||||
fn drop(&mut self) {
|
||||
if let Some(x) = self.drop_user_data {
|
||||
x(self.user_data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Start a timer with the given duration in millisecond.
|
||||
/// Returns the timer id.
|
||||
/// The timer MUST be stopped with sixtyfps_timer_stop
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sixtyfps_timer_start(
|
||||
duration: u64,
|
||||
callback: extern "C" fn(*mut c_void),
|
||||
user_data: *mut c_void,
|
||||
drop_user_data: Option<extern "C" fn(*mut c_void)>,
|
||||
) -> i64 {
|
||||
let wrap = WrapFn { callback, user_data, drop_user_data };
|
||||
let timer = Timer::default();
|
||||
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)
|
||||
}
|
||||
|
||||
/// Execute a callback with a delay in milisecond
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sixtyfps_timer_singleshot(
|
||||
delay: u64,
|
||||
callback: extern "C" fn(*mut c_void),
|
||||
user_data: *mut c_void,
|
||||
drop_user_data: Option<extern "C" fn(*mut c_void)>,
|
||||
) {
|
||||
let wrap = WrapFn { callback, user_data, drop_user_data };
|
||||
Timer::single_shot(core::time::Duration::from_millis(delay), move || {
|
||||
(wrap.callback)(wrap.user_data)
|
||||
});
|
||||
}
|
||||
|
||||
/// Stop a timer and free its raw data
|
||||
#[no_mangle]
|
||||
pub extern "C" fn sixtyfps_timer_stop(id: i64) {
|
||||
if id == -1 {
|
||||
return;
|
||||
}
|
||||
let timer = Timer { id: Cell::new(Some(id as _)) };
|
||||
timer.stop()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue