25 #ifndef ACE_ROUTINE_COROUTINE_SCHEDULER_H
26 #define ACE_ROUTINE_COROUTINE_SCHEDULER_H
28 #if ACE_ROUTINE_DEBUG == 1
32 #include "CoroutineProfiler.h"
36 namespace ace_routine {
81 template <
typename T_COROUTINE>
82 class CoroutineSchedulerTemplate {
85 static void setup() { getScheduler()->setupScheduler(); }
89 getScheduler()->setupCoroutinesInternal();
98 static void loop() { getScheduler()->runCoroutine(); }
107 getScheduler()->runCoroutineWithProfiler();
116 static void list(Print& printer) {
117 getScheduler()->listCoroutines(printer);
129 return &singletonScheduler;
133 CoroutineSchedulerTemplate() =
default;
145 void setupScheduler() {
146 mCurrent = T_COROUTINE::getRoot();
150 void setupCoroutinesInternal() {
151 for (T_COROUTINE** p = T_COROUTINE::getRoot();
153 p = (*p)->getNext()) {
155 (*p)->setupCoroutine();
163 void runCoroutine() {
165 if (*mCurrent ==
nullptr) {
166 mCurrent = T_COROUTINE::getRoot();
170 if (*mCurrent ==
nullptr) {
176 switch ((*mCurrent)->getStatus()) {
177 case T_COROUTINE::kStatusYielding:
178 case T_COROUTINE::kStatusDelaying:
183 (*mCurrent)->runCoroutine();
186 case T_COROUTINE::kStatusEnding:
188 (*mCurrent)->setTerminated();
197 mCurrent = (*mCurrent)->getNext();
204 void runCoroutineWithProfiler() {
206 if (*mCurrent ==
nullptr) {
207 mCurrent = T_COROUTINE::getRoot();
211 if (*mCurrent ==
nullptr) {
217 switch ((*mCurrent)->getStatus()) {
218 case T_COROUTINE::kStatusYielding:
219 case T_COROUTINE::kStatusDelaying:
227 (*mCurrent)->runCoroutineWithProfiler();
230 case T_COROUTINE::kStatusEnding:
232 (*mCurrent)->setTerminated();
241 mCurrent = (*mCurrent)->getNext();
245 void listCoroutines(Print& printer) {
246 for (T_COROUTINE** p = T_COROUTINE::getRoot(); (*p) !=
nullptr;
247 p = (*p)->getNext()) {
248 printer.print(F(
"Coroutine "));
249 (*p)->printNameTo(printer);
250 printer.print(F(
"; status: "));
251 (*p)->statusPrintTo(printer);
259 T_COROUTINE** mCurrent =
nullptr;
262 using CoroutineScheduler = CoroutineSchedulerTemplate<Coroutine>;