ReactESP 3.0.0
Asynchronous programming for the ESP microcontrollers
Loading...
Searching...
No Matches
ReactESP.cpp
Go to the documentation of this file.
1#include "ReactESP.h"
2
3#include <Arduino.h>
4#include <FunctionalInterrupt.h>
5
6#include <cstring>
7
8namespace reactesp {
9
10// Event classes define the behaviour of each particular
11// Event
12
13bool TimedEvent::operator<(const TimedEvent& other) const {
14 return (this->last_trigger_time + this->interval) <
15 (other.last_trigger_time + other.interval);
16}
17
19 event_loop->timed_queue.push(this);
20}
21
23 this->enabled = false;
24 // the object will be deleted when it's popped out of the
25 // timer queue
26}
27
28DelayEvent::DelayEvent(uint32_t delay, react_callback callback)
29 : TimedEvent(delay, callback) {
30 this->last_trigger_time = micros();
31}
32
33DelayEvent::DelayEvent(uint64_t delay, react_callback callback)
34 : TimedEvent(delay, callback) {
35 this->last_trigger_time = micros();
36}
37
39 this->last_trigger_time = micros();
40 this->callback();
41 delete this;
42}
43
45 auto now = micros();
46 this->last_trigger_time = this->last_trigger_time + this->interval;
47 if (this->last_trigger_time + this->interval < now) {
48 // we're lagging more than one full interval; reset the time
49 this->last_trigger_time = now;
50 }
51 this->callback();
52 event_loop->timed_queue.push(this);
53}
54
56 event_loop->untimed_list.push_front(this);
57}
58
60 event_loop->untimed_list.remove(this);
61 delete this;
62}
63
65 if (0 != stream.available()) {
66 this->callback();
67 }
68}
69
71
72#ifdef ESP32
73bool ISREvent::isr_service_installed = false;
74
75void ISREvent::isr(void* this_ptr) {
76 auto* this_ = static_cast<ISREvent*>(this_ptr);
77 this_->callback();
78}
79#endif
80
82#ifdef ESP32
83 gpio_isr_handler_add((gpio_num_t)pin_number, ISREvent::isr, (void*)this);
84#elif defined(ESP8266)
85 attachInterrupt(digitalPinToInterrupt(pin_number), callback, mode);
86#endif
87 event_loop->isr_event_list.push_front(this);
88}
89
91 event_loop->isr_event_list.remove(this);
92#ifdef ESP32
93 gpio_isr_handler_remove((gpio_num_t)pin_number);
94#elif defined(ESP8266)
95 detachInterrupt(digitalPinToInterrupt(this->pin_number));
96#endif
97 delete this;
98}
99
100void EventLoop::tickTimed() {
101 const uint64_t now = micros();
102 TimedEvent* top = nullptr;
103
104 while (true) {
105 if (timed_queue.empty()) {
106 break;
107 }
108
109 top = timed_queue.top();
110 if (!top->isEnabled()) {
111 timed_queue.pop();
112 delete top;
113 continue;
114 }
115 const uint64_t trigger_t = top->getTriggerTimeMicros();
116 if (now >= trigger_t) {
117 timed_queue.pop();
118 top->tick(this);
119 } else {
120 break;
121 }
122 }
123}
124
125void EventLoop::tickUntimed() {
126 for (UntimedEvent* re : this->untimed_list) {
127 re->tick(this);
128 }
129}
130
132 tickUntimed();
133 tickTimed();
134}
135
136DelayEvent* EventLoop::onDelay(uint32_t delay, react_callback callback) {
137 auto* dre = new DelayEvent(delay, callback);
138 dre->add(this);
139 return dre;
140}
141
143 react_callback callback) {
144 auto* dre = new DelayEvent(delay, callback);
145 dre->add(this);
146 return dre;
147}
148
149RepeatEvent* EventLoop::onRepeat(uint32_t interval, react_callback callback) {
150 auto* rre = new RepeatEvent(interval, callback);
151 rre->add(this);
152 return rre;
153}
154
156 react_callback callback) {
157 auto* rre = new RepeatEvent(interval, callback);
158 rre->add(this);
159 return rre;
160}
161
163 auto* sre = new StreamEvent(stream, callback);
164 sre->add(this);
165 return sre;
166}
167
168ISREvent* EventLoop::onInterrupt(uint8_t pin_number, int mode,
169 react_callback callback) {
170 auto* isrre = new ISREvent(pin_number, mode, callback);
171 isrre->add(this);
172 return isrre;
173}
174
176 auto* tre = new TickEvent(callback);
177 tre->add(this);
178 return tre;
179}
180
181void EventLoop::remove(Event* event) { event->remove(this); }
182
183} // namespace reactesp
Event that is triggered after a certain time delay.
Definition ReactESP.h:107
DelayEvent(uint32_t delay, react_callback callback)
Construct a new Delay Event object.
Definition ReactESP.cpp:28
void tick(EventLoop *event_loop) override
Definition ReactESP.cpp:38
Events are code to be called when a given condition is fulfilled.
Definition ReactESP.h:36
const react_callback callback
Definition ReactESP.h:38
Main event loop of a EventLoop program.
Definition ReactESP.h:260
friend class UntimedEvent
Definition ReactESP.h:264
DelayEvent * onDelayMicros(uint64_t delay, react_callback callback)
Create a new DelayEvent.
Definition ReactESP.cpp:142
friend class ISREvent
Definition ReactESP.h:265
StreamEvent * onAvailable(Stream &stream, react_callback callback)
Create a new StreamEvent.
Definition ReactESP.cpp:162
TickEvent * onTick(react_callback callback)
Create a new TickEvent.
Definition ReactESP.cpp:175
DelayEvent * onDelay(uint32_t delay, react_callback callback)
Create a new DelayEvent.
Definition ReactESP.cpp:136
RepeatEvent * onRepeatMicros(uint64_t interval, react_callback callback)
Create a new RepeatEvent.
Definition ReactESP.cpp:155
ISREvent * onInterrupt(uint8_t pin_number, int mode, react_callback callback)
Create a new ISREvent (interrupt event)
Definition ReactESP.cpp:168
RepeatEvent * onRepeat(uint32_t interval, react_callback callback)
Create a new RepeatEvent.
Definition ReactESP.cpp:149
void remove(Event *event)
Remove a event from the list of active events.
Definition ReactESP.cpp:181
friend class RepeatEvent
Definition ReactESP.h:263
Event that is triggered on an input pin change.
Definition ReactESP.h:202
void remove(EventLoop *event_loop) override
Definition ReactESP.cpp:90
void add(EventLoop *event_loop) override
Definition ReactESP.cpp:81
Event that is triggered repeatedly.
Definition ReactESP.h:130
void tick(EventLoop *event_loop) override
Definition ReactESP.cpp:44
Event that is triggered when there is input available at the given Arduino Stream.
Definition ReactESP.h:167
void tick(EventLoop *event_loop) override
Definition ReactESP.cpp:64
Event that is triggered unconditionally at each execution loop.
Definition ReactESP.h:187
void tick(EventLoop *event_loop) override
Definition ReactESP.cpp:70
TimedEvents are called based on elapsing of time.
Definition ReactESP.h:58
const uint64_t interval
Definition ReactESP.h:60
uint64_t getTriggerTimeMicros() const
Definition ReactESP.h:94
bool isEnabled() const
Definition ReactESP.h:97
void add(EventLoop *event_loop) override
Definition ReactESP.cpp:18
void remove(EventLoop *event_loop) override
Definition ReactESP.cpp:22
bool operator<(const TimedEvent &other) const
Definition ReactESP.cpp:13
uint64_t last_trigger_time
Definition ReactESP.h:61
void add(EventLoop *event_loop) override
Definition ReactESP.cpp:55
void remove(EventLoop *event_loop) override
Definition ReactESP.cpp:59
EventLoop event_loop
Definition main.cpp:19
std::function< void()> react_callback
Definition ReactESP.h:12
virtual void tick(EventLoop *event_loop)=0