Skip to content

Commit

Permalink
Merge pull request #22 from mairas/task_support
Browse files Browse the repository at this point in the history
Support for running ReactESP simultaneously in multiple FreeRTOS tasks
  • Loading branch information
mairas authored Mar 3, 2022
2 parents eb27169 + 8cea2a7 commit 7db22fc
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 31 deletions.
62 changes: 45 additions & 17 deletions src/ReactESP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,16 @@ bool TimedReaction::operator<(const TimedReaction& other) {
(other.last_trigger_time + other.interval);
}

void TimedReaction::add() { ReactESP::app->timed_queue.push(this); }
void TimedReaction::add(ReactESP* app) {
if (app == nullptr) {
Serial.println("Got a null pointer in TimedReaction::add");
app = ReactESP::app;
}
app_context = app;
app->timed_queue.push(this);
}

void TimedReaction::remove() {
void TimedReaction::remove(ReactESP* app) {
this->enabled = false;
// the object will be deleted when it's popped out of the
// timer queue
Expand Down Expand Up @@ -57,13 +64,22 @@ void RepeatReaction::tick() {
this->last_trigger_time = now;
}
this->callback();
ReactESP::app->timed_queue.push(this);
app_context->timed_queue.push(this);
}

void UntimedReaction::add(ReactESP* app) {
if (app == nullptr) {
app = ReactESP::app;
}
app->untimed_list.push_front(this);
}

void UntimedReaction::add() { ReactESP::app->untimed_list.push_front(this); }
void UntimedReaction::remove(ReactESP* app) {
if (app == nullptr) {
app = ReactESP::app;
}

void UntimedReaction::remove() {
ReactESP::app->untimed_list.remove(this);
app->untimed_list.remove(this);
delete this;
}

Expand All @@ -84,17 +100,25 @@ void ISRReaction::isr(void* this_ptr) {
}
#endif

void ISRReaction::add() {
void ISRReaction::add(ReactESP* app) {
if (app == nullptr) {
app = ReactESP::app;
}

#ifdef ESP32
gpio_isr_handler_add((gpio_num_t)pin_number, ISRReaction::isr, (void*)this);
#elif defined(ESP8266)
attachInterrupt(digitalPinToInterrupt(pin_number), callback, mode);
#endif
ReactESP::app->isr_reaction_list.push_front(this);
app->isr_reaction_list.push_front(this);
}

void ISRReaction::remove() {
ReactESP::app->isr_reaction_list.remove(this);
void ISRReaction::remove(ReactESP* app) {
if (app == nullptr) {
app = ReactESP::app;
}

app->isr_reaction_list.remove(this);
#ifdef ESP32
gpio_isr_handler_remove((gpio_num_t)pin_number);
#elif defined(ESP8266)
Expand Down Expand Up @@ -144,47 +168,51 @@ void ReactESP::tick() {

DelayReaction* ReactESP::onDelay(const uint32_t t, const react_callback cb) {
DelayReaction* dre = new DelayReaction(t, cb);
dre->add();
dre->add(this);
return dre;
}

DelayReaction* ReactESP::onDelayMicros(const uint64_t t,
const react_callback cb) {
DelayReaction* dre = new DelayReaction(t, cb);
dre->add();
dre->add(this);
return dre;
}

RepeatReaction* ReactESP::onRepeat(const uint32_t t, const react_callback cb) {
RepeatReaction* rre = new RepeatReaction(t, cb);
rre->add();
rre->add(this);
return rre;
}

RepeatReaction* ReactESP::onRepeatMicros(const uint64_t t,
const react_callback cb) {
RepeatReaction* rre = new RepeatReaction(t, cb);
rre->add();
rre->add(this);
return rre;
}

StreamReaction* ReactESP::onAvailable(Stream& stream, const react_callback cb) {
StreamReaction* sre = new StreamReaction(stream, cb);
sre->add();
sre->add(this);
return sre;
}

ISRReaction* ReactESP::onInterrupt(const uint8_t pin_number, int mode,
const react_callback cb) {
ISRReaction* isrre = new ISRReaction(pin_number, mode, cb);
isrre->add();
isrre->add(this);
return isrre;
}

TickReaction* ReactESP::onTick(const react_callback cb) {
TickReaction* tre = new TickReaction(cb);
tre->add();
tre->add(this);
return tre;
}

void ReactESP::remove(Reaction* reaction) {
reaction->remove(this);
}

} // namespace reactesp
41 changes: 27 additions & 14 deletions src/ReactESP.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class Reaction {
*/
Reaction(react_callback callback) : callback(callback) {}
// FIXME: why do these have to be defined?
virtual void add() = 0;
virtual void remove() = 0;
virtual void add(ReactESP* app = nullptr) = 0;
virtual void remove(ReactESP* app = nullptr) = 0;
virtual void tick() = 0;
};

Expand All @@ -49,6 +49,8 @@ class TimedReaction : public Reaction {
const uint64_t interval;
uint64_t last_trigger_time;
bool enabled;
// A repeat reaction needs to know which app it belongs to
ReactESP* app_context = nullptr;

public:
/**
Expand Down Expand Up @@ -76,8 +78,8 @@ class TimedReaction : public Reaction {

virtual ~TimedReaction() {}
bool operator<(const TimedReaction& other);
void add();
void remove();
void add(ReactESP* app = nullptr) override;
void remove(ReactESP* app = nullptr) override;
uint32_t getTriggerTime() { return (last_trigger_time + interval) / 1000; }
uint64_t getTriggerTimeMicros() { return (last_trigger_time + interval); }
bool isEnabled() { return enabled; }
Expand Down Expand Up @@ -142,8 +144,8 @@ class UntimedReaction : public Reaction {
public:
UntimedReaction(const react_callback callback) : Reaction(callback) {}
virtual ~UntimedReaction() {}
virtual void add();
virtual void remove();
virtual void add(ReactESP* app = nullptr) override;
virtual void remove(ReactESP* app = nullptr) override;
virtual void tick() = 0;
};

Expand Down Expand Up @@ -193,7 +195,7 @@ class ISRReaction : public Reaction {
static bool isr_service_installed;
static void isr(void* arg);
#endif

public:
/**
* @brief Construct a new ISRReaction object
Expand All @@ -204,9 +206,7 @@ class ISRReaction : public Reaction {
* ICACHE_RAM_ATTR attribute.
*/
ISRReaction(uint8_t pin_number, int mode, const react_callback callback)
: Reaction(callback),
pin_number(pin_number),
mode(mode) {
: Reaction(callback), pin_number(pin_number), mode(mode) {
#ifdef ESP32
gpio_int_type_t intr_type;
switch (mode) {
Expand All @@ -233,8 +233,8 @@ class ISRReaction : public Reaction {
#endif
}
virtual ~ISRReaction() {}
void add();
void remove();
void add(ReactESP* app = nullptr) override;
void remove(ReactESP* app = nullptr) override;
void tick() {}
};

Expand All @@ -253,9 +253,15 @@ class ReactESP {

public:
/**
* @brief Construct a new ReactESP object
* @brief Construct a new ReactESP object.
*
* @param singleton If true, set the singleton instance to this object
*/
ReactESP() { app = this; }
ReactESP(bool singleton = true) {
if (singleton) {
app = this;
}
}
void tick(void);

/// Static singleton reference to the instantiated ReactESP object
Expand Down Expand Up @@ -321,6 +327,13 @@ class ReactESP {
*/
TickReaction* onTick(const react_callback cb);

/**
* @brief Remove a reaction from the list of active reactions
*
* @param reaction Reaction to remove
*/
void remove(Reaction* reaction);

private:
std::priority_queue<TimedReaction*, std::vector<TimedReaction*>,
TriggerTimeCompare>
Expand Down

0 comments on commit 7db22fc

Please sign in to comment.