mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-01 14:21: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 <memory>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream> // FIXME: remove: iostream always bring it lots of code so we should not have it in this header
|
#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 {
|
namespace sixtyfps::cbindgen_private {
|
||||||
// Workaround https://github.com/eqrion/cbindgen/issues/43
|
// 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:
|
// layouts:
|
||||||
using cbindgen_private::box_layout_info;
|
using cbindgen_private::box_layout_info;
|
||||||
using cbindgen_private::BoxLayoutCellData;
|
using cbindgen_private::BoxLayoutCellData;
|
||||||
|
|
|
@ -85,4 +85,5 @@ pub fn use_modules() -> usize {
|
||||||
+ string::ffi::sixtyfps_shared_string_bytes as usize
|
+ string::ffi::sixtyfps_shared_string_bytes as usize
|
||||||
+ eventloop::ffi::sixtyfps_component_window_drop as usize
|
+ eventloop::ffi::sixtyfps_component_window_drop as usize
|
||||||
+ component::ffi::sixtyfps_component_init_items 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
|
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