From 1b5a88516d47116affd0e2d8ba26ede226786539 Mon Sep 17 00:00:00 2001 From: Stanislav Hnatiuk Date: Mon, 23 Apr 2018 13:20:31 +0300 Subject: [PATCH] Add light versions. Light versions of Thread and StaticThreadController that uses less memory. --- StaticThreadControllerLite.h | 52 +++++++++++++++++++++++++++++ ThreadLite.cpp | 42 +++++++++++++++++++++++ ThreadLite.h | 64 ++++++++++++++++++++++++++++++++++++ 3 files changed, 158 insertions(+) create mode 100644 StaticThreadControllerLite.h create mode 100644 ThreadLite.cpp create mode 100644 ThreadLite.h diff --git a/StaticThreadControllerLite.h b/StaticThreadControllerLite.h new file mode 100644 index 0000000..fc454a4 --- /dev/null +++ b/StaticThreadControllerLite.h @@ -0,0 +1,52 @@ +/* + StaticThreadControllerLite.h - Controlls a list of ThreadsLite with different timings + + Basicaly, what it does is to keep track of current ThreadsLite and run when + necessary. + + StaticThreadControllerLite is based on the class StaticThreadController, + but takes less memory and maximum period is only 32,767 seconds. + WARNING! It is not recommended to use if you do not have a memory deficit. + + Copyright © 2016 Alex Eremin. + Copyright © 2018 Stanislav Hnatiuk. + Released into the public domain. +*/ + +#ifndef STATICTHREADCONTROLLERLITE_H +#define STATICTHREADCONTROLLERLITE_H + +#include "ThreadLite.h" + +template +class StaticThreadControllerLite { + protected: + ThreadLite thread[N]; + public: + template + StaticThreadControllerLite(T... params) : thread{params...} { }; + + // Runs all ThreadLite + void run() { + for (uint8_t i = 0; i < N; i++) { + // Is enabled? Timeout exceeded? + if (thread[i].shouldRun()) { + thread[i].run(); + } + } + } + + // Return the quantity of ThreadsLite + static constexpr int size() { + return N; + }; + + // Return the I ThreadLite on the array + // Doesn't perform any bounds checks and behaviour is + // unpredictable in case of index > N + ThreadLite& operator[](uint8_t index) { + return thread[index]; + } +}; + +#endif // STATICTHREADCONTROLLERLITE_H diff --git a/ThreadLite.cpp b/ThreadLite.cpp new file mode 100644 index 0000000..61a2a7d --- /dev/null +++ b/ThreadLite.cpp @@ -0,0 +1,42 @@ +// Copyright © 2013 Ivan Seidel Gomes. +// Copyright © 2018 Stanislav Hnatiuk. + +#include "ThreadLite.h" + +ThreadLite::ThreadLite(void (*callback)(void), TIME_INT _interval) { + _onRun = callback; + _cached_next_run = 0; + last_run = 0; + setInterval(_interval); +}; + +void ThreadLite::runned() { + // Saves last_run + last_run = millis(); + + // Cache next run + _cached_next_run = last_run + interval; +} + +void ThreadLite::setInterval(TIME_INT _interval) { + // Save interval + interval = _interval; + + // Cache the next run based on the last_run + _cached_next_run = last_run + interval; +} + +bool ThreadLite::shouldRun() { + TIME_INT time = millis(); + // If the "sign" bit is set the signed difference would be negative + bool time_remaining = (time - _cached_next_run) & TIME_OVERFLOW; + + // Exceeded the time limit, AND is enabled? Then should run... + return !time_remaining; +} + +void ThreadLite::run() { + _onRun(); + // Update last_run and _cached_next_run + runned(); +} diff --git a/ThreadLite.h b/ThreadLite.h new file mode 100644 index 0000000..b970913 --- /dev/null +++ b/ThreadLite.h @@ -0,0 +1,64 @@ +/* + ThreadLite.h - An runnable object + + Thread is responsable for holding the "action" for something, + also, it responds if it "should" or "should not" run, based on + the current time; + + ThreadLite is based on the class Thread, but takes less memory + and maximum period is only 32,767 seconds. + WARNING! It is not recommended to use if you do not have a memory deficit. + + Copyright © 2013 Ivan Seidel Gomes. + Copyright © 2018 Stanislav Hnatiuk. + Released into the public domain. +*/ + +#ifndef THREADLITE_H +#define THREADLITE_H + +#if defined(ARDUINO) && ARDUINO >= 100 +#include +#endif + +#define TIME_INT uint16_t +#define TIME_OVERFLOW 0x8000 // uint16_t = 0x8000 or uint32_t = 0x80000000 + +class ThreadLite { + protected: + // Desired interval between runs + TIME_INT interval; + + // Last runned time in Ms + TIME_INT last_run; + + // Scheduled run in Ms (MUST BE CACHED) + TIME_INT _cached_next_run; + + /* + IMPORTANT! Run after all calls to run() + Updates last_run and cache next run. + NOTE: This MUST be called if extending + this class and implementing run() method + */ + + // Default is to mark it runned "now" + void runned(); + + // Callback for run() if not implemented + void (*_onRun)(void); + + public: + ThreadLite(void (*callback)(void), TIME_INT _interval); + + // Set the desired interval for calls, and update _cached_next_run + void setInterval(TIME_INT _interval); + + // Default is to check whether it should run "now" + bool shouldRun(); + + // Runs ThreadLite + void run(); +}; + +#endif // THREADLITE_H