1 | // Copyright © SixtyFPS GmbH <info@slint.dev> |
2 | // SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial |
3 | |
4 | // cSpell: ignore singleshot |
5 | |
6 | #pragma once |
7 | |
8 | #include <chrono> |
9 | |
10 | #include <slint_timer_internal.h> |
11 | |
12 | namespace slint { |
13 | |
14 | using cbindgen_private::TimerMode; |
15 | |
16 | /// A Timer that can call a callback at repeated interval |
17 | /// |
18 | /// Use the static single_shot function to make a single shot timer |
19 | struct Timer |
20 | { |
21 | /// Construct a null timer. Use the start() method to activate the timer with a mode, interval |
22 | /// and callback. |
23 | Timer() = default; |
24 | /// Construct a timer which will repeat the callback every `interval` milliseconds until |
25 | /// the destructor of the timer is called. |
26 | /// |
27 | /// This is a convenience function and equivalent to calling |
28 | /// `start(slint::TimerMode::Repeated, interval, callback);` on a default constructed Timer. |
29 | template<std::invocable F> |
30 | Timer(std::chrono::milliseconds interval, F callback) |
31 | : id(cbindgen_private::slint_timer_start( |
32 | id: 0, mode: TimerMode::Repeated, duration: interval.count(), |
33 | callback: [](void *data) { (*reinterpret_cast<F *>(data))(); }, user_data: new F(std::move(callback)), |
34 | drop_user_data: [](void *data) { delete reinterpret_cast<F *>(data); })) |
35 | { |
36 | } |
37 | Timer(const Timer &) = delete; |
38 | Timer &operator=(const Timer &) = delete; |
39 | ~Timer() { cbindgen_private::slint_timer_destroy(id); } |
40 | |
41 | /// Starts the timer with the given \a mode and \a interval, in order for the \a callback to |
42 | /// called when the timer fires. If the timer has been started previously and not fired yet, |
43 | /// then it will be restarted. |
44 | template<std::invocable F> |
45 | void start(TimerMode mode, std::chrono::milliseconds interval, F callback) |
46 | { |
47 | id = cbindgen_private::slint_timer_start( |
48 | id, mode, duration: interval.count(), callback: [](void *data) { (*reinterpret_cast<F *>(data))(); }, |
49 | user_data: new F(std::move(callback)), drop_user_data: [](void *data) { delete reinterpret_cast<F *>(data); }); |
50 | } |
51 | /// Stops the previously started timer. Does nothing if the timer has never been started. A |
52 | /// stopped timer cannot be restarted with restart(). Use start() instead. |
53 | void stop() { cbindgen_private::slint_timer_stop(id); } |
54 | /// Restarts the timer. If the timer was previously started by calling [`Self::start()`] |
55 | /// with a duration and callback, then the time when the callback will be next invoked |
56 | /// is re-calculated to be in the specified duration relative to when this function is called. |
57 | /// |
58 | /// Does nothing if the timer was never started. |
59 | void restart() { cbindgen_private::slint_timer_restart(id); } |
60 | /// Returns true if the timer is running; false otherwise. |
61 | bool running() const { return cbindgen_private::slint_timer_running(id); } |
62 | |
63 | /// Call the callback after the given duration. |
64 | template<std::invocable F> |
65 | static void single_shot(std::chrono::milliseconds duration, F callback) |
66 | { |
67 | cbindgen_private::slint_timer_singleshot( |
68 | delay: duration.count(), callback: [](void *data) { (*reinterpret_cast<F *>(data))(); }, |
69 | user_data: new F(std::move(callback)), drop_user_data: [](void *data) { delete reinterpret_cast<F *>(data); }); |
70 | } |
71 | |
72 | private: |
73 | uint64_t id = 0; |
74 | }; |
75 | |
76 | } // namespace slint |
77 | |