25 #ifndef ACE_ROUTINE_COROUTINE_SCHEDULER_H
26 #define ACE_ROUTINE_COROUTINE_SCHEDULER_H
28 #if ACE_ROUTINE_DEBUG == 1
35 namespace ace_routine {
80 template <
typename T_COROUTINE>
81 class CoroutineSchedulerTemplate {
84 static void setup() { getScheduler()->setupScheduler(); }
88 getScheduler()->setupCoroutinesInternal();
97 static void loop() { getScheduler()->runCoroutine(); }
105 static void list(Print& printer) {
106 getScheduler()->listCoroutines(printer);
118 return &singletonScheduler;
122 CoroutineSchedulerTemplate() =
default;
134 void setupScheduler() {
135 mCurrent = T_COROUTINE::getRoot();
139 void setupCoroutinesInternal() {
140 for (T_COROUTINE** p = T_COROUTINE::getRoot();
142 p = (*p)->getNext()) {
144 (*p)->setupCoroutine();
149 void runCoroutine() {
151 if (*mCurrent ==
nullptr) {
152 mCurrent = T_COROUTINE::getRoot();
156 if (*mCurrent ==
nullptr) {
161 #if ACE_ROUTINE_DEBUG == 1
162 Serial.print(F(
"Processing "));
163 Serial.print((uintptr_t) (*mCurrent));
168 switch ((*mCurrent)->getStatus()) {
169 case T_COROUTINE::kStatusYielding:
170 case T_COROUTINE::kStatusDelaying:
175 (*mCurrent)->runCoroutine();
178 case T_COROUTINE::kStatusEnding:
180 (*mCurrent)->setTerminated();
189 mCurrent = (*mCurrent)->getNext();
194 void listCoroutines(Print& printer) {
195 for (T_COROUTINE** p = T_COROUTINE::getRoot(); (*p) !=
nullptr;
196 p = (*p)->getNext()) {
197 printer.print(F(
"Coroutine "));
198 printer.print((uintptr_t) *p);
199 printer.print(F(
"; status: "));
200 (*p)->statusPrintTo(printer);
208 T_COROUTINE** mCurrent =
nullptr;
211 using CoroutineScheduler = CoroutineSchedulerTemplate<Coroutine>;