forked from slint-ui/slint
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtimer.rs
More file actions
138 lines (126 loc) · 4.97 KB
/
timer.rs
File metadata and controls
138 lines (126 loc) · 4.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
use pyo3::prelude::*;
use pyo3_stub_gen::{
derive::gen_stub_pyclass, derive::gen_stub_pyclass_enum, derive::gen_stub_pymethods,
};
/// The TimerMode specifies what should happen after the timer fired.
///
/// Used by the `Timer.start()` function.
#[derive(Copy, Clone, PartialEq)]
#[gen_stub_pyclass_enum]
#[pyclass(name = "TimerMode", eq, eq_int)]
pub enum PyTimerMode {
/// A SingleShot timer is fired only once.
SingleShot,
/// A Repeated timer is fired repeatedly until it is stopped or dropped.
Repeated,
}
impl From<PyTimerMode> for i_slint_core::timers::TimerMode {
fn from(value: PyTimerMode) -> Self {
match value {
PyTimerMode::SingleShot => i_slint_core::timers::TimerMode::SingleShot,
PyTimerMode::Repeated => i_slint_core::timers::TimerMode::Repeated,
}
}
}
/// Timer is a handle to the timer system that triggers a callback after a specified
/// period of time.
///
/// Use `Timer.start()` to create a timer that that repeatedly triggers a callback, or
/// `Timer.single_shot()` to trigger a callback only once.
///
/// The timer will automatically stop when garbage collected. You must keep the Timer object
/// around for as long as you want the timer to keep firing.
///
/// Timers can only be used in the thread that runs the Slint event loop. They don't
/// fire if used in another thread.
#[gen_stub_pyclass]
#[pyclass(name = "Timer", unsendable)]
pub struct PyTimer {
timer: i_slint_core::timers::Timer,
}
#[gen_stub_pymethods]
#[pymethods]
impl PyTimer {
#[new]
fn py_new() -> Self {
PyTimer { timer: Default::default() }
}
/// Starts the timer with the given mode and interval, in order for the callback to called when the
/// timer fires. If the timer has been started previously and not fired yet, then it will be restarted.
///
/// Arguments:
/// * `mode`: The timer mode to apply, i.e. whether to repeatedly fire the timer or just once.
/// * `interval`: The duration from now until when the timer should firethe first time, and subsequently
/// for `TimerMode.Repeated` timers.
/// * `callback`: The function to call when the time has been reached or exceeded.
fn start(
&self,
mode: PyTimerMode,
interval: chrono::Duration,
callback: PyObject,
) -> PyResult<()> {
let interval = interval
.to_std()
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
self.timer.start(mode.into(), interval, move || {
Python::with_gil(|py| {
callback.call0(py).expect("unexpected failure running python timer callback");
});
});
Ok(())
}
/// Starts the timer with the duration and the callback to called when the
/// timer fires. It is fired only once and then deleted.
///
/// Arguments:
/// * `duration`: The duration from now until when the timer should fire.
/// * `callback`: The function to call when the time has been reached or exceeded.
#[staticmethod]
fn single_shot(duration: chrono::Duration, callback: PyObject) -> PyResult<()> {
let duration = duration
.to_std()
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
i_slint_core::timers::Timer::single_shot(duration, move || {
Python::with_gil(|py| {
callback.call0(py).expect("unexpected failure running python timer callback");
});
});
Ok(())
}
/// Stops the previously started timer. Does nothing if the timer has never been started.
fn stop(&self) {
self.timer.stop();
}
/// Restarts the timer. If the timer was previously started by calling `Timer.start()`
/// with a duration and callback, then the time when the callback will be next invoked
/// is re-calculated to be in the specified duration relative to when this function is called.
///
/// Does nothing if the timer was never started.
fn restart(&self) {
self.timer.restart();
}
/// Set to true if the timer is running; false otherwise.
#[getter]
fn running(&self) -> bool {
self.timer.running()
}
/// The duration of timer.
///
/// When setting this property and the timer is running (see `Timer.running`),
/// then the time when the callback will be next invoked is re-calculated to be in the
/// specified duration relative to when this property is set.
#[setter]
fn set_interval(&self, interval: chrono::Duration) -> PyResult<()> {
let interval = interval
.to_std()
.map_err(|e| pyo3::exceptions::PyValueError::new_err(e.to_string()))?;
self.timer.set_interval(interval);
Ok(())
}
#[getter]
fn interval(&self) -> core::time::Duration {
self.timer.interval()
}
}