AceRoutine  0.1
A low-memory, fast-switching, cooperative multitasking library using stackless coroutines on Arduino platforms.
Public Member Functions | Static Public Member Functions | Protected Types | Protected Member Functions | Static Protected Attributes | Friends | List of all members
ace_routine::Coroutine Class Referenceabstract

Base class of all coroutines. More...

#include <Coroutine.h>

Inheritance diagram for ace_routine::Coroutine:
Inheritance graph
[legend]

Public Member Functions

Coroutine ** getNext ()
 Return the next pointer as a pointer to the pointer, similar to getRoot(). More...
 
const FCStringgetName () const
 Human-readable name of the coroutine. More...
 
virtual int run ()=0
 The body of the coroutine. More...
 
virtual unsigned long millis () const
 Returns the current millisecond clock. More...
 
void suspend ()
 Suspend the coroutine at the next scheduler iteration. More...
 
void resume ()
 Add a Suspended coroutine into the head of the scheduler linked list, and change the state to Yielding. More...
 
bool isDelayExpired ()
 Check if delay time is over. More...
 
bool isSuspended () const
 The coroutine was suspended with a call to suspend(). More...
 
bool isYielding () const
 The coroutine returned using COROUTINE_YIELD(). More...
 
bool isAwaiting () const
 The coroutine returned using COROUTINE_AWAIT(). More...
 
bool isDelaying () const
 The coroutine returned using COROUTINE_DELAY(). More...
 
bool isRunning () const
 The coroutine is currently running. More...
 
bool isEnding () const
 The coroutine returned using COROUTINE_END(). More...
 
bool isTerminated () const
 The coroutine was terminated by the scheduler with a call to setTerminated(). More...
 
bool isDone () const
 The coroutine is either Ending or Terminated. More...
 

Static Public Member Functions

static Coroutine ** getRoot ()
 Get the pointer to the root pointer. More...
 

Protected Types

typedef uint8_t Status
 The execution status of the coroutine, corresponding to the COROUTINE_YIELD(), COROUTINE_DELAY(), COROUTINE_AWAIT() and COROUTINE_END() macros. More...
 

Protected Member Functions

 Coroutine ()
 Constructor. More...
 
void init (const char *name)
 Initialize the coroutine, set it to Yielding state, and add it to the linked list of coroutines. More...
 
void init (const __FlashStringHelper *name)
 Same as init(const char*) except using flash string type. More...
 
Status getStatus () const
 Return the status of the coroutine. More...
 
void setJump (void *jumpPoint)
 Pointer to label where execute will start on the next call to run(). More...
 
void * getJump () const
 Pointer to label where execute will start on the next call to run(). More...
 
void setRunning ()
 Set the kStatusRunning state. More...
 
void setYielding ()
 Set the kStatusDelaying state. More...
 
void setAwaiting ()
 Set the kStatusAwaiting state. More...
 
void setDelaying ()
 Set the kStatusDelaying state. More...
 
void setDelay (uint16_t delayMillisDuration)
 Configure the delay timer. More...
 
void setEnding ()
 Set the kStatusEnding state. More...
 
void setTerminated ()
 Set status to indicate that the Coroutine has been removed from the Scheduler queue. More...
 

Static Protected Attributes

static const Status kStatusSuspended = 0
 Coroutine has been suspended using suspend() and the scheduler should remove it from the queue upon the next iteration. More...
 
static const Status kStatusYielding = 1
 Coroutine returned using the COROUTINE_YIELD() statement. More...
 
static const Status kStatusAwaiting = 2
 Coroutine returned using the COROUTINE_AWAIT() statement. More...
 
static const Status kStatusDelaying = 3
 Coroutine returned using the COROUTINE_DELAY() statement. More...
 
static const Status kStatusRunning = 4
 Coroutine is currenly running. More...
 
static const Status kStatusEnding = 5
 Coroutine executed the COROUTINE_END() statement. More...
 
static const Status kStatusTerminated = 6
 Coroutine has ended and no longer in the scheduler queue. More...
 

Friends

class CoroutineScheduler
 

Detailed Description

Base class of all coroutines.

The actual coroutine code is an implementation of the virtual run() method.

Definition at line 217 of file Coroutine.h.

Member Typedef Documentation

◆ Status

typedef uint8_t ace_routine::Coroutine::Status
protected

The execution status of the coroutine, corresponding to the COROUTINE_YIELD(), COROUTINE_DELAY(), COROUTINE_AWAIT() and COROUTINE_END() macros.

The finite state diagram looks like this:

*          Suspended
*          ^   ^   ^
*         /    |    \
*        /     |     \
*       v      |      \
* Yielding Awaiting Delaying
*      ^       ^       ^
*       \      |      /
*        \     |     /
*         \    |    /
*          v   v   v
*           Running
*              |
*              |
*              v
*           Ending
*              |
*              |
*              v
*         Terminated
* 

Definition at line 355 of file Coroutine.h.

Constructor & Destructor Documentation

◆ Coroutine()

ace_routine::Coroutine::Coroutine ( )
inlineprotected

Constructor.

Definition at line 384 of file Coroutine.h.

Member Function Documentation

◆ getJump()

void* ace_routine::Coroutine::getJump ( ) const
inlineprotected

Pointer to label where execute will start on the next call to run().

Definition at line 412 of file Coroutine.h.

◆ getName()

const FCString& ace_routine::Coroutine::getName ( ) const
inline

Human-readable name of the coroutine.

Definition at line 236 of file Coroutine.h.

◆ getNext()

Coroutine** ace_routine::Coroutine::getNext ( )
inline

Return the next pointer as a pointer to the pointer, similar to getRoot().

This makes it much easier to manipulate a singly-linked list. Also makes setNext() method unnecessary.

Definition at line 233 of file Coroutine.h.

◆ getRoot()

Coroutine ** ace_routine::Coroutine::getRoot ( )
static

Get the pointer to the root pointer.

Implemented as a function static to fix the C++ static initialization problem, making it safe to use this in other static contexts.

Definition at line 33 of file Coroutine.cpp.

◆ getStatus()

Status ace_routine::Coroutine::getStatus ( ) const
inlineprotected

Return the status of the coroutine.

Used by the CoroutineScheduler.

Definition at line 406 of file Coroutine.h.

◆ init() [1/2]

void ace_routine::Coroutine::init ( const char *  name)
inlineprotected

Initialize the coroutine, set it to Yielding state, and add it to the linked list of coroutines.

Parameters
nameThe name of the coroutine as a human-readable string.

Definition at line 392 of file Coroutine.h.

◆ init() [2/2]

void ace_routine::Coroutine::init ( const __FlashStringHelper *  name)
inlineprotected

Same as init(const char*) except using flash string type.

Definition at line 399 of file Coroutine.h.

◆ isAwaiting()

bool ace_routine::Coroutine::isAwaiting ( ) const
inline

The coroutine returned using COROUTINE_AWAIT().

Definition at line 292 of file Coroutine.h.

◆ isDelayExpired()

bool ace_routine::Coroutine::isDelayExpired ( )
inline

Check if delay time is over.

Definition at line 280 of file Coroutine.h.

◆ isDelaying()

bool ace_routine::Coroutine::isDelaying ( ) const
inline

The coroutine returned using COROUTINE_DELAY().

Definition at line 295 of file Coroutine.h.

◆ isDone()

bool ace_routine::Coroutine::isDone ( ) const
inline

The coroutine is either Ending or Terminated.

This method is recommended over isEnding() or isTerminated() because it works when the coroutine is executed either manually or through the CoroutineScheduler.

Definition at line 320 of file Coroutine.h.

◆ isEnding()

bool ace_routine::Coroutine::isEnding ( ) const
inline

The coroutine returned using COROUTINE_END().

In most cases, isDone() is recommended instead because it works when coroutines are executed manually or through the CoroutineScheduler.

Definition at line 305 of file Coroutine.h.

◆ isRunning()

bool ace_routine::Coroutine::isRunning ( ) const
inline

The coroutine is currently running.

True only within the coroutine.

Definition at line 298 of file Coroutine.h.

◆ isSuspended()

bool ace_routine::Coroutine::isSuspended ( ) const
inline

The coroutine was suspended with a call to suspend().

Definition at line 286 of file Coroutine.h.

◆ isTerminated()

bool ace_routine::Coroutine::isTerminated ( ) const
inline

The coroutine was terminated by the scheduler with a call to setTerminated().

In most cases, isDone() should be used instead because it works when coroutines are executed manually or through the CoroutineScheudler.

Definition at line 313 of file Coroutine.h.

◆ isYielding()

bool ace_routine::Coroutine::isYielding ( ) const
inline

The coroutine returned using COROUTINE_YIELD().

Definition at line 289 of file Coroutine.h.

◆ millis()

unsigned long ace_routine::Coroutine::millis ( ) const
virtual

Returns the current millisecond clock.

By default it returns the global millis() function from Arduino but can be overridden for testing.

Definition at line 66 of file Coroutine.cpp.

◆ resume()

void ace_routine::Coroutine::resume ( )

Add a Suspended coroutine into the head of the scheduler linked list, and change the state to Yielding.

If the coroutine is in any other state, this method does nothing. This method works only if the CoroutineScheduler::loop() is used.

Definition at line 51 of file Coroutine.cpp.

◆ run()

virtual int ace_routine::Coroutine::run ( )
pure virtual

The body of the coroutine.

The COROUTINE macro creates a subclass of this class and puts the body of the coroutine into this method.

Returns
The return value is always ignored. This method is declared to return an int to prevent the user from accidentally returning from this method using an explicit 'return' statement instead of through one of the macros (e.g. COROUTINE_YIELD(), COROUTINE_DELAY(), COROUTINE_AWAIT() or COROUTINE_END()).

Implemented in ace_routine::cli::CommandDispatcher.

◆ setAwaiting()

void ace_routine::Coroutine::setAwaiting ( )
inlineprotected

Set the kStatusAwaiting state.

Definition at line 421 of file Coroutine.h.

◆ setDelay()

void ace_routine::Coroutine::setDelay ( uint16_t  delayMillisDuration)
inlineprotected

Configure the delay timer.

The maximum duration is set to (UINT16_MAX / 2) (i.e. 32767 milliseconds) if given a larger value. This makes the longest allowable time between two successive calls to isDelayExpired() for a given coroutine to be 32767 (UINT16_MAX - UINT16_MAX / 2 - 1) milliseconds, which should be long enough for basically all real use-cases. (The '- 1' comes from an edge case where isDelayExpired() evaluates to be true in the CoroutineScheduler::runCoroutine() but becomes to be false in the COROUTINE_DELAY() macro inside Coroutine::run()) because the clock increments by 1 millisecond.)

Definition at line 437 of file Coroutine.h.

◆ setDelaying()

void ace_routine::Coroutine::setDelaying ( )
inlineprotected

Set the kStatusDelaying state.

Definition at line 424 of file Coroutine.h.

◆ setEnding()

void ace_routine::Coroutine::setEnding ( )
inlineprotected

Set the kStatusEnding state.

Definition at line 445 of file Coroutine.h.

◆ setJump()

void ace_routine::Coroutine::setJump ( void *  jumpPoint)
inlineprotected

Pointer to label where execute will start on the next call to run().

Definition at line 409 of file Coroutine.h.

◆ setRunning()

void ace_routine::Coroutine::setRunning ( )
inlineprotected

Set the kStatusRunning state.

Definition at line 415 of file Coroutine.h.

◆ setTerminated()

void ace_routine::Coroutine::setTerminated ( )
inlineprotected

Set status to indicate that the Coroutine has been removed from the Scheduler queue.

Should be used only by the CoroutineScheduler.

Definition at line 451 of file Coroutine.h.

◆ setYielding()

void ace_routine::Coroutine::setYielding ( )
inlineprotected

Set the kStatusDelaying state.

Definition at line 418 of file Coroutine.h.

◆ suspend()

void ace_routine::Coroutine::suspend ( )
inline

Suspend the coroutine at the next scheduler iteration.

If the coroutine is already in the process of ending or is already terminated, then this method does nothing. A coroutine cannot use this method to suspend itself, it can only suspend some other coroutine. Currently, there is no ability for a coroutine to suspend itself, that would require the addition of a COROUTINE_SUSPEND() macro. Also, this method works only if the CoroutineScheduler::loop() is used because the suspend functionality is implemented by the CoroutineScheduler.

Definition at line 266 of file Coroutine.h.

Member Data Documentation

◆ kStatusAwaiting

const Status ace_routine::Coroutine::kStatusAwaiting = 2
staticprotected

Coroutine returned using the COROUTINE_AWAIT() statement.

Definition at line 369 of file Coroutine.h.

◆ kStatusDelaying

const Status ace_routine::Coroutine::kStatusDelaying = 3
staticprotected

Coroutine returned using the COROUTINE_DELAY() statement.

Definition at line 372 of file Coroutine.h.

◆ kStatusEnding

const Status ace_routine::Coroutine::kStatusEnding = 5
staticprotected

Coroutine executed the COROUTINE_END() statement.

Definition at line 378 of file Coroutine.h.

◆ kStatusRunning

const Status ace_routine::Coroutine::kStatusRunning = 4
staticprotected

Coroutine is currenly running.

True only within the coroutine itself.

Definition at line 375 of file Coroutine.h.

◆ kStatusSuspended

const Status ace_routine::Coroutine::kStatusSuspended = 0
staticprotected

Coroutine has been suspended using suspend() and the scheduler should remove it from the queue upon the next iteration.

We don't distinguish whether the coroutine is still in the queue or not with this status. We can add that later if we need to.

Definition at line 363 of file Coroutine.h.

◆ kStatusTerminated

const Status ace_routine::Coroutine::kStatusTerminated = 6
staticprotected

Coroutine has ended and no longer in the scheduler queue.

Definition at line 381 of file Coroutine.h.

◆ kStatusYielding

const Status ace_routine::Coroutine::kStatusYielding = 1
staticprotected

Coroutine returned using the COROUTINE_YIELD() statement.

Definition at line 366 of file Coroutine.h.


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