Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions Thread.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#include "Thread.h"

Thread::Thread(void (*callback)(void), unsigned long _interval){
enabled = true;
onRun(callback);
_cached_next_run = 0;
last_run = millis();

ThreadID = (int)this;
#ifdef USE_THREAD_NAMES
ThreadName = "Thread ";
ThreadName = ThreadName + ThreadID;
#endif

setInterval(_interval);
};

void Thread::runned(unsigned long time){
// Saves last_run
last_run = time;

// Cache next run
_cached_next_run = last_run + interval;
}

void Thread::setInterval(unsigned long _interval){
// Save interval
interval = _interval;

// Cache the next run based on the last_run
_cached_next_run = last_run + interval;
}

bool Thread::shouldRun(unsigned long time){
// If the "sign" bit is set the signed difference would be negative
bool time_remaining = (time - _cached_next_run) & 0x80000000;

// Exceeded the time limit, AND is enabled? Then should run...
return !time_remaining && enabled;
}

void Thread::onRun(void (*callback)(void)){
_onRun = callback;
}

void Thread::run(){
if(_onRun != NULL)
_onRun();

// Update last_run and _cached_next_run
runned();
}
89 changes: 89 additions & 0 deletions Thread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
Thread.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;

For instructions, go to https://github.com/ivanseidel/ArduinoThread

Created by Ivan Seidel Gomes, March, 2013.
Released into the public domain.
*/

#ifndef Thread_h
#define Thread_h

#if defined(ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#endif

#include <inttypes.h>

/*
Uncomment this line to enable ThreadName Strings.

It might be usefull if you are loging thread with Serial,
or displaying a list of threads...
*/
// #define USE_THREAD_NAMES 1

class Thread{
protected:
// Desired interval between runs
unsigned long interval;

// Last runned time in Ms
unsigned long last_run;

// Scheduled run in Ms (MUST BE CACHED)
unsigned long _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
*/
void runned(unsigned long time);

// Default is to mark it runned "now"
void runned() { runned(millis()); }

// Callback for run() if not implemented
void (*_onRun)(void);

public:

// If the current Thread is enabled or not
bool enabled;

// ID of the Thread (initialized from memory adr.)
int ThreadID;

#ifdef USE_THREAD_NAMES
// Thread Name (used for better UI).
String ThreadName;
#endif

Thread(void (*callback)(void) = NULL, unsigned long _interval = 0);

// Set the desired interval for calls, and update _cached_next_run
virtual void setInterval(unsigned long _interval);

// Return if the Thread should be runned or not
virtual bool shouldRun(unsigned long time);

// Default is to check whether it should run "now"
bool shouldRun() { return shouldRun(millis()); }

// Callback set
void onRun(void (*callback)(void));

// Runs Thread
virtual void run();
};

#endif
115 changes: 115 additions & 0 deletions ThreadController.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#include "Thread.h"
#include "ThreadController.h"

ThreadController::ThreadController(unsigned long _interval): Thread(){
cached_size = 0;

clear();
setInterval(_interval);

#ifdef USE_THREAD_NAMES
// Overrides name
ThreadName = "ThreadController ";
ThreadName = ThreadName + ThreadID;
#endif
}

/*
ThreadController run() (cool stuf)
*/
void ThreadController::run(){
// Run this thread before
if(_onRun != NULL)
_onRun();

unsigned 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;
}
53 changes: 53 additions & 0 deletions ThreadController.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
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, because of that,
it allows you to add a ThreadController inside another ThreadController...

For instructions, go to https://github.com/ivanseidel/ArduinoThread

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(unsigned 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