# SFBAlarm Class Reference

Manage "alarm clock"-style settable timers. More...

`#include <SFBAlarm.h>`

## Public Member Functions
u32 | create (SFBAlarmHandler handler)
| Create a new alarm, return its corresponding alarm number.
u32 | create (SFBAlarmArgHandler handler, void *arg)
| Create a new alarm, return its corresponding alarm number.
void | update (u32 alarmNumber, SFBAlarmHandler handler)
| Alter the handler of an existing alarm.
void | update (u32 alarmNumber, SFBAlarmArgHandler handler, void *arg)
| Alter the handler and/or the extra argument of an existing alarm.
u32 | get (u32 alarmNumber)
| If alarm alarmNumber is set, access the alarm time.
bool | set (u32 alarmNumber, u32 when)
| Set (or reset) alarm alarmNumber to go off at when.
bool | cancel (u32 alarmNumber)
| Cancel any pending alarm for alarm alarmNumber.
u32 | currentAlarmNumber ()
| Find out what alarm number is currently active.
int | runDueEvents (int maxEvents, u32 deadline)
| [Intended for core use only]
int | runPriorityEvents (int maxEvents, u32 priorityAtLeast)
| [Intended for core use only]
bool | canCreate ()
| Determine if it is possible to create another alarm.
u32 | created ()
| Return the number of alarms have been created.
bool | canAdd ()
| [Intended for core use] `true` iff the internal alarm queue isn't full
bool | canRemove ()
| Return `true` if count() is greater than zero, else `false`.
u32 | count ()
| Return the number of currently set() alarms.
bool | inUse (u32 alarmIndex)
| `true` iff alarmIndex is a legal, currently scheduled alarm number.
u32 | getTopTime ()
| Get the earliest time in the queue.

## Detailed Description

Manage "alarm clock"-style settable timers.

For working code samples, see alarm1::cpp, alarm2::cpp, and alarm3::cpp; the rest of this description discusses internals of the system.

## Theory of operation

The primary, somewhat incompatible, goals of this implementation are:

1. Fast, high resolution alarm scheduling, accurate to the millisecond barring load
2. Integrate tightly with the core so that alarm triggering is automatic
3. Easy-to-use API involving no interrupt level code and a minimum of pointers
4. Internal data structures are incorruptible by API calls regardless of arguments
5. Complete freedom to set and cancel alarms without caring if they were previously set
6. Support dozens of alarms reasonably compactly, without dynamic allocation

The most consequential design decision is to refer to alarms by a non-zero 'alarm number' rather than via pointer, primarily in support of goals (3) and (4). In addition, to reduce risk of confusion, there is no support for destroying alarm numbers once they are created (although update(u32 alarmNumber, SFBAlarmHandler handler) can be used to achieve the effect of an alarm number destruction and immediate reallocation).

The result is a conventional heap-based priority queue implementation, using an indirect index array 'slots' to reorder elements without copying the element info, and a reverse array 'idxs' to find the current priority queue position of an element, to support deletion and priority changes.

      used      alarms
        +----+    +----+
        |  3 |    |  4 |
        +----+    +----+
                 alarm
         slots   Number idxs     times      handlers     args
         +----+        +----+ +---------+ +---------+ +---------+
      0  | xx |     0  | 0  | |   --    | |   --    | |   --    |
         +----+        +----+ +---------+ +---------+ +---------+
      1  | 3  |     1  | 2  | |     210 | | MyAlarm | |   0     |
         +----+        +----+ +---------+ +---------+ +---------+
      2  | 1  |     2  | 3  | |     309 | |  Serial | |&SerPort1|
         +----+        +----+ +---------+ +---------+ +---------+
      3  | 2  |     3  | 1  | |     123 | |  Serial | |&SerPort0|
         +----+        +----+ +---------+ +---------+ +---------+
      4  | 4  |     4  | 0  | |    ??   | |    ??   | |    ??   |
         +----+        +----+ +---------+ +---------+ +---------+

Mapping invariants:

- (i >= 1 && i <= used) => idxs[slots[i]] == i

- (used <= alarms) - You can't have more events scheduled than are defined..

- (There's also the priority queue invariant, of course..)

Alarms RAM usage (allocated in bodyram) is 14*SFBALARM_QUEUE_SIZE+4, currently a total of 720 bytes after alignment.

## Member Function Documentation

bool SFBAlarm::cancel | ( | u32 | alarmNumber | ) |

Cancel any pending alarm for alarm alarmNumber.

Parameters:

  | alarmNumber | The alarm to cancel

Returns:
  `true` if the alarm had been currently set, `false` if not.

Blinks:
  E_API_BAD_ALARM if alarmNumber is not an alarm number previously returned by create(SFBAlarmHandler) or create(SFBAlarmArgHandler,void*)

bool SFBAlarm::canCreate | ( |  | ) |

Determine if it is possible to create another alarm.

The alarm creating functions create(SFBAlarmHandler) and create(SFBAlarmArgHandler,void*) die blinking if they are called when there's no more room to create an additional alarm. To avoid that risk, a sketch may call this function first.

Returns:
  `true` if at least one more alarm can be created, `false` otherwise.

u32 SFBAlarm::create | ( | SFBAlarmArgHandler | handler,
|  | void * | arg |
| ) |  |  |

Create a new alarm, return its corresponding alarm number.

This is the 'more advanced' alarm creation method, providing an additional arg agument for use by the alarm handlers; see alarm3::cpp for a usage example. For the simpler 'basic alarm' creation mechanism see create(SFBAlarmHandler).

Note this method blinks E_API_NO_MORE_ALARMS if no more alarms are available; if a sketch needs to survive running out of alarms it must call canCreate() to ascertain that another alarm is available before calling this method.

Parameters:

  | handler | function to call whenever this alarm goes off
  | arg | an arbitrary pointer value to associate with this alarm, which will be provided as the second argument to handler whenever the alarm goes off.

Returns:
  a non-zero `alarmNumber` to use to refer to this alarm in the future

Blinks:
  E_API_NO_MORE_ALARMS if the alarm system is full so a new alarm could not be created.

u32 SFBAlarm::create | ( | SFBAlarmHandler | handler | ) |

Create a new alarm, return its corresponding alarm number.

Note this method blinks E_API_NO_MORE_ALARMS if no more alarms are available; if a sketch needs to survive running out of alarms it must call canCreate() to ascertain that another alarm is available before calling this method.

This is the simpler method of the two methods of creating an alarm; see also create(SFBAlarmArgHandler, void *) for a more advanced mechanism that provides additional flexibility.

Parameters:

  | handler | function to call whenever this alarm goes off

Returns:
  a non-zero `alarmNumber` to use to refer to this alarm in the future

Blinks:
  E_API_NO_MORE_ALARMS if the alarm system is full so a new alarm could not be created.

Examples:
  alarm1.cpp, alarm2.cpp, alarm3.cpp, profile3.cpp, and speed4.cpp.

u32 SFBAlarm::currentAlarmNumber | ( |  | ) | `[inline]`

Find out what alarm number is currently active.

This method should be called only during a callback to an alarm handler; its return value is not defined elsewhere.

Returns:
  The alarm number that triggered the current alarm handler callback, or an unspecified value if no alarm handler is currently running.

Examples:
  alarm2.cpp, profile3.cpp, and speed4.cpp.

u32 SFBAlarm::get | ( | u32 | alarmNumber | ) |

If alarm alarmNumber is set, access the alarm time.

If alarmNumber is not set, returns the most recent previous alarm time; if alarmNumber has never been set, return 0.

Parameters:

  | alarmNumber | The alarm to access

Returns:
  the current or most-recent alarm setting, or zero

Blinks:
  E_API_BAD_ALARM if alarmNumber is not an alarm number previously returned by create(SFBAlarmHandler) or create(SFBAlarmArgHandler,void*)

Since:
  0.9.5

u32 SFBAlarm::getTopTime | ( |  | ) | `[inline]`

Get the earliest time in the queue.

Only valid when canRemove() returns true.

bool SFBAlarm::inUse | ( | u32 | alarmIndex | ) | `[inline]`

`true` iff alarmIndex is a legal, currently scheduled alarm number.

bool SFBAlarm::set | ( | u32 | alarmNumber,
|  | u32 | when |
| ) |  |  |

Set (or reset) alarm alarmNumber to go off at when.

If when is in the past relative to millis() (in the sense of IS_EARLIER), the alarm will go off at its soonest possible opportunity.

Parameters:

  | alarmNumber | The alarm to set

Returns:
  `true` if the alarm was currently set, `false` if not.

Blinks:
  E_API_BAD_ALARM if alarmNumber is not an alarm number previously returned by create(SFBAlarmHandler) or create(SFBAlarmArgHandler,void*)

Examples:
  alarm1.cpp, alarm2.cpp, alarm3.cpp, profile3.cpp, and speed4.cpp.

void SFBAlarm::update | ( | u32 | alarmNumber,
|  | SFBAlarmArgHandler | handler,
|  | void * | arg |
| ) |  |  |

Alter the handler and/or the extra argument of an existing alarm.

The existing alarm may be set or unset, or even currently running; in all cases the new handler value and/or arg value will take effect the next time the alarm is triggered. See also update(u32,SFBAlarmHandler).

Parameters:

  | alarmNumber | The number of an existing alarm, whose handler should be changed.
  | handler | Non-null pointer to the alarm handler function (the two-argument SFBAlarmArgHandler kind) that should become the handler for alarmNumber
  | arg | an arbitrary pointer value to associate with alarmNumber, which will be provided to handler whenever alarm alarmNumber is triggered

Blinks:
  E_API_BAD_ALARM if alarmNumber is not the number of an existing alarm.

Blinks:
  E_API_NULL_HANDLER if handler is null

void SFBAlarm::update | ( | u32 | alarmNumber,
|  | SFBAlarmHandler | handler |
| ) |  |  | `[inline]`

Alter the handler of an existing alarm.

The existing alarm may be set or unset, or even currently running; in all cases the new handler value will take effect the next time the alarm is triggered. See also update(u32,SFBAlarmArgHandler,void *).

Parameters:

  | alarmNumber | The number of an existing alarm, whose handler should be changed.
  | handler | Non-null pointer to the alarm handler function (the one-argument SFBAlarmHandler kind) that should become the handler for alarmNumber

Blinks:
  E_API_BAD_ALARM if alarmNumber is not the number of an existing alarm.

Blinks:
  E_API_NULL_HANDLER if handler is null

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

- src/include/SFBAlarm.h
- src/components/library/SFBAlarm.cpp