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