Uniot Core
0.8.1
Loading...
Searching...
No Matches
TaskScheduler.h
Go to the documentation of this file.
1/*
2 * This is a part of the Uniot project.
3 * Copyright (C) 2016-2020 Uniot <contact@uniot.io>
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
26
32
33#pragma once
34
35#if defined(ESP8266)
36#include "ESP8266Task.h"
37#elif defined(ESP32)
38#include "ESP32Task.h"
39#endif
40
41#include <Common.h>
42#include <IExecutor.h>
44#include <IterableQueue.h>
45
46#include <functional>
47#include <memory>
48
49namespace uniot {
50
51#if defined(ESP8266)
53#elif defined(ESP32)
54using Task = ESP32Task;
55#endif
56
67class SchedulerTask : public Task {
68 public:
75 using SchedulerTaskCallback = std::function<void(SchedulerTask &, short)>; // TODO: add ms to callback
76
81
88 : SchedulerTask([&](SchedulerTask &, short times) { executor.execute(times); }) {}
89
96 : Task(), mTotalElapsedMs(0), mRepeatTimes(0), mCanDoHardWork(false) {
97 mspCallback = std::make_shared<SchedulerTaskCallback>(callback);
98 }
99
106 void attach(uint32_t ms, short times = 0) { // TODO: auto detach
107 mRepeatTimes = times > 0 ? times : -1;
108 Task::attach<volatile bool *>(ms, mRepeatTimes != 1, [](volatile bool *can) { *can = true; }, &mCanDoHardWork);
109 }
110
116 void once(uint32_t ms) {
117 attach(ms, 1);
118 }
119
126 inline void loop() {
127 auto startMs = millis();
128 if (mCanDoHardWork) {
129 mCanDoHardWork = false;
130
131 if (mRepeatTimes > 0 && !--mRepeatTimes) {
132 Task::detach();
133 }
134 (*mspCallback)(*this, mRepeatTimes);
135 }
136 mTotalElapsedMs += millis() - startMs;
137 }
138
144 uint64_t getTotalElapsedMs() const {
145 return mTotalElapsedMs;
146 }
147
148 private:
149 uint64_t mTotalElapsedMs;
150 short mRepeatTimes;
151 volatile bool mCanDoHardWork;
152 spSchedulerTaskCallback mspCallback;
153};
154
155
167 public:
172
180 using TaskInfoCallback = std::function<void(const char *, bool, uint64_t)>;
181
185 TaskScheduler() : mTotalElapsedMs(0) {}
186
194 return std::make_shared<SchedulerTask>(callback);
195 }
196
203 static TaskPtr make(IExecutor &executor) {
204 return std::make_shared<SchedulerTask>(executor);
205 }
206
214 TaskScheduler &push(const char *name, TaskPtr task) {
215 mTasks.push(MakePair(name, task));
216 return *this;
217 }
218
226 connection.pushTo(*this);
227 return *this;
228 }
229
235 inline void loop() {
236 auto startMs = millis();
237 mTasks.begin();
238 while (!mTasks.isEnd()) {
239 const auto &task = mTasks.current();
240 task.second->loop();
241
242 // Remove anonymous tasks only if they are detached (finished)
243 if (!task.first && !task.second->isAttached()) {
244 // auto wasSize = mTasks.calcSize();
245 mTasks.deleteCurrent();
246 // auto newSize = mTasks.calcSize();
247 // UNIOT_LOG_DEBUG("Anonymous task removed, size: %d -> %d", wasSize, newSize);
248 } else {
249 mTasks.next();
250 }
251
252 yield();
253 }
254 mTotalElapsedMs += millis() - startMs;
255 }
256
262 void exportTasksInfo(TaskInfoCallback callback) const {
263 if (!callback) {
264 return;
265 }
266
267 uint64_t totalAnonymousElapsedMs = 0;
268 uint8_t anonymousTaskCount = 0;
269
270 mTasks.forEach([&](const Pair<const char *, TaskPtr> &task) {
271 if (task.first) {
272 callback(task.first, task.second->isAttached(), task.second->getTotalElapsedMs());
273 } else {
274 totalAnonymousElapsedMs += task.second->getTotalElapsedMs();
275 anonymousTaskCount++;
276 }
277 });
278
279 if (anonymousTaskCount > 0) {
280 constexpr size_t BUFFER_SIZE = 20;
281 static char anonymousTaskName[BUFFER_SIZE];
282 snprintf(anonymousTaskName, BUFFER_SIZE, "__anonymous[%d]", anonymousTaskCount);
283 callback(anonymousTaskName, true, totalAnonymousElapsedMs);
284 }
285 }
286
292 uint64_t getTotalElapsedMs() const {
293 return mTotalElapsedMs;
294 }
295
296 private:
297 uint64_t mTotalElapsedMs;
300};
301
302} // namespace uniot
ESP32-specific task implementation for the Uniot Core.
Definition IterableQueue.h:36
Definition ESP32Task.h:41
Definition ESP8266Task.h:48
void attach(uint32_t ms, bool repeat, TaskCallback callback)
Attach a simple callback to run periodically.
Definition ESP8266Task.h:86
void detach()
Stop and detach the timer.
Definition ESP8266Task.h:107
Interface for executing tasks in the scheduler system.
Definition IExecutor.h:31
virtual void execute(short times)=0
Execute the implementation's functionality.
Interface for connecting components to the TaskScheduler.
Definition ISchedulerConnectionKit.h:35
virtual void pushTo(TaskScheduler &scheduler)=0
Register this component with the given scheduler.
uint64_t getTotalElapsedMs() const
Get the total execution time of this task in milliseconds.
Definition TaskScheduler.h:144
SchedulerTask(SchedulerTaskCallback callback)
Constructor with custom callback function.
Definition TaskScheduler.h:95
SchedulerTask(IExecutor &executor)
Constructor that wraps an IExecutor implementation.
Definition TaskScheduler.h:87
SharedPointer< SchedulerTaskCallback > spSchedulerTaskCallback
Shared pointer type for task callbacks.
Definition TaskScheduler.h:80
void loop()
Main execution loop for the task.
Definition TaskScheduler.h:126
std::function< void(SchedulerTask &, short)> SchedulerTaskCallback
Callback function signature for scheduled tasks.
Definition TaskScheduler.h:75
void once(uint32_t ms)
Schedule the task to run once after the specified delay.
Definition TaskScheduler.h:116
void attach(uint32_t ms, short times=0)
Attach the task to run on a specified interval.
Definition TaskScheduler.h:106
auto MakePair(Args &&...args) -> decltype(std::make_pair(std::forward< Args >(args)...))
Creates a pair instance, alias for std::make_pair.
Definition Common.h:184
std::shared_ptr< T > SharedPointer
Type alias for std::shared_ptr with cleaner syntax.
Definition Common.h:160
std::pair< T_First, T_Second > Pair
Type alias for std::pair with cleaner syntax.
Definition Common.h:169
SharedPointer< SchedulerTask > TaskPtr
Shared pointer type for scheduler tasks.
Definition TaskScheduler.h:171
std::function< void(const char *, bool, uint64_t)> TaskInfoCallback
Callback signature for task status reporting.
Definition TaskScheduler.h:180
void exportTasksInfo(TaskInfoCallback callback) const
Report information about all registered tasks.
Definition TaskScheduler.h:262
TaskScheduler()
Constructor.
Definition TaskScheduler.h:185
static TaskPtr make(SchedulerTask::SchedulerTaskCallback callback)
Static factory method to create a task with a callback.
Definition TaskScheduler.h:193
static TaskPtr make(IExecutor &executor)
Static factory method to create a task from an IExecutor.
Definition TaskScheduler.h:203
TaskScheduler & push(const char *name, TaskPtr task)
Add a named task to the scheduler.
Definition TaskScheduler.h:214
uint64_t getTotalElapsedMs() const
Get the total execution time of the scheduler in milliseconds.
Definition TaskScheduler.h:292
TaskScheduler & push(ISchedulerConnectionKit &connection)
Add connection kit components to the scheduler.
Definition TaskScheduler.h:225
void loop()
Main execution loop for the scheduler.
Definition TaskScheduler.h:235
Contains all classes and functions related to the Uniot Core.
ESP8266Task Task
Definition TaskScheduler.h:52