Skip to content

Commit 386c364

Browse files
committed
upd
1 parent 4e9def4 commit 386c364

File tree

9 files changed

+147
-130
lines changed

9 files changed

+147
-130
lines changed

docs/0.main.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,9 @@ bool isTimer();
196196
// задача - тикер
197197
bool isTicker();
198198

199+
// задача - поток
200+
bool isThread();
201+
199202
// задача - обработчик событий
200203
bool isListener();
201204
```
@@ -344,11 +347,12 @@ T* getData();
344347
```
345348
346349
### LoopThread
347-
Тикер, наследует `LoopTicker`
350+
Поток, наследует `LoopTask`
351+
348352
```cpp
349-
LoopThread(TaskCallback callback, bool states = true, bool events = true);
350-
LoopThread(const char* id, TaskCallback callback, bool states = true, bool events = true);
351-
LoopThread(hash_t id, TaskCallback callback, bool states = true, bool events = true);
353+
LoopThread(TaskCallback callback);
354+
LoopThread(const char* id, TaskCallback callback);
355+
LoopThread(hash_t id, TaskCallback callback);
352356
```
353357

354358
### LoopThreadData<T>

docs/2.threads.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ LP_THREAD({
102102
});
103103
```
104104
105+
> Примечание: оставшееся время до продолжения выполнения учитывается в `Looper.nextTimerLeft()`, как и у задач-таймеров
106+
105107
### Ожидание условия
106108
Поток также может асинхронно ждать наступления указанного условия, например:
107109

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.5
2+
version=1.1.6
33
author=AlexGyver <[email protected]>
44
maintainer=AlexGyver <[email protected]>
55
sentence=Simple task, thread and event manager for Arduino

src/Looper.h

Lines changed: 1 addition & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -5,103 +5,4 @@
55
#include "nodes/Thread.h"
66
#include "nodes/Ticker.h"
77
#include "nodes/Timer.h"
8-
9-
// ========= macro =========
10-
// широковещательное событие
11-
#define LP_BROADCAST (hash_t)0
12-
13-
// отправить событие
14-
#define LP_SEND_EVENT(id, data) Looper.sendEvent(LPH(id), data)
15-
16-
// отложить отправку события
17-
#define LP_PUSH_EVENT(id, data) Looper.pushEvent(LPH(id), data)
18-
19-
#define LP_MAKE(type, ...) static type _LP_CONCAT(__loop_obj_, __COUNTER__)(__VA_ARGS__)
20-
#define LP_MAKE_(id, type, ...) static type _LP_CONCAT(__loop_obj_, __COUNTER__)(LPH(id), __VA_ARGS__)
21-
#define LP_NEW(type, ...) new type(__VA_ARGS__)
22-
#define LP_NEW_(id, type, ...) new type(LPH(id), __VA_ARGS__)
23-
24-
// LISTENER
25-
#define LP_LISTENER_(id, ...) LP_MAKE_(id, LoopListener, __VA_ARGS__)
26-
27-
// TICKER
28-
#define LP_TICKER(...) LP_MAKE(LoopTicker, __VA_ARGS__)
29-
#define LP_TICKER_(id, ...) LP_MAKE_(id, LoopTicker, __VA_ARGS__)
30-
31-
// TIMER
32-
#define LP_TIMER(ms, ...) LP_MAKE(LoopTimer, ms, __VA_ARGS__)
33-
#define LP_TIMER_(id, ms, ...) LP_MAKE_(id, LoopTimer, ms, __VA_ARGS__)
34-
35-
// THREAD
36-
#define _LP_THREAD_CASE Looper.thisThread()->_case
37-
#define _LP_THREAD_RESET() _LP_THREAD_CASE = 0;
38-
39-
// начать поток
40-
#define LP_THREAD_BEGIN() \
41-
switch (_LP_THREAD_CASE) { \
42-
case 0:;
43-
44-
// завершить поток
45-
#define LP_THREAD_END() \
46-
} \
47-
_LP_THREAD_RESET();
48-
49-
#define _LP_THREAD_INNER(body) \
50-
LP_THREAD_BEGIN(); \
51-
body \
52-
LP_THREAD_END();
53-
54-
#define LP_THREAD(body) static LoopThread _LP_CONCAT(__loop_obj_, __COUNTER__)([]() { _LP_THREAD_INNER(body) })
55-
#define LP_THREAD_(id, body) static LoopThread _LP_CONCAT(__loop_obj_, __COUNTER__)(LPH(id), []() { _LP_THREAD_INNER(body) })
56-
#define LP_THREAD_DATA(T, data, data_arg, body) static LoopThreadData<T> _LP_CONCAT(__loop_obj_, __COUNTER__)(data, [](data_arg) { _LP_THREAD_INNER(body) })
57-
#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) })
58-
59-
// перезапустить поток (начать выполнение с начала)
60-
#define LP_RESTART() \
61-
do { \
62-
_LP_THREAD_RESET(); \
63-
return; \
64-
} while (0);
65-
66-
// выйти из потока и потом вернуться в эту точку
67-
#define LP_EXIT() \
68-
do { \
69-
_LP_THREAD_CASE = __COUNTER__ + 1; \
70-
return; \
71-
case __COUNTER__:; \
72-
} while (0);
73-
74-
// асинхронно ждать условия
75-
#define LP_WAIT(cond) \
76-
do { \
77-
_LP_THREAD_CASE = __COUNTER__ + 1; \
78-
case __COUNTER__: \
79-
if (!(cond)) return; \
80-
} while (0);
81-
82-
// асинхронно ждать события
83-
#define LP_WAIT_EVENT() LP_WAIT(Looper.thisEvent());
84-
85-
// асинхронно ждать время в мс
86-
#define LP_DELAY(ms) \
87-
do { \
88-
Looper.thisThread()->_resetTmr(); \
89-
LP_WAIT(Looper.thisThread()->_elapsed(ms)); \
90-
Looper.thisThread()->_stopTmr(); \
91-
} while (0);
92-
93-
// устарело
94-
#define LP_SLEEP(ms) LP_DELAY(ms)
95-
96-
// освободить семафор
97-
#define LP_SEM_SIGNAL(sem) sem++;
98-
99-
// ждать семафор
100-
#define LP_SEM_WAIT(sem) \
101-
do { \
102-
LP_WAIT(sem); \
103-
sem--; \
104-
} while (0);
105-
106-
// семафор
107-
typedef uint16_t LP_SEM;
8+
#include "nodes/macro.h"

src/LooperClass.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ void LooperClass::loop() {
1717
while (_thisTask) {
1818
looper::yield();
1919
switch (_thisTask->_tickMask()) {
20-
case (TASK_ENABLED_TICKER):
20+
case TASK_ENABLED_THREAD:
21+
case TASK_ENABLED_TICKER:
2122
_thisTask->exec();
2223
break;
23-
case (TASK_ENABLED_TIMER):
24+
25+
case TASK_ENABLED_TIMER:
2426
static_cast<LoopTimer*>(_thisTask)->poll();
2527
break;
2628
}
@@ -49,11 +51,19 @@ void LooperClass::restart() {
4951
uint32_t LooperClass::nextTimerLeft() {
5052
uint32_t next = UINT32_MAX;
5153
LoopTask* p = _tasks.getLast();
54+
uint32_t left = 0;
5255
while (p) {
53-
if (p->_tickMask() == TASK_ENABLED_TIMER) {
54-
uint32_t left = static_cast<LoopTimer*>(p)->left();
55-
if (left < next) next = left;
56+
switch (p->_tickMask()) {
57+
case TASK_ENABLED_THREAD:
58+
left = static_cast<LoopThread*>(p)->_tmr.left();
59+
break;
60+
61+
case TASK_ENABLED_TIMER:
62+
left = static_cast<LoopTimer*>(p)->left();
63+
break;
5664
}
65+
if (!left) return 0;
66+
if (next > left) next = left;
5767
p = p->getPrev();
5868
}
5969
return next == UINT32_MAX ? 0 : next;

src/nodes/LoopTask.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,14 @@ bool LoopTask::isTicker() {
6969
bool LoopTask::isListener() {
7070
return sreg.read(TASK_IS_LISTENER);
7171
}
72+
bool LoopTask::isThread() {
73+
return sreg.read(TASK_IS_THREAD);
74+
}
7275

7376
bool LoopTask::canListen() {
7477
return sreg.isSet(TASK_ENABLED | TASK_HAS_EVENTS);
7578
}
7679

7780
uint8_t LoopTask::_tickMask() {
78-
return sreg.mask(TASK_ENABLED | TASK_IS_TICKER | TASK_IS_TIMER);
81+
return sreg.mask(TASK_ENABLED | TASK_IS_TICKER | TASK_IS_TIMER | TASK_IS_THREAD);
7982
}

src/nodes/LoopTask.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
#define TASK_IS_LISTENER (1 << 1)
1313
#define TASK_IS_TICKER (1 << 2)
1414
#define TASK_IS_TIMER (1 << 3)
15-
#define TASK_HAS_EVENTS (1 << 4)
16-
#define TASK_HAS_STATES (1 << 5)
15+
#define TASK_IS_THREAD (1 << 4)
16+
#define TASK_HAS_EVENTS (1 << 5)
17+
#define TASK_HAS_STATES (1 << 6)
1718

1819
#define TASK_ENABLED_TICKER (TASK_ENABLED | TASK_IS_TICKER)
1920
#define TASK_ENABLED_TIMER (TASK_ENABLED | TASK_IS_TIMER)
21+
#define TASK_ENABLED_THREAD (TASK_ENABLED | TASK_IS_THREAD)
2022

2123
enum class tState : uint8_t {
2224
None,
@@ -99,6 +101,9 @@ class LoopTask : public looper::List<LoopTask>::Node {
99101

100102
// задача - обработчик событий
101103
bool isListener();
104+
105+
// задача - поток
106+
bool isThread();
102107

103108
// запущен и слушает события
104109
bool canListen();

src/nodes/Thread.h

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,19 @@
11
#pragma once
2-
#include "Ticker.h"
2+
#include "../utils/SimpleTimer.h"
3+
#include "CallbackData.h"
4+
#include "LoopTask.h"
35

46
// задача-поток, вызывается постоянно
5-
class LoopThread : public LoopTicker {
7+
class LoopThread : public LoopTask {
68
public:
7-
using LoopTicker::LoopTicker;
8-
9-
void _resetTmr() {
10-
if (!_tmr) {
11-
_tmr = looper::millis();
12-
if (!_tmr) _tmr--;
13-
}
14-
}
15-
void _stopTmr() {
16-
_tmr = 0;
17-
}
18-
bool _elapsed(uint32_t ms) {
19-
return looper::millis() - _tmr >= ms;
20-
}
9+
LoopThread(TaskCallback callback) : LoopThread((hash_t)0, callback) {}
10+
LoopThread(const char* id, TaskCallback callback) : LoopThread(LPHr(id), callback) {}
11+
LoopThread(hash_t id, TaskCallback callback) : LoopTask(id, callback, TASK_IS_THREAD, true, true) {}
2112

2213
uint16_t _case = 0;
14+
SimpleTimer _tmr;
2315

2416
private:
25-
uint32_t _tmr = 0;
2617
};
2718

2819
// поток с данными

src/nodes/macro.h

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#pragma once
2+
#include <inttypes.h>
3+
4+
// ========= macro =========
5+
// широковещательное событие
6+
#define LP_BROADCAST (hash_t)0
7+
8+
// отправить событие
9+
#define LP_SEND_EVENT(id, data) Looper.sendEvent(LPH(id), data)
10+
11+
// отложить отправку события
12+
#define LP_PUSH_EVENT(id, data) Looper.pushEvent(LPH(id), data)
13+
14+
#define LP_MAKE(type, ...) static type _LP_CONCAT(__loop_obj_, __COUNTER__)(__VA_ARGS__)
15+
#define LP_MAKE_(id, type, ...) static type _LP_CONCAT(__loop_obj_, __COUNTER__)(LPH(id), __VA_ARGS__)
16+
#define LP_NEW(type, ...) new type(__VA_ARGS__)
17+
#define LP_NEW_(id, type, ...) new type(LPH(id), __VA_ARGS__)
18+
19+
// LISTENER
20+
#define LP_LISTENER_(id, ...) LP_MAKE_(id, LoopListener, __VA_ARGS__)
21+
22+
// TICKER
23+
#define LP_TICKER(...) LP_MAKE(LoopTicker, __VA_ARGS__)
24+
#define LP_TICKER_(id, ...) LP_MAKE_(id, LoopTicker, __VA_ARGS__)
25+
26+
// TIMER
27+
#define LP_TIMER(ms, ...) LP_MAKE(LoopTimer, ms, __VA_ARGS__)
28+
#define LP_TIMER_(id, ms, ...) LP_MAKE_(id, LoopTimer, ms, __VA_ARGS__)
29+
30+
// THREAD
31+
#define _LP_THREAD_CASE Looper.thisThread()->_case
32+
#define _LP_THREAD_RESET() _LP_THREAD_CASE = 0;
33+
34+
// начать поток
35+
#define LP_THREAD_BEGIN() \
36+
switch (_LP_THREAD_CASE) { \
37+
case 0:;
38+
39+
// завершить поток
40+
#define LP_THREAD_END() \
41+
} \
42+
_LP_THREAD_RESET();
43+
44+
#define _LP_THREAD_INNER(body) \
45+
LP_THREAD_BEGIN(); \
46+
body \
47+
LP_THREAD_END();
48+
49+
#define LP_THREAD(body) static LoopThread _LP_CONCAT(__loop_obj_, __COUNTER__)([]() { _LP_THREAD_INNER(body) })
50+
#define LP_THREAD_(id, body) static LoopThread _LP_CONCAT(__loop_obj_, __COUNTER__)(LPH(id), []() { _LP_THREAD_INNER(body) })
51+
#define LP_THREAD_DATA(T, data, data_arg, body) static LoopThreadData<T> _LP_CONCAT(__loop_obj_, __COUNTER__)(data, [](data_arg) { _LP_THREAD_INNER(body) })
52+
#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) })
53+
54+
// перезапустить поток (начать выполнение с начала)
55+
#define LP_RESTART() \
56+
do { \
57+
_LP_THREAD_RESET(); \
58+
return; \
59+
} while (0);
60+
61+
// выйти из потока и потом вернуться в эту точку
62+
#define LP_EXIT() \
63+
do { \
64+
_LP_THREAD_CASE = __COUNTER__ + 1; \
65+
return; \
66+
case __COUNTER__:; \
67+
} while (0);
68+
69+
// асинхронно ждать условия
70+
#define LP_WAIT(cond) \
71+
do { \
72+
_LP_THREAD_CASE = __COUNTER__ + 1; \
73+
case __COUNTER__: \
74+
if (!(cond)) return; \
75+
} while (0);
76+
77+
// асинхронно ждать события
78+
#define LP_WAIT_EVENT() LP_WAIT(Looper.thisEvent());
79+
80+
// асинхронно ждать время в мс
81+
#define LP_DELAY(ms) \
82+
do { \
83+
Looper.thisThread()->_tmr.restart(ms); \
84+
LP_WAIT(Looper.thisThread()->_tmr.timeout()); \
85+
} while (0);
86+
87+
// устарело
88+
#define LP_SLEEP(ms) LP_DELAY(ms)
89+
90+
// освободить семафор
91+
#define LP_SEM_SIGNAL(sem) sem++;
92+
93+
// ждать семафор
94+
#define LP_SEM_WAIT(sem) \
95+
do { \
96+
LP_WAIT(sem); \
97+
sem--; \
98+
} while (0);
99+
100+
// семафор
101+
typedef uint16_t LP_SEM;

0 commit comments

Comments
 (0)