Skip to content

Commit

Permalink
Function name is changed from tick() to left(), optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
sixtelgreg committed Jan 29, 2022
1 parent 6e6f9bd commit fcefadf
Showing 1 changed file with 44 additions and 63 deletions.
107 changes: 44 additions & 63 deletions src/arduino-timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
#include <limits.h>

#ifndef TIMER_MAX_TASKS
#define TIMER_MAX_TASKS 0x10
#define TIMER_MAX_TASKS 0x10
#endif

#define _timer_foreach_task(T, task) \
Expand All @@ -57,42 +57,37 @@
_timer_foreach_task(const struct task *, T)

template <
size_t max_tasks = TIMER_MAX_TASKS, /* max allocated tasks */
size_t max_tasks = TIMER_MAX_TASKS, /* max allocated tasks */
unsigned long (*time_func)() = millis, /* time function for timer */
typename T = void * /* handler argument type */
>
typename T = void * /* handler argument type */
>
class Timer {
public:

typedef uintptr_t Task; /* public task handle */
public:
typedef uintptr_t Task; /* public task handle */
typedef bool (*handler_t)(T opaque); /* task handler func signature */

/* Calls handler with opaque as argument in delay units of time */
Task
in(unsigned long delay, handler_t h, T opaque = T())
{
in(unsigned long delay, handler_t h, T opaque = T()) {
return task_id(add_task(time_func(), delay, h, opaque));
}

/* Calls handler with opaque as argument at time */
Task
at(unsigned long time, handler_t h, T opaque = T())
{
at(unsigned long time, handler_t h, T opaque = T()) {
const unsigned long now = time_func();
return task_id(add_task(now, time - now, h, opaque));
}

/* Calls handler with opaque as argument every interval units of time */
Task
every(unsigned long interval, handler_t h, T opaque = T())
{
every(unsigned long interval, handler_t h, T opaque = T()) {
return task_id(add_task(time_func(), interval, h, opaque, interval));
}

/* Cancel the timer task */
void
cancel(Task &task)
{
cancel(Task &task) {
if (!task) return;

timer_foreach_task(t) {
Expand All @@ -107,17 +102,15 @@ class Timer {

/* Cancel all timer tasks */
void
cancel()
{
cancel() {
timer_foreach_task(t) {
remove(t);
}
}

/* Left until the task ends */
unsigned long
ticks(const Task &task)
{
left(const Task &task) {
auto lft = 0ul;
if (!task)
return lft;
Expand All @@ -127,10 +120,8 @@ class Timer {
const unsigned long now = time_func();
const unsigned long duration = now - t->start;

if (duration >= t->expires)
break;

lft = t->expires - duration;
if (duration < t->expires)
lft = t->expires - duration;
break;
}
}
Expand All @@ -140,15 +131,14 @@ class Timer {

/* Ticks the timer forward - call this function in loop() */
unsigned long
tick()
{
tick() {
tick<void>();
return ticks();
}

template <typename R> void
tick()
{
template <typename R>
void
tick() {
timer_foreach_task(task) {
if (task->handler) {
const unsigned long t = time_func();
Expand All @@ -157,17 +147,18 @@ class Timer {
if (duration >= task->expires) {
task->repeat = task->handler(task->opaque) && task->repeat;

if (task->repeat) task->start = t;
else remove(task);
if (task->repeat)
task->start = t;
else
remove(task);
}
}
}
}

/* Ticks until the next event */
unsigned long
ticks() const
{
ticks() const {
unsigned long ticks = ULONG_MAX, elapsed;
const unsigned long start = time_func();

Expand All @@ -188,16 +179,17 @@ class Timer {

elapsed = time_func() - start;

if (elapsed >= ticks || ticks == ULONG_MAX) ticks = 0;
else ticks -= elapsed;
if (elapsed >= ticks || ticks == ULONG_MAX)
ticks = 0;
else
ticks -= elapsed;

return ticks;
}

/* Number of active tasks in the timer */
size_t
size() const
{
size() const {
size_t s = 0;

timer_foreach_const_task(task) {
Expand All @@ -209,8 +201,7 @@ class Timer {

/* True if there are no active tasks */
bool
empty() const
{
empty() const {
timer_foreach_const_task(task) {
if (task->handler) return false;
}
Expand All @@ -220,23 +211,20 @@ class Timer {

Timer() : ctr(0), tasks{} {}

private:

private:
size_t ctr;

struct task {
handler_t handler; /* task handler callback func */
T opaque; /* argument given to the callback handler */
T opaque; /* argument given to the callback handler */
unsigned long start,
expires; /* when the task expires */
expires; /* when the task expires */
size_t repeat, /* repeat task */
id;
id;
} tasks[max_tasks];

inline
void
remove(struct task *task)
{
inline void
remove(struct task *task) {
task->handler = NULL;
task->opaque = T();
task->start = 0;
Expand All @@ -245,36 +233,30 @@ class Timer {
task->id = 0;
}

inline
Task
task_id(const struct task * const t)
{
inline Task
task_id(const struct task *const t) {
const Task id = reinterpret_cast<Task>(t);

return id ? id ^ t->id : id;
}

inline
struct task *
next_task_slot()
{
inline struct task *
next_task_slot() {
timer_foreach_task(slot) {
if (slot->handler == NULL) return slot;
}

return NULL;
}

inline
struct task *
inline struct task *
add_task(unsigned long start, unsigned long expires,
handler_t h, T opaque, bool repeat = 0)
{
struct task * const slot = next_task_slot();
handler_t h, T opaque, bool repeat = 0) {
struct task *const slot = next_task_slot();

if (!slot) return NULL;

if (++ctr == 0) ++ctr; // overflow
if (++ctr == 0) ++ctr; // overflow

slot->id = ctr;
slot->handler = h;
Expand All @@ -289,8 +271,7 @@ class Timer {

/* create a timer with the default settings */
inline Timer<>
timer_create_default()
{
timer_create_default() {
return Timer<>();
}

Expand Down

0 comments on commit fcefadf

Please sign in to comment.