From 0cb83f4142e2ae5e7722f31a5f52c9dc03d2186f Mon Sep 17 00:00:00 2001 From: Ivan Seidel Date: Sat, 11 May 2013 01:02:11 -0300 Subject: [PATCH] Initial commit Basic class creations: Thread and ThreadController --- Thread.cpp | 58 +++++++++ Thread.h | 55 +++++++++ ThreadController.cpp | 110 ++++++++++++++++++ ThreadController.h | 51 ++++++++ .../ControllerInController.ino | 78 +++++++++++++ examples/SimpleThread/SimpleThread.ino | 35 ++++++ .../SimpleThreadController.ino | 48 ++++++++ 7 files changed, 435 insertions(+) create mode 100644 Thread.cpp create mode 100644 Thread.h create mode 100644 ThreadController.cpp create mode 100644 ThreadController.h create mode 100644 examples/ControllerInController/ControllerInController.ino create mode 100644 examples/SimpleThread/SimpleThread.ino create mode 100644 examples/SimpleThreadController/SimpleThreadController.ino diff --git a/Thread.cpp b/Thread.cpp new file mode 100644 index 0000000..4161e42 --- /dev/null +++ b/Thread.cpp @@ -0,0 +1,58 @@ +#include "Thread.h" + +Thread::Thread(void (*callback)(void), long _interval){ + enabled = true; + onRun(callback); + _cached_next_run = 0; + last_run = 0; + + ThreadID = (int)this; + ThreadName = "Thread "; + ThreadName = ThreadName + ThreadID; + + setInterval(_interval); +}; + +void Thread::runned(long time){ + // If less than 0, than get current ticks + if(time < 0) + time = millis(); + + // Saves last_run + last_run = time; + + // Cache next run + _cached_next_run = last_run + interval; +} + +Thread Thread::setInterval(long _interval){ + // Filter intervals less than 0 + interval = (_interval < 0? 0: _interval); + + // Cache the next run based on the last_run + _cached_next_run = last_run + interval; + + // Return self object + return *this; +} + +bool Thread::shouldRun(long time){ + // If less than 0, than get current ticks + if(time < 0) + time = millis(); + + // Exceeded the time limit, AND is enabled? Then should run... + return ((time >= _cached_next_run) && enabled); +} + +void Thread::onRun(void (*callback)(void)){ + _onRun = callback; +} + +void Thread::run(){ + if(_onRun != NULL) + _onRun(); + + // Update last_run and _cached_next_run + runned(); +} \ No newline at end of file diff --git a/Thread.h b/Thread.h new file mode 100644 index 0000000..07688ed --- /dev/null +++ b/Thread.h @@ -0,0 +1,55 @@ +/* + Thread.h - An runnable object + + Contains information about the running Thread, such as: + Delay between calls, + If it should be runned, + + ThreadController is an extended class of Thread, since you can include + + Created by Ivan Seidel Gomes, March, 2013. + Released into the public domain. +*/ + +#ifndef Thread_h +#define Thread_h + +#include +#include +#define MAX_THREADS 15; + +class Thread{ +protected: + long interval, // Desired interval between runs + last_run, // Last runned time in Ms + _cached_next_run; // Scheduled run in Ms (MUST BE CACHED) + + void runned(long time=-1); // 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 + + void (*_onRun)(void); // Callback for run() if not implemented + +public: + bool enabled; // If the current Thread is enabled or not + + int ThreadID; // ID of the Thread (initialized from memory adr.) + String ThreadName; // Thread Name (used for better UI). + + Thread(void (*callback)(void) = NULL, long _interval = 0); + + // Set the desired interval for calls, and update _cached_next_run + Thread setInterval(long _interval); + + // Return if the Thread should be runned or not + virtual bool shouldRun(long time = -1); + + // Callback set + void onRun(void (*callback)(void)); + + // Runs Thread + virtual void run(); +}; + +#endif \ No newline at end of file diff --git a/ThreadController.cpp b/ThreadController.cpp new file mode 100644 index 0000000..a1fe3a4 --- /dev/null +++ b/ThreadController.cpp @@ -0,0 +1,110 @@ +#include "Thread.h" +#include "ThreadController.h" + +ThreadController::ThreadController(long _interval){ + cached_size = 0; + + clear(); + Thread::Thread(); + setInterval(_interval); + + // Overrides name + ThreadName = "ThreadController "; + ThreadName = ThreadName + ThreadID; +} + +/* + ThreadController run() (cool stuf) +*/ +void ThreadController::run(){ + long time = millis(); + int checks = 0; + for(int i = 0; i < MAX_THREADS && checks <= cached_size; i++){ + // Object exists? Is enabled? Timeout exceeded? + if(thread[i]){ + checks++; + if(thread[i]->shouldRun(time)){ + thread[i]->run(); + } + } + } + + // ThreadController extends Thread, so we should flag as runned thread + runned(); +} + + +/* + List controller (boring part) +*/ +bool ThreadController::add(Thread* _thread){ + // Check if the Thread already exists on the array + for(int i = 0; i < MAX_THREADS; i++){ + if(thread[i] != NULL && thread[i]->ThreadID == _thread->ThreadID) + return true; + } + + // Find an empty slot + for(int i = 0; i < MAX_THREADS; i++){ + if(!thread[i]){ + // Found a empty slot, now add Thread + thread[i] = _thread; + cached_size++; + return true; + } + } + + // Array is full + return false; +} + +void ThreadController::remove(int id){ + // Find Threads with the id, and removes + bool found = false; + for(int i = 0; i < MAX_THREADS; i++){ + if(thread[i]->ThreadID == id){ + thread[i] = NULL; + cached_size--; + return; + } + } +} + +void ThreadController::remove(Thread* _thread){ + remove(_thread->ThreadID); +} + +void ThreadController::clear(){ + for(int i = 0; i < MAX_THREADS; i++){ + thread[i] = NULL; + } + cached_size = 0; +} + +int ThreadController::size(bool cached){ + if(cached) + return cached_size; + + int size = 0; + for(int i = 0; i < MAX_THREADS; i++){ + if(thread[i]) + size++; + } + cached_size = size; + + return cached_size; +} + +Thread* ThreadController::get(int index){ + int pos = -1; + for(int i = 0; i < MAX_THREADS; i++){ + if(thread[i] != NULL){ + pos++; + + if(pos == index) + return thread[i]; + } + } + + return NULL; +} \ No newline at end of file diff --git a/ThreadController.h b/ThreadController.h new file mode 100644 index 0000000..d5f6f92 --- /dev/null +++ b/ThreadController.h @@ -0,0 +1,51 @@ +/* + ThreadController.h - Controlls a list of Threads with different timings + + Basicaly, what it does is to keep track of current Threads and run when + necessary. + + ThreadController is an extended class of Thread, since you can include + + + Created by Ivan Seidel Gomes, March, 2013. + Released into the public domain. +*/ + +#ifndef ThreadController_h +#define ThreadController_h + +#include "Thread.h" +#include "inttypes.h" + +#define MAX_THREADS 15 + +class ThreadController: public Thread{ +protected: + Thread* thread[MAX_THREADS]; + int cached_size; +public: + ThreadController(long _interval = 0); + + // run() Method is overrided + void run(); + + // Adds a thread in the first available slot (remove first) + // Returns if the Thread could be added or not + bool add(Thread* _thread); + + // remove the thread (given the Thread* or ThreadID) + void remove(int _id); + void remove(Thread* _thread); + + // Removes all threads + void clear(); + + // Return the quantity of Threads + int size(bool cached = true); + + // Return the I Thread on the array + // Returns NULL if none found + Thread* get(int index); +}; + +#endif \ No newline at end of file diff --git a/examples/ControllerInController/ControllerInController.ino b/examples/ControllerInController/ControllerInController.ino new file mode 100644 index 0000000..feb8a0a --- /dev/null +++ b/examples/ControllerInController/ControllerInController.ino @@ -0,0 +1,78 @@ +#include +#include + +int ledPin = 13; + +// ThreadController that will controll all threads +ThreadController controll = ThreadController(); + +//My Thread +Thread myThread = Thread(); +//His Thread +Thread hisThread = Thread(); +//Blink Led Thread +Thread blinkLedThread = Thread(); +//ThreadController, that will be added to controll +ThreadController groupOfThreads = ThreadController(); + +// callback for myThread +void niceCallback(){ + Serial.print("COOL! I'm running on: "); + Serial.println(millis()); +} + +// callback for hisThread +void boringCallback(){ + Serial.println("BORING..."); +} + +// callback for blinkLedThread +void blinkLed(){ + static bool ledStatus = false; + ledStatus = !ledStatus; + + digitalWrite(ledPin, ledStatus); + + Serial.print("blinking: "); + Serial.println(ledStatus); +} + +void setup(){ + Serial.begin(9600); + + pinMode(ledPin, OUTPUT); + + // Configure myThread + myThread.onRun(niceCallback); + myThread.setInterval(500); + + // Configure hisThread + hisThread.onRun(boringCallback); + hisThread.setInterval(250); + + // Configure blinkLedThread + blinkLedThread.onRun(blinkLed); + blinkLedThread.setInterval(100); + + // Adds myThread to the controll + controll.add(&myThread); + + // Adds hisThread and blinkLedThread to groupOfThreads + groupOfThreads.add(&hisThread); + groupOfThreads.add(&blinkLedThread); + + // Add groupOfThreads to controll + controll.add(&groupOfThreads); + +} + +void loop(){ + // run ThreadController + // this will check every thread inside ThreadController, + // if it should run. If yes, he will run it; + controll.run(); + + // Rest of code + float h = 3.1415; + h/=2; +} \ No newline at end of file diff --git a/examples/SimpleThread/SimpleThread.ino b/examples/SimpleThread/SimpleThread.ino new file mode 100644 index 0000000..e45362a --- /dev/null +++ b/examples/SimpleThread/SimpleThread.ino @@ -0,0 +1,35 @@ +#include +int ledPin = 13; + +//My simple Thread +Thread myThread = Thread(); + +// callback for myThread +void niceCallback(){ + static bool ledStatus = false; + ledStatus = !ledStatus; + + digitalWrite(ledPin, ledStatus); + + Serial.print("COOL! I'm running on: "); + Serial.println(millis()); +} + +void setup(){ + Serial.begin(9600); + + pinMode(ledPin, OUTPUT); + + myThread.onRun(niceCallback); + myThread.setInterval(500); +} + +void loop(){ + // checks if thread should run + if(myThread.shouldRun()) + myThread.run(); + + // Other code... + int x = 0; + x = 1 + 2; +} \ No newline at end of file diff --git a/examples/SimpleThreadController/SimpleThreadController.ino b/examples/SimpleThreadController/SimpleThreadController.ino new file mode 100644 index 0000000..949290b --- /dev/null +++ b/examples/SimpleThreadController/SimpleThreadController.ino @@ -0,0 +1,48 @@ +#include +#include + +// ThreadController that will controll all threads +ThreadController controll = ThreadController(); + +//My Thread (as a pointer) +Thread* myThread = new Thread(); +//His Thread (not pointer) +Thread hisThread = Thread(); + +// callback for myThread +void niceCallback(){ + Serial.print("COOL! I'm running on: "); + Serial.println(millis()); +} + +// callback for hisThread +void boringCallback(){ + Serial.println("BORING..."); +} + +void setup(){ + Serial.begin(9600); + + // Configure myThread + myThread->onRun(niceCallback); + myThread->setInterval(500); + + // Configure myThread + hisThread.onRun(boringCallback); + hisThread.setInterval(250); + + // Adds both threads to the controller + controll.add(myThread); + controll.add(&hisThread); // & to pass the pointer to it +} + +void loop(){ + // run ThreadController + // this will check every thread inside ThreadController, + // if it should run. If yes, he will run it; + controll.run(); + + // Rest of code + float h = 3.1415; + h/=2; +} \ No newline at end of file