AUI Framework  master
Cross-platform module-based framework for developing C++20 desktop applications
AScheduler.h
1/*
2 * AUI Framework - Declarative UI toolkit for modern C++20
3 * Copyright (C) 2020-2024 Alex2772 and Contributors
4 *
5 * SPDX-License-Identifier: MPL-2.0
6 *
7 * This Source Code Form is subject to the terms of the Mozilla Public
8 * License, v. 2.0. If a copy of the MPL was not distributed with this
9 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 */
11
12#pragma once
13
14#include <chrono>
15#include <functional>
16#include <list>
17#include "AUI/Reflect/AEnumerate.h"
18#include <AUI/Thread/AMutex.h>
19#include <AUI/Thread/AConditionVariable.h>
20#include <AUI/Thread/IEventLoop.h>
21#include <AUI/Util/ABitField.h>
22
23
27AUI_ENUM_FLAG(ASchedulerIteration) {
28 NONE = 0,
29
37 DONT_BLOCK_INFINITELY = 0b1,
38
46 DONT_BLOCK_TIMED = 0b10,
47
51 DONT_BLOCK = DONT_BLOCK_INFINITELY | DONT_BLOCK_TIMED,
52};
53
58class API_AUI_CORE AScheduler: public IEventLoop {
59private:
60 using SchedulerDuration = std::chrono::microseconds;
61
62 struct Timer {
63 std::chrono::milliseconds timeout;
64 std::chrono::high_resolution_clock::time_point nextExecution;
65 std::function<void()> callback;
66 };
67
68 struct Task {
69 std::chrono::high_resolution_clock::time_point executionTime;
70 std::function<void()> callback;
71 _weak<Timer> timer;
72 };
73public:
75
76 AScheduler();
77
83 bool iteration(ABitField<ASchedulerIteration> flag = ASchedulerIteration::NONE);
84
85 void notifyProcessMessages() override;
86 void loop() override;
87
88 template<typename Duration>
89 void enqueue(Duration timeout, std::function<void()> callback) {
90 std::unique_lock lock(mSync);
91 Task asTask = {
92 std::chrono::duration_cast<SchedulerDuration>(timeout) + currentTime(),
93 std::move(callback)
94 };
95 enqueueTask(std::move(asTask));
96 mCV.notify_all();
97 }
98
107 template<typename Duration>
108 TimerHandle timer(Duration timeout, std::function<void()> callback) {
109 auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(timeout);
110 Timer t = {
111 millis,
112 millis + currentTime(),
113 std::move(callback)
114 };
115 auto asTimer = _new<Timer>(std::move(t));
116
117 std::unique_lock lock(mSync);
118 mTimers.push_back(asTimer);
119 enqueueTimer(asTimer);
120 return asTimer;
121 }
122
123
124 void removeTimer(const TimerHandle& t);
125
126 [[nodiscard]]
127 bool emptyTasks() const noexcept {
128 return mTasks.empty();
129 }
130
131 void stop() {
132 mIsRunning = false;
133 mCV.notify_all();
134 }
135
136
137private:
138 AMutex mSync;
140 bool mIsRunning = false;
141
142 std::list<Task> mTasks;
143 std::list<_<Timer>> mTimers;
144
145 static std::chrono::high_resolution_clock::time_point currentTime() noexcept {
146 return std::chrono::high_resolution_clock::now();
147 }
148
149 void enqueueTimer(const _<Timer>& timer) {
150 Task t = {
151 timer->nextExecution,
152 [this, timer]() {
153 timer->callback();
154 std::unique_lock lock(mSync);
155 enqueueTimer(timer);
156 },
157 timer
158 };
159 timer->nextExecution += timer->timeout;
160 enqueueTask(std::move(t));
161 }
162
163
164 void enqueueTask(Task&& asTask) {
165 auto whereToInsert = std::find_if(mTasks.begin(), mTasks.end(), [&](const Task& rhs) {
166 return asTask.executionTime < rhs.executionTime;
167 });
168
169 mTasks.insert(whereToInsert, std::move(asTask));
170 mCV.notify_all();
171 }
172
173};
Bit field implementation.
Definition: ABitField.h:20
Represents a condition variable.
Definition: AConditionVariable.h:24
void notify_all() noexcept
Definition: AConditionVariable.h:62
Basic scheduler used for timers.
Definition: AScheduler.h:58
TimerHandle timer(Duration timeout, std::function< void()> callback)
Creates a timer.
Definition: AScheduler.h:108
Definition: IEventLoop.h:17
virtual void loop()=0
Do message processing loop.
virtual void notifyProcessMessages()=0
Notifies this IEventLoop that its thread got a new message to process.
An std::weak_ptr with AUI extensions.
Definition: SharedPtrTypes.h:177
@ NONE
Image is kept in it's original size.
AUI_ENUM_FLAG(ASide)
Describes sides of a 2D rectangle.
Definition: ASide.h:24
Basic syscall-based synchronization primitive.
Definition: AMutex.h:33
An std::weak_ptr with AUI extensions.
Definition: SharedPtrTypes.h:51