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