Skip to content

Commit 999a517

Browse files
committed
upd
1 parent 6104202 commit 999a517

File tree

7 files changed

+74
-42
lines changed

7 files changed

+74
-42
lines changed

docs/0.main.md

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,10 @@ LP_TICKER_(id, func)
3939
// создать статический таймер
4040
LP_TIMER(ms, func)
4141
LP_TIMER_(id, ms, func)
42+
```
4243
44+
### Макросы потоков
45+
```cpp
4346
// создать статический поток
4447
LP_THREAD(body)
4548
LP_THREAD_(id, body)
@@ -57,7 +60,10 @@ LP_WAIT_EVENT(cond)
5760
LP_WAIT(cond)
5861
5962
// асинхронно ждать время в мс в потоке
60-
LP_SLEEP(ms)
63+
LP_DELAY(ms)
64+
65+
// выйти из потока и потом вернуться в эту точку
66+
LP_EXIT()
6167
6268
// освободить семафор
6369
LP_SEM_SIGNAL(sem)
@@ -89,8 +95,8 @@ void delay(uint32_t ms);
8995
// добавить задачу
9096
void add(LoopTask* task);
9197

92-
// убрать задачу
93-
void remove(LoopTask* task);
98+
// убрать задачу и вызвать обработчик выхода (опционально)
99+
void remove(LoopTask* task, bool callExit = true);
94100

95101
// получить указатель на задачу по id
96102
LoopTask* getTask(hash_t id);
@@ -116,8 +122,8 @@ LoopTimer* thisTimer();
116122
template <typename T>
117123
T* thisTaskAs();
118124

119-
// убрать текущую задачу из loop
120-
void removeThis();
125+
// убрать текущую задачу из loop и вызвать обработчик выхода (опционально)
126+
void removeThis(bool callExit = true);
121127

122128
// статус текущей задачи
123129
tState thisState();

docs/2.threads.md

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,26 @@ LP_THREAD_("thread_id", {
2525

2626
> Внутри обработчика точно так же можно обращаться к задаче через `thisTask` и делать всё то же самое, что с `LoopTicker` (остановить, исключить из loop, отправить-поймать событие и так далее).
2727
28+
Для управления потоком используются специальные макросы.
29+
30+
### Выход из потока
31+
В любой момент можно покинуть поток и отдать выполнение другим потокам, на следующем круге диспетчера задач управление вернётся к потоку и продолжится после точки выхода. Полезно например если нужно "размазать" какие то долгие сложные вычисления по времени и выполнять в промежутках другие потоки:
32+
33+
```cpp
34+
LP_THREAD({
35+
Serial.println("test 1");
36+
LP_EXIT();
37+
Serial.println("test 2");
38+
LP_EXIT();
39+
});
40+
```
41+
2842
### Ожидание времени
2943
Поток может асинхронно ждать указанное время, это ожидание **не блокирует выполнение программы**:
3044
3145
```cpp
3246
LP_THREAD({
33-
LP_SLEEP(500);
47+
LP_DELAY(500);
3448
Serial.println("test!");
3549
});
3650
```
@@ -40,9 +54,9 @@ LP_THREAD({
4054
```cpp
4155
LP_THREAD({
4256
digitalWrite(LED_BUILTIN, 1);
43-
LP_SLEEP(500);
57+
LP_DELAY(500);
4458
digitalWrite(LED_BUILTIN, 0);
45-
LP_SLEEP(500);
59+
LP_DELAY(500);
4660
});
4761
```
4862
@@ -54,9 +68,9 @@ LP_THREAD({
5468
5569
while (true) {
5670
digitalWrite(LED_BUILTIN, 1);
57-
LP_SLEEP(500);
71+
LP_DELAY(500);
5872
digitalWrite(LED_BUILTIN, 0);
59-
LP_SLEEP(500);
73+
LP_DELAY(500);
6074
}
6175
});
6276
```
@@ -89,7 +103,7 @@ LP_THREAD_("thread", {
89103
90104
// отправляем событие по таймеру
91105
LP_THREAD({
92-
LP_SLEEP(2000);
106+
LP_DELAY(2000);
93107
Looper.pushEvent("thread");
94108
});
95109
@@ -110,7 +124,7 @@ LP_TIMER(1000, []() {
110124
LP_THREAD({
111125
for (int i = 0; i < 10; i++) {
112126
Serial.println(i);
113-
LP_SLEEP(500);
127+
LP_DELAY(500);
114128
// тут мы выйдем из функции и потеряем значение i
115129
}
116130
});
@@ -124,7 +138,7 @@ LP_THREAD({
124138
125139
for (i = 0; i < 10; i++) {
126140
Serial.println(i);
127-
LP_SLEEP(500);
141+
LP_DELAY(500);
128142
}
129143
});
130144
```
@@ -150,7 +164,7 @@ LP_THREAD({
150164
// тут мы забираем семафор себе, другие потоки будут заблокированы
151165

152166
// имитация бурной деятельности
153-
LP_SLEEP(500);
167+
LP_DELAY(500);
154168
val = random(100);
155169

156170
LP_SEM_SIGNAL(sem); // освобождаем семафор
@@ -165,7 +179,7 @@ LP_THREAD({
165179
LoopThreadData<int> thread_data(new int(3), [](int* data) {
166180
LP_THREAD_BEGIN();
167181
168-
LP_SLEEP(500);
182+
LP_DELAY(500);
169183
Serial.println(*data);
170184
*data += 1;
171185
@@ -174,7 +188,7 @@ LoopThreadData<int> thread_data(new int(3), [](int* data) {
174188
175189
// макрос
176190
LP_THREAD_DATA(int, new int(3), int* data, {
177-
LP_SLEEP(500);
191+
LP_DELAY(500);
178192
Serial.println(*data);
179193
*data += 1;
180194
});

examples/threads/threads.ino

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ LP_THREAD({
88

99
while (true) {
1010
digitalWrite(LED_BUILTIN, 1);
11-
LP_SLEEP(500);
11+
LP_DELAY(500);
1212
digitalWrite(LED_BUILTIN, 0);
13-
LP_SLEEP(500);
13+
LP_DELAY(500);
1414
}
1515
});
1616
// === blink
@@ -21,7 +21,7 @@ LP_THREAD({
2121

2222
// for (i = 0; i < 10; i++) {
2323
// Serial.println(i);
24-
// LP_SLEEP(500);
24+
// LP_DELAY(500);
2525
// }
2626
// });
2727
// === цикл
@@ -46,7 +46,7 @@ LP_THREAD({
4646

4747
// LP_THREAD({
4848
// LP_SEM_WAIT(sem);
49-
// LP_SLEEP(500);
49+
// LP_DELAY(500);
5050
// val = random(100);
5151
// LP_SEM_SIGNAL(sem);
5252
// });
@@ -57,30 +57,30 @@ LP_THREAD({
5757
// Serial.println("wait event");
5858
// LP_WAIT_EVENT();
5959
// Serial.println("event!");
60-
// LP_SLEEP(500);
60+
// LP_DELAY(500);
6161
// });
6262

6363
// LP_TIMER(1000, []() {
6464
// Looper.pushEvent("thread");
6565
// });
6666

6767
// LP_THREAD({
68-
// LP_SLEEP(2000);
68+
// LP_DELAY(2000);
6969
// Looper.pushEvent("thread");
7070
// });
7171
// === event
7272

7373
// === data
7474
// LP_THREAD_DATA(int, new int(3), int* data, {
75-
// LP_SLEEP(500);
75+
// LP_DELAY(500);
7676
// Serial.println(*data);
7777
// *data += 1;
7878
// });
7979

8080
// LoopThreadData<int> thread_manual(new int(3), [](int* data) {
8181
// LP_THREAD_BEGIN();
8282

83-
// LP_SLEEP(500);
83+
// LP_DELAY(500);
8484
// Serial.println(*data);
8585
// *data += 1;
8686

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=Looper
2-
version=1.1.1
2+
version=1.1.2
33
author=AlexGyver <[email protected]>
44
maintainer=AlexGyver <[email protected]>
55
sentence=Simple task and event manager for Arduino

src/Looper.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,23 +51,30 @@
5151
#define LP_THREAD_DATA(T, data, data_arg, body) static LoopThreadData<T> _LP_CONCAT(__loop_obj_, __COUNTER__)(data, [](data_arg) { _LP_THREAD_INNER(body) })
5252
#define LP_THREAD_DATA_(id, T, data, data_arg, body) static LoopThreadData<T> _LP_CONCAT(__loop_obj_, __COUNTER__)(LPH(id), data, [](data_arg) { _LP_THREAD_INNER(body) })
5353

54-
// асинхронно ждать условия
55-
#define LP_WAIT(cond) \
54+
// выйти из потока и потом вернуться в эту точку
55+
#define LP_EXIT() \
5656
Looper.thisThread()->_case = __COUNTER__ + 1; \
57-
case __COUNTER__: \
58-
if (!(cond)) return;
57+
case __COUNTER__:
58+
59+
// асинхронно ждать условия
60+
#define LP_WAIT(cond) \
61+
LP_EXIT(); \
62+
if (!(cond)) return;
5963

6064
// асинхронно ждать события
6165
#define LP_WAIT_EVENT(cond) LP_WAIT(Looper.thisEvent());
6266

6367
// асинхронно ждать время в мс
64-
#define LP_SLEEP(ms) \
68+
#define LP_DELAY(ms) \
6569
do { \
6670
Looper.thisThread()->_resetTmr(); \
6771
LP_WAIT(Looper.thisThread()->_elapsed(ms)); \
6872
Looper.thisThread()->_stopTmr(); \
6973
} while (0);
7074

75+
// устарело
76+
#define LP_SLEEP(ms) LP_DELAY(ms)
77+
7178
// освободить семафор
7279
#define LP_SEM_SIGNAL(sem) sem++;
7380

src/LooperClass.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -85,20 +85,25 @@ void LooperClass::add(LoopTask* task) {
8585
if (!_setup) _tickState(task, tState::Setup);
8686
}
8787

88-
void LooperClass::remove(LoopTask* task) {
88+
void LooperClass::remove(LoopTask* task, bool callExit) {
8989
if (!task) return;
90-
_tickState(task, tState::Exit);
90+
91+
if (_thisTask == task) {
92+
if (!_removed) {
93+
_removed = true;
94+
if (callExit) _tickState(task, tState::Exit);
95+
}
96+
} else {
97+
if (callExit) _tickState(task, tState::Exit);
98+
}
9199

92100
#if LOOPER_USE_EVENTS
93101
task->isListener() ? _lisns.remove(task) : _tasks.remove(task);
94102
#else
95103
if (!task->isListener()) _tasks.remove(task);
96104
#endif
97105

98-
if (_thisTask == task) {
99-
_thisTask = _thisTask->getPrev();
100-
_removed = true;
101-
}
106+
if (_thisTask == task) _thisTask = _thisTask->getPrev();
102107
}
103108

104109
void LooperClass::_tickState(LoopTask* task, tState state) {
@@ -113,8 +118,8 @@ void LooperClass::_tickState(LoopTask* task, tState state) {
113118
}
114119
}
115120

116-
void LooperClass::removeThis() {
117-
remove(thisTask());
121+
void LooperClass::removeThis(bool callExit) {
122+
remove(thisTask(), callExit);
118123
}
119124

120125
LoopTask* LooperClass::thisTask() { return _removed ? nullptr : _thisTask; }

src/LooperClass.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ class LooperClass {
3535
// добавить задачу
3636
void add(LoopTask* task);
3737

38-
// убрать задачу
39-
void remove(LoopTask* task);
38+
// убрать задачу и вызвать обработчик выхода (опционально)
39+
void remove(LoopTask* task, bool callExit = true);
4040

4141
// получить указатель на задачу по id
4242
LoopTask* getTask(hash_t id);
@@ -66,8 +66,8 @@ class LooperClass {
6666
return static_cast<T*>(thisTask());
6767
}
6868

69-
// убрать текущую задачу из loop
70-
void removeThis();
69+
// убрать текущую задачу из loop и вызвать обработчик выхода (опционально)
70+
void removeThis(bool callExit = true);
7171

7272
// статус текущей задачи
7373
tState thisState();

0 commit comments

Comments
 (0)