AceRoutine  1.4.2
A low-memory, fast-switching, cooperative multitasking library using stackless coroutines on Arduino platforms.
Static Public Member Functions | List of all members
ace_routine::CoroutineSchedulerTemplate< T_COROUTINE > Class Template Reference

Class that manages instances of the Coroutine class, and executes them in a round-robin fashion. More...

#include <CoroutineScheduler.h>

Static Public Member Functions

static void setup ()
 Set up the scheduler. More...
 
static void setupCoroutines ()
 Set up the coroutines by calling their setupCoroutine() methods.
 
static void loop ()
 Run the current coroutine using the current scheduler. More...
 
static void list (Print &printer)
 Print out the known coroutines to the printer (usually Serial). More...
 

Detailed Description

template<typename T_COROUTINE>
class ace_routine::CoroutineSchedulerTemplate< T_COROUTINE >

Class that manages instances of the Coroutine class, and executes them in a round-robin fashion.

This is expected to be used as a singleton.

Design Notes:

Originally, this class was intended to be more substantial, for example, I imagined that different scheduling algorithms could be implemented, allowing coroutines to have different priorities. To ensure that there was only a single instance of the CoroutineScheduler, a singleton pattern was used. The getScheduler() method fixes the problem that C++ does not guarantee the order of static initialization of resources defined in different files.

It seemed cumbersome to require the client code to go through the getScheduler() method to access the singleton instance. So each public instance method of the CoroutineScheduler is wrapped in a more user-friendly static method to make it easier to use. For example, CoroutineScheduler::setup() is a shorthand for CoroutineScheduler::getScheduler()->setupScheduler().

As the library matured, I started to put more emphasis on keeping the runtime overhead of the library as small as possible, especially on 8-bit AVR processors, to allow a Coroutine instance to be a viable alternative to writing a normal C/C++ function with complex internal finite state machines. It turned out that the simple round-robin scheduling algorithm currently implemented by CoroutineScheduler is good enough, and this class remained quite simple.

With its current functionality, the CoroutineSchedule does not need to be a singleton because the information that stores the singly-linked list of Coroutines is actually stored in the Coroutine class, not the CoroutineScheduler class. Because it does not need to be singleton, the getScheduler() method is not really required, and we could have just allowed the end-user to explicitly create an instance of CoroutineScheduler and use it like a normal object.

However, once the API of CoroutineScheduler with its static wrapper methods was released to the public, backwards compatibility meant that I could not remove this extra layer of indirection. Fortunately, the none of these methods are virtual, so the extra level of indirection consumes very little overhead, even on 8-bit AVR processors.

Definition at line 270 of file Coroutine.h.

Member Function Documentation

◆ list()

template<typename T_COROUTINE >
static void ace_routine::CoroutineSchedulerTemplate< T_COROUTINE >::list ( Print &  printer)
inlinestatic

Print out the known coroutines to the printer (usually Serial).

Note that if this method is never called, the linker will strip out the code. If Serial is never configured in setup(), then this method causes no additional flash memory consumption.

Definition at line 105 of file CoroutineScheduler.h.

◆ loop()

template<typename T_COROUTINE >
static void ace_routine::CoroutineSchedulerTemplate< T_COROUTINE >::loop ( )
inlinestatic

Run the current coroutine using the current scheduler.

This method returns when the underlying Coroutine suspends execution, which allows the system loop() to return to do systems processing, such as WiFi. Everyone must cooperate to make the whole thing work.

Definition at line 97 of file CoroutineScheduler.h.

◆ setup()

template<typename T_COROUTINE >
static void ace_routine::CoroutineSchedulerTemplate< T_COROUTINE >::setup ( )
inlinestatic

Set up the scheduler.

Should be called from the global setup().

Definition at line 84 of file CoroutineScheduler.h.


The documentation for this class was generated from the following files: