Skip to content

Commit 006a5aa

Browse files
authored
Merge pull request #13 from CAHEK7/StaticThreadController
Static thread controller
2 parents fcd0b64 + 7854b3a commit 006a5aa

File tree

4 files changed

+161
-5
lines changed

4 files changed

+161
-5
lines changed

README.md

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,18 @@ It should be noted that these are not “threads” in the real computer-science
3232
There are many examples showing many ways to use it. Here, we will explain Class itself,
3333
what it does and "how" it does.
3434

35-
There are basicaly, two Classes included in this Library:
36-
`Thread` and `ThreadController` (that inherits from Thread).
35+
There are basicaly, three Classes included in this Library:
36+
`Thread`, `ThreadController` and `StaticThreadController` (both controllers inherit from Thread).
3737

3838
- `Thread class`: This is the basic class, witch contains methods to set and run callbacks,
3939
check if the Thread should be runned, and also creates a unique ThreadID on the instantiation.
4040

4141
- `ThreadController class`: Responsable for "holding" multiple Threads. Can also be called
4242
as "a group of Threads", and is used to perform run in every Thread ONLY when needed.
4343

44+
- `StaticThreadController class`: Slighly faster and smaller version of `ThreadController`.
45+
It works similar to `ThreadController`, but once constructed it can't add or remove threads to run.
46+
4447
* The instantiation of a Thread class is very simple:
4548

4649
```c++
@@ -79,7 +82,8 @@ if(myThread.shouldRun()){
7982

8083
Now that you got the idea, let's think a little bit: What if i have 3, 5, 100 Threads. Do I need to check EACH one?!?
8184

82-
* The answer is: NO. Create a `ThreadController`, and put all your boring-complex Threads inside it!
85+
* The answer is: NO. Create a `ThreadController` or `StaticThreadController`,
86+
and put all your boring-complex Threads inside it!
8387

8488
```c++
8589
// Instantiate a new ThreadController
@@ -90,11 +94,18 @@ controller.add(&hisThread);
9094
controller.add(&sensorReadings);
9195
...
9296
```
97+
or
98+
```c++
99+
// Instantiate a new StaticThreadController with the number of threads to be supplied as template parameter
100+
StaticThreadController<3> controller (&myThread, &hisThread, &sensorReadings);
101+
// You don't need to do anything else, controller now contains all the threads.
102+
...
103+
```
93104
94105
* You have created, configured, grouped it. What is missing? Yes, whe should RUN it!
95106
96107
```c++
97-
// call run on a Thread or a ThreadController to run it
108+
// call run on a Thread, a ThreadController or a StaticThreadController to run it
98109
controller.run();
99110
```
100111

@@ -126,6 +137,12 @@ or disable a GROUP of Threads, think about putting all of them inside a ThreadCo
126137
and adding this ThreadController to another ThreadController (YES! One ThreadController
127138
inside another). Check `ControllerInController` example.
128139

140+
* There is a `StaticThreadController` which is better to use when you know exact number of
141+
threads to run. You cannot add or remove threads in runtime, but `StaticThreadController`
142+
doesn't have additional memory overhead to keep all the treads together, doesn't have any
143+
limitations how many threads to store (except of available memory) and also the code may be slighly
144+
more optimized because all the threads always exist and no need to do any runtime checks.
145+
129146
* Check the full example `CustomTimedThread` for a cool application of Threads that runs
130147
for a period, after a button is pressed.
131148

@@ -177,5 +194,12 @@ interrupts(); // This will enable the interrupts egain. DO NOT FORGET!
177194
inside the ThreadController. If cached is `false`, will force the calculation of threads.
178195
- `Thread* ThreadController::get(int index)` - Returns the Thread on the position `index`.
179196

197+
198+
- `void StaticThreadController::run()` - This will run the all `Threads` within the `StaicThreadController`,
199+
only if needed (if shouldRun returns true);
200+
- `int StaticThreadController::size()` - Returns how many Threads are allocated inside the StaticThreadController.
201+
- `Thread* ThreadController::get(int index)` - Returns the Thread on the position `index` and `nullptr` if `index`
202+
is out of bounds.
203+
180204
### You don't need to know:
181205
- Nothing, yet ;)

StaticThreadController.h

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
StaticThreadController.h - Controlls a list of Threads with different timings
3+
4+
Basicaly, what it does is to keep track of current Threads and run when
5+
necessary.
6+
7+
StaticThreadController is an extended class of Thread, because of that,
8+
it allows you to add a StaticThreadController inside another kind of ThreadController...
9+
10+
It works exact as ThreadController except you can't add or remove treads dynamically.
11+
12+
Created by Alex Eremin, September, 2016.
13+
Released into the public domain.
14+
*/
15+
16+
#ifndef StaticThreadController_h
17+
#define StaticThreadController_h
18+
19+
#include "Thread.h"
20+
21+
template <int N>
22+
class StaticThreadController: public Thread{
23+
protected:
24+
//since this is a static controller, the pointers themselves can be const
25+
//it should be distinguished from 'const Thread* thread[N]'
26+
Thread * const thread[N];
27+
public:
28+
template <typename... T>
29+
StaticThreadController(T... params) :
30+
Thread(),
31+
thread{params...}
32+
{
33+
#ifdef USE_THREAD_NAMES
34+
// Overrides name
35+
ThreadName = "StaticThreadController ";
36+
ThreadName = ThreadName + ThreadID;
37+
#endif
38+
};
39+
40+
// run() Method is overrided
41+
void run() override
42+
{
43+
// Run this thread before
44+
if(_onRun != nullptr && shouldRun())
45+
_onRun();
46+
47+
for(int i = 0; i < N; i++){
48+
// Is enabled? Timeout exceeded?
49+
if(thread[i]->shouldRun()){
50+
thread[i]->run();
51+
}
52+
}
53+
54+
// StaticThreadController extends Thread, so we should flag as runned thread
55+
runned();
56+
}
57+
58+
// Return the quantity of Threads
59+
static constexpr int size() { return N; };
60+
61+
// Return the I Thread on the array
62+
// Returns nullptr if index is out of bounds
63+
Thread* get(int index) {
64+
return (index >= 0 && index < N) ? thread[index] : nullptr;
65+
};
66+
67+
// Return the I Thread on the array
68+
// Doesn't perform any bounds checks and behaviour is
69+
// unpredictable in case of index > N
70+
Thread& operator[](int index) {
71+
return *thread[index];
72+
};
73+
};
74+
75+
#endif
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include <Thread.h>
2+
#include <StaticThreadController.h>
3+
4+
//My Thread (as a pointer)
5+
Thread* myThread = new Thread();
6+
//His Thread (not pointer)
7+
Thread hisThread = Thread();
8+
9+
// callback for myThread
10+
void niceCallback(){
11+
Serial.print("COOL! I'm running on: ");
12+
Serial.println(millis());
13+
}
14+
15+
// callback for hisThread
16+
void boringCallback(){
17+
Serial.println("BORING...");
18+
}
19+
20+
// callback for theThread
21+
void justCallback(){
22+
Serial.println("executing...");
23+
}
24+
25+
//The Thread (as a pointer) with justCallback initialized
26+
Thread* theThread = new Thread(justCallback);
27+
28+
// StaticThreadController that will controll all threads
29+
// All non-pointers go with '&', but pointers go without '&',
30+
StaticThreadController<3> controll (myThread, &hisThread, theThread);
31+
32+
void setup(){
33+
Serial.begin(9600);
34+
35+
// Configure myThread
36+
myThread->onRun(niceCallback);
37+
myThread->setInterval(500);
38+
39+
// Configure hisThread
40+
hisThread.onRun(boringCallback);
41+
hisThread.setInterval(250);
42+
43+
// Set interval for theThread using StaticThreadController interface
44+
controll[3].setInterval(375);
45+
}
46+
47+
void loop(){
48+
// run StaticThreadController
49+
// this will check every thread inside ThreadController,
50+
// if it should run. If yes, he will run it;
51+
controll.run();
52+
53+
// Rest of code
54+
float h = 3.1415;
55+
h/=2;
56+
}

keywords.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
Thread KEYWORD1
1010
ThreadController KEYWORD1
11+
StaticThreadController KEYWORD1
1112

1213
#######################################
1314
# Methods and Functions (KEYWORD2)
@@ -19,7 +20,7 @@ shouldRun KEYWORD2
1920
onRun KEYWORD2
2021
run KEYWORD2
2122

22-
# Specific of ThreadController
23+
# Specific of ThreadController or StaticThreadController
2324
add KEYWORD2
2425
remove KEYWORD2
2526
clear KEYWORD2

0 commit comments

Comments
 (0)