morph 0.1.0
Asynchronous bridge between GUI thread and business models
Loading...
Searching...
No Matches
scheduler.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: Apache-2.0
2
3#pragma once
4#include <chrono>
5#include <cstddef>
6#include <functional>
7#include <memory>
8
9#include "../attributes.hpp"
10#include "../core/executor.hpp"
12
13class QObject;
14
15/// @file
16/// @brief `morph::qt_quick::QtScheduler`: `reactive::Scheduler` on Qt's timers.
17///
18/// Specified in `docs/spec/qt_quick/frontend.md`, "Scheduler".
19
20namespace morph::qt_quick {
21
22/// @brief `reactive::Scheduler` on `QTimer`s, for a runtime whose owner is the Qt event loop's thread.
23///
24/// Each callback runs on that thread with @p owner as the current executor, so it may write the reactive state the
25/// owner's runtime holds. It keeps every guarantee of the `Scheduler` contract: a cancelled timer never fires; a
26/// handle may be cancelled from inside its own callback and may outlive the scheduler; a periodic timer that the
27/// loop could not serve for several periods fires once. Neither copyable nor movable; used on its thread only.
28class QtScheduler final : public reactive::Scheduler {
29public:
30 /// @brief A scheduler whose timers belong to @p context.
31 /// @param owner The executor the callbacks run under. Borrowed: it outlives the scheduler.
32 /// @param context The object the timers are children of; null makes them children of an object the scheduler
33 /// owns.
34 explicit QtScheduler(exec::IExecutor& owner MORPH_LIFETIMEBOUND, QObject* context = nullptr);
35 /// @brief Stops every timer; a handle cancelled later does nothing.
36 ~QtScheduler() override;
37 QtScheduler(QtScheduler const&) = delete;
38 QtScheduler& operator=(QtScheduler const&) = delete;
39 QtScheduler(QtScheduler&&) = delete;
40 QtScheduler& operator=(QtScheduler&&) = delete;
41
42 /// @copydoc reactive::Scheduler::after
43 [[nodiscard]] reactive::TimerHandle after(std::chrono::milliseconds delay, std::function<void()> fn) override;
44 /// @copydoc reactive::Scheduler::every
45 [[nodiscard]] reactive::TimerHandle every(std::chrono::milliseconds period, std::function<void()> fn) override;
46
47 /// @brief How many timers are armed.
48 /// @return Their number.
49 [[nodiscard]] std::size_t pendingTimers() const noexcept;
50
51private:
52 struct State;
53 /// Arms @p fn @p delay from now, then every @p period; a zero @p period fires once.
54 // NOLINTNEXTLINE(bugprone-easily-swappable-parameters): the first delay, then the period, as `every` gives them.
55 [[nodiscard]] reactive::TimerHandle add(std::chrono::milliseconds delay, std::chrono::milliseconds period,
56 std::function<void()> fn);
57
58 std::shared_ptr<State> _state;
59};
60
61} // namespace morph::qt_quick
QtScheduler(exec::IExecutor &owner, QObject *context=nullptr)
A scheduler whose timers belong to context.
std::size_t pendingTimers() const noexcept
How many timers are armed.
reactive::TimerHandle every(std::chrono::milliseconds period, std::function< void()> fn) override
Runs fn every period, starting one period from now.
reactive::TimerHandle after(std::chrono::milliseconds delay, std::function< void()> fn) override
Runs fn once, delay from now.
~QtScheduler() override
Stops every timer; a handle cancelled later does nothing.
Runs callbacks after a delay or on a period, on the runtime's owner executor.
Owns one scheduled timer and cancels it when destroyed. Move-only.
Definition scheduler.hpp:19
morph::reactive::Scheduler: timers a frontend runs on the runtime's owner executor.
Abstract executor interface.
Definition executor.hpp:70