Fix: Component script not stopped in certain situations (#1004)

* Move stop/is_running implementation to Action base class

Try to fix issue #1105.  Until now if an UpdateComponentAction, a
LambdaAction, or any action that can contain those inside their
"else" or "then" action lists, resulted in a call to script.stop on
the script that contains them, the script would continue running,
because they didn't implement a stop() method.  Basically only
the asynchronous ones did: DelayAction, WaitUntilAction and
ScriptWaitAction.

With this change num_running_ in Action replaces
DelayAction::num_running_ and WaitUntilAction::triggered_ to provide
the same is_running logic to other actions.

* Make some Action methods protected

Apparently play()/stop() etc. are not meant to be called directly by
users of the class and if they're called directly that would not give
the expected result for the classes that have an empty play().

Make all methods except play_complex, stop_comples and is_running
protected.  While there also make RemoteTransmitterActionBase::encode
protected.

* lint

* format

Co-authored-by: Guillermo Ruffino <glm.net@gmail.com>
This commit is contained in:
Andrew Zaborowski 2020-06-29 00:44:15 +02:00 committed by GitHub
parent 78633c5768
commit 2f07225984
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
28 changed files with 121 additions and 109 deletions

View file

@ -29,6 +29,7 @@ template<typename... Ts> class HomeAssistantServiceCallAction : public Action<Ts
template<typename T> void add_variable(std::string key, T value) {
this->variables_.push_back(TemplatableKeyValuePair<Ts...>(key, value));
}
void play(Ts... x) override {
HomeassistantServiceResponse resp;
resp.service = this->service_.value(x...);

View file

@ -137,6 +137,7 @@ template<typename... Ts> class BinarySensorPublishAction : public Action<Ts...>
public:
explicit BinarySensorPublishAction(BinarySensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(bool, state)
void play(Ts... x) override {
auto val = this->state_.value(x...);
this->sensor_->publish_state(val);

View file

@ -41,6 +41,10 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
public:
explicit ControlAction(Cover *cover) : cover_(cover) {}
TEMPLATABLE_VALUE(bool, stop)
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
void play(Ts... x) override {
auto call = this->cover_->make_call();
if (this->stop_.has_value())
@ -52,10 +56,6 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
call.perform();
}
TEMPLATABLE_VALUE(bool, stop)
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
protected:
Cover *cover_;
};
@ -63,6 +63,10 @@ template<typename... Ts> class ControlAction : public Action<Ts...> {
template<typename... Ts> class CoverPublishAction : public Action<Ts...> {
public:
CoverPublishAction(Cover *cover) : cover_(cover) {}
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
TEMPLATABLE_VALUE(CoverOperation, current_operation)
void play(Ts... x) override {
if (this->position_.has_value())
this->cover_->position = this->position_.value(x...);
@ -73,10 +77,6 @@ template<typename... Ts> class CoverPublishAction : public Action<Ts...> {
this->cover_->publish_state();
}
TEMPLATABLE_VALUE(float, position)
TEMPLATABLE_VALUE(float, tilt)
TEMPLATABLE_VALUE(CoverOperation, current_operation)
protected:
Cover *cover_;
};

View file

@ -104,7 +104,6 @@ class DFPlayer : public uart::UARTDevice, public Component {
#define DFPLAYER_SIMPLE_ACTION(ACTION_CLASS, ACTION_METHOD) \
template<typename... Ts> class ACTION_CLASS : public Action<Ts...>, public Parented<DFPlayer> { \
public: \
void play(Ts... x) override { this->parent_->ACTION_METHOD(); } \
};
@ -115,6 +114,7 @@ template<typename... Ts> class PlayFileAction : public Action<Ts...>, public Par
public:
TEMPLATABLE_VALUE(uint16_t, file)
TEMPLATABLE_VALUE(boolean, loop)
void play(Ts... x) override {
auto file = this->file_.value(x...);
auto loop = this->loop_.value(x...);
@ -131,6 +131,7 @@ template<typename... Ts> class PlayFolderAction : public Action<Ts...>, public P
TEMPLATABLE_VALUE(uint16_t, folder)
TEMPLATABLE_VALUE(uint16_t, file)
TEMPLATABLE_VALUE(boolean, loop)
void play(Ts... x) override {
auto folder = this->folder_.value(x...);
auto file = this->file_.value(x...);
@ -146,6 +147,7 @@ template<typename... Ts> class PlayFolderAction : public Action<Ts...>, public P
template<typename... Ts> class SetDeviceAction : public Action<Ts...>, public Parented<DFPlayer> {
public:
TEMPLATABLE_VALUE(Device, device)
void play(Ts... x) override {
auto device = this->device_.value(x...);
this->parent_->set_device(device);
@ -155,6 +157,7 @@ template<typename... Ts> class SetDeviceAction : public Action<Ts...>, public Pa
template<typename... Ts> class SetVolumeAction : public Action<Ts...>, public Parented<DFPlayer> {
public:
TEMPLATABLE_VALUE(uint8_t, volume)
void play(Ts... x) override {
auto volume = this->volume_.value(x...);
this->parent_->set_volume(volume);
@ -164,6 +167,7 @@ template<typename... Ts> class SetVolumeAction : public Action<Ts...>, public Pa
template<typename... Ts> class SetEqAction : public Action<Ts...>, public Parented<DFPlayer> {
public:
TEMPLATABLE_VALUE(EqPreset, eq)
void play(Ts... x) override {
auto eq = this->eq_.value(x...);
this->parent_->set_eq(eq);

View file

@ -400,6 +400,7 @@ class Image {
template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
public:
TEMPLATABLE_VALUE(DisplayPage *, page)
void play(Ts... x) override {
auto *page = this->page_.value(x...);
if (page != nullptr) {
@ -411,18 +412,18 @@ template<typename... Ts> class DisplayPageShowAction : public Action<Ts...> {
template<typename... Ts> class DisplayPageShowNextAction : public Action<Ts...> {
public:
DisplayPageShowNextAction(DisplayBuffer *buffer) : buffer_(buffer) {}
void play(Ts... x) override { this->buffer_->show_next_page(); }
protected:
DisplayBuffer *buffer_;
};
template<typename... Ts> class DisplayPageShowPrevAction : public Action<Ts...> {
public:
DisplayPageShowPrevAction(DisplayBuffer *buffer) : buffer_(buffer) {}
void play(Ts... x) override { this->buffer_->show_prev_page(); }
protected:
DisplayBuffer *buffer_;
};

View file

@ -43,7 +43,6 @@ template<typename... Ts> class SetFrequencyAction : public Action<Ts...> {
this->parent_->update_frequency(freq);
}
protected:
ESP8266PWM *parent_;
};

View file

@ -25,7 +25,6 @@ template<typename... Ts> class TurnOnAction : public Action<Ts...> {
call.perform();
}
protected:
FanState *state_;
};
@ -35,7 +34,6 @@ template<typename... Ts> class TurnOffAction : public Action<Ts...> {
void play(Ts... x) override { this->state_->turn_off().perform(); }
protected:
FanState *state_;
};
@ -45,7 +43,6 @@ template<typename... Ts> class ToggleAction : public Action<Ts...> {
void play(Ts... x) override { this->state_->toggle().perform(); }
protected:
FanState *state_;
};

View file

@ -37,6 +37,7 @@ class MHZ19Component : public PollingComponent, public uart::UARTDevice {
template<typename... Ts> class MHZ19CalibrateZeroAction : public Action<Ts...> {
public:
MHZ19CalibrateZeroAction(MHZ19Component *mhz19) : mhz19_(mhz19) {}
void play(Ts... x) override { this->mhz19_->calibrate_zero(); }
protected:
@ -46,6 +47,7 @@ template<typename... Ts> class MHZ19CalibrateZeroAction : public Action<Ts...> {
template<typename... Ts> class MHZ19ABCEnableAction : public Action<Ts...> {
public:
MHZ19ABCEnableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {}
void play(Ts... x) override { this->mhz19_->abc_enable(); }
protected:
@ -55,6 +57,7 @@ template<typename... Ts> class MHZ19ABCEnableAction : public Action<Ts...> {
template<typename... Ts> class MHZ19ABCDisableAction : public Action<Ts...> {
public:
MHZ19ABCDisableAction(MHZ19Component *mhz19) : mhz19_(mhz19) {}
void play(Ts... x) override { this->mhz19_->abc_disable(); }
protected:

View file

@ -316,6 +316,7 @@ template<typename... Ts> class MQTTPublishJsonAction : public Action<Ts...> {
TEMPLATABLE_VALUE(bool, retain)
void set_payload(std::function<void(Ts..., JsonObject &)> payload) { this->payload_ = payload; }
void play(Ts... x) override {
auto f = std::bind(&MQTTPublishJsonAction<Ts...>::encode_, this, x..., std::placeholders::_1);
auto topic = this->topic_.value(x...);

View file

@ -33,6 +33,7 @@ template<typename... Ts> class SetLevelAction : public Action<Ts...> {
SetLevelAction(FloatOutput *output) : output_(output) {}
TEMPLATABLE_VALUE(float, level)
void play(Ts... x) override { this->output_->set_level(this->level_.value(x...)); }
protected:

View file

@ -71,6 +71,10 @@ template<typename... Ts> class PIDAutotuneAction : public Action<Ts...> {
public:
PIDAutotuneAction(PIDClimate *parent) : parent_(parent) {}
void set_noiseband(float noiseband) { noiseband_ = noiseband; }
void set_positive_output(float positive_output) { positive_output_ = positive_output; }
void set_negative_output(float negative_output) { negative_output_ = negative_output; }
void play(Ts... x) {
auto tuner = make_unique<PIDAutotuner>();
tuner->set_noiseband(this->noiseband_);
@ -79,10 +83,6 @@ template<typename... Ts> class PIDAutotuneAction : public Action<Ts...> {
this->parent_->start_autotune(std::move(tuner));
}
void set_noiseband(float noiseband) { noiseband_ = noiseband; }
void set_positive_output(float positive_output) { positive_output_ = positive_output; }
void set_negative_output(float negative_output) { negative_output_ = negative_output; }
protected:
float noiseband_;
float positive_output_;

View file

@ -23,6 +23,7 @@ DECLARE_REMOTE_PROTOCOL(JVC)
template<typename... Ts> class JVCAction : public RemoteTransmitterActionBase<Ts...> {
public:
TEMPLATABLE_VALUE(uint32_t, data)
void encode(RemoteTransmitData *dst, Ts... x) override {
JVCData data{};
data.data = this->data_.value(x...);

View file

@ -26,6 +26,7 @@ template<typename... Ts> class LGAction : public RemoteTransmitterActionBase<Ts.
public:
TEMPLATABLE_VALUE(uint32_t, data)
TEMPLATABLE_VALUE(uint8_t, nbits)
void encode(RemoteTransmitData *dst, Ts... x) override {
LGData data{};
data.data = this->data_.value(x...);

View file

@ -25,6 +25,7 @@ template<typename... Ts> class NECAction : public RemoteTransmitterActionBase<Ts
public:
TEMPLATABLE_VALUE(uint16_t, address)
TEMPLATABLE_VALUE(uint16_t, command)
void encode(RemoteTransmitData *dst, Ts... x) override {
NECData data{};
data.address = this->address_.value(x...);

View file

@ -26,6 +26,7 @@ template<typename... Ts> class PanasonicAction : public RemoteTransmitterActionB
public:
TEMPLATABLE_VALUE(uint16_t, address)
TEMPLATABLE_VALUE(uint32_t, command)
void encode(RemoteTransmitData *dst, Ts... x) override {
PanasonicData data{};
data.address = this->address_.value(x...);

View file

@ -25,6 +25,7 @@ template<typename... Ts> class PioneerAction : public RemoteTransmitterActionBas
public:
TEMPLATABLE_VALUE(uint16_t, rc_code_1)
TEMPLATABLE_VALUE(uint16_t, rc_code_2)
void encode(RemoteTransmitData *dst, Ts... x) override {
PioneerData data{};
data.rc_code_1 = this->rc_code_1_.value(x...);

View file

@ -26,6 +26,7 @@ template<typename... Ts> class RC5Action : public RemoteTransmitterActionBase<Ts
public:
TEMPLATABLE_VALUE(uint8_t, address)
TEMPLATABLE_VALUE(uint8_t, command)
void encode(RemoteTransmitData *dst, Ts... x) override {
RC5Data data{};
data.address = this->address_.value(x...);

View file

@ -323,6 +323,9 @@ template<typename... Ts> class RemoteTransmitterActionBase : public Action<Ts...
public:
void set_parent(RemoteTransmitterBase *parent) { this->parent_ = parent; }
TEMPLATABLE_VALUE(uint32_t, send_times);
TEMPLATABLE_VALUE(uint32_t, send_wait);
void play(Ts... x) override {
auto call = this->parent_->transmit();
this->encode(call.get_data(), x...);
@ -331,12 +334,9 @@ template<typename... Ts> class RemoteTransmitterActionBase : public Action<Ts...
call.perform();
}
protected:
virtual void encode(RemoteTransmitData *dst, Ts... x) = 0;
TEMPLATABLE_VALUE(uint32_t, send_times);
TEMPLATABLE_VALUE(uint32_t, send_wait);
protected:
RemoteTransmitterBase *parent_{};
};

View file

@ -24,6 +24,7 @@ DECLARE_REMOTE_PROTOCOL(Samsung)
template<typename... Ts> class SamsungAction : public RemoteTransmitterActionBase<Ts...> {
public:
TEMPLATABLE_VALUE(uint32_t, data)
void encode(RemoteTransmitData *dst, Ts... x) override {
SamsungData data{};
data.data = this->data_.value(x...);

View file

@ -26,6 +26,7 @@ template<typename... Ts> class SonyAction : public RemoteTransmitterActionBase<T
public:
TEMPLATABLE_VALUE(uint32_t, data)
TEMPLATABLE_VALUE(uint8_t, nbits)
void encode(RemoteTransmitData *dst, Ts... x) override {
SonyData data{};
data.data = this->data_.value(x...);

View file

@ -74,6 +74,7 @@ template<typename... Ts> class RotaryEncoderSetValueAction : public Action<Ts...
public:
RotaryEncoderSetValueAction(RotaryEncoderSensor *encoder) : encoder_(encoder) {}
TEMPLATABLE_VALUE(int, value)
void play(Ts... x) override { this->encoder_->set_value(this->value_.value(x...)); }
protected:

View file

@ -53,41 +53,34 @@ template<typename... Ts> class ScriptWaitAction : public Action<Ts...>, public C
public:
ScriptWaitAction(Script *script) : script_(script) {}
void play(Ts... x) { /* ignore - see play_complex */
}
void play_complex(Ts... x) override {
this->num_running_++;
// Check if we can continue immediately.
if (!this->script_->is_running()) {
this->triggered_ = false;
this->play_next(x...);
this->play_next_(x...);
return;
}
this->var_ = std::make_tuple(x...);
this->triggered_ = true;
this->loop();
}
void stop() override { this->triggered_ = false; }
void loop() override {
if (!this->triggered_)
if (this->num_running_ == 0)
return;
if (this->script_->is_running())
return;
this->triggered_ = false;
this->play_next_tuple(this->var_);
this->play_next_tuple_(this->var_);
}
float get_setup_priority() const override { return setup_priority::DATA; }
bool is_running() override { return this->triggered_ || this->is_running_next(); }
void play(Ts... x) override { /* ignore - see play_complex */
}
protected:
Script *script_;
bool triggered_{false};
std::tuple<Ts...> var_{};
};

View file

@ -25,6 +25,7 @@ template<typename... Ts> class SensorPublishAction : public Action<Ts...> {
public:
SensorPublishAction(Sensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(float, state)
void play(Ts... x) override { this->sensor_->publish_state(this->state_.value(x...)); }
protected:

View file

@ -64,6 +64,7 @@ template<typename... Ts> class ServoWriteAction : public Action<Ts...> {
public:
ServoWriteAction(Servo *servo) : servo_(servo) {}
TEMPLATABLE_VALUE(float, value)
void play(Ts... x) override { this->servo_->write(this->value_.value(x...)); }
protected:
@ -73,6 +74,7 @@ template<typename... Ts> class ServoWriteAction : public Action<Ts...> {
template<typename... Ts> class ServoDetachAction : public Action<Ts...> {
public:
ServoDetachAction(Servo *servo) : servo_(servo) {}
void play(Ts... x) override { this->servo_->detach(); }
protected:

View file

@ -73,6 +73,7 @@ template<typename... Ts> class SwitchPublishAction : public Action<Ts...> {
public:
SwitchPublishAction(Switch *a_switch) : switch_(a_switch) {}
TEMPLATABLE_VALUE(bool, state)
void play(Ts... x) override { this->switch_->publish_state(this->state_.value(x...)); }
protected:

View file

@ -30,6 +30,7 @@ template<typename... Ts> class TextSensorPublishAction : public Action<Ts...> {
public:
TextSensorPublishAction(TextSensor *sensor) : sensor_(sensor) {}
TEMPLATABLE_VALUE(std::string, state)
void play(Ts... x) override { this->sensor_->publish_state(this->state_.value(x...)); }
protected:

View file

@ -75,45 +75,55 @@ template<typename... Ts> class ActionList;
template<typename... Ts> class Action {
public:
virtual void play(Ts... x) = 0;
virtual void play_complex(Ts... x) {
this->num_running_++;
this->play(x...);
this->play_next(x...);
this->play_next_(x...);
}
void play_next(Ts... x) {
if (this->next_ != nullptr) {
this->next_->play_complex(x...);
virtual void stop_complex() {
if (num_running_) {
this->stop();
this->num_running_ = 0;
}
this->stop_next_();
}
virtual bool is_running() { return this->num_running_ > 0 || this->is_running_next_(); }
protected:
friend ActionList<Ts...>;
virtual void play(Ts... x) = 0;
void play_next_(Ts... x) {
if (this->num_running_ > 0) {
this->num_running_--;
if (this->next_ != nullptr) {
this->next_->play_complex(x...);
}
}
}
virtual void stop() {}
virtual void stop_complex() {
this->stop();
this->stop_next();
template<int... S> void play_next_tuple_(const std::tuple<Ts...> &tuple, seq<S...>) {
this->play_next_(std::get<S>(tuple)...);
}
void stop_next() {
void play_next_tuple_(const std::tuple<Ts...> &tuple) {
this->play_next_tuple_(tuple, typename gens<sizeof...(Ts)>::type());
}
virtual void stop() {}
void stop_next_() {
if (this->next_ != nullptr) {
this->next_->stop_complex();
}
}
virtual bool is_running() { return this->is_running_next(); }
bool is_running_next() {
bool is_running_next_() {
if (this->next_ == nullptr)
return false;
return this->next_->is_running();
}
void play_next_tuple(const std::tuple<Ts...> &tuple) {
this->play_next_tuple_(tuple, typename gens<sizeof...(Ts)>::type());
}
protected:
friend ActionList<Ts...>;
template<int... S> void play_next_tuple_(const std::tuple<Ts...> &tuple, seq<S...>) {
this->play_next(std::get<S>(tuple)...);
}
Action<Ts...> *next_ = nullptr;
int num_running_{0};
};
template<typename... Ts> class ActionList {

View file

@ -108,34 +108,23 @@ template<typename... Ts> class DelayAction : public Action<Ts...>, public Compon
TEMPLATABLE_VALUE(uint32_t, delay)
void stop() override {
this->cancel_timeout("");
this->num_running_ = 0;
}
void play(Ts... x) override { /* ignore - see play_complex */
}
void play_complex(Ts... x) override {
auto f = std::bind(&DelayAction<Ts...>::delay_end_, this, x...);
auto f = std::bind(&DelayAction<Ts...>::play_next_, this, x...);
this->num_running_++;
this->set_timeout(this->delay_.value(x...), f);
}
float get_setup_priority() const override { return setup_priority::HARDWARE; }
bool is_running() override { return this->num_running_ > 0 || this->is_running_next(); }
protected:
void delay_end_(Ts... x) {
this->num_running_--;
this->play_next(x...);
void play(Ts... x) override { /* ignore - see play_complex */
}
int num_running_{0};
void stop() override { this->cancel_timeout(""); }
};
template<typename... Ts> class LambdaAction : public Action<Ts...> {
public:
explicit LambdaAction(std::function<void(Ts...)> &&f) : f_(std::move(f)) {}
void play(Ts... x) override { this->f_(x...); }
protected:
@ -148,41 +137,40 @@ template<typename... Ts> class IfAction : public Action<Ts...> {
void add_then(const std::vector<Action<Ts...> *> &actions) {
this->then_.add_actions(actions);
this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next(x...); }));
this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next_(x...); }));
}
void add_else(const std::vector<Action<Ts...> *> &actions) {
this->else_.add_actions(actions);
this->else_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next(x...); }));
}
void play(Ts... x) override { /* ignore - see play_complex */
this->else_.add_action(new LambdaAction<Ts...>([this](Ts... x) { this->play_next_(x...); }));
}
void play_complex(Ts... x) override {
this->num_running_++;
bool res = this->condition_->check(x...);
if (res) {
if (this->then_.empty()) {
this->play_next(x...);
} else {
this->play_next_(x...);
} else if (this->num_running_ > 0) {
this->then_.play(x...);
}
} else {
if (this->else_.empty()) {
this->play_next(x...);
} else {
this->play_next_(x...);
} else if (this->num_running_ > 0) {
this->else_.play(x...);
}
}
}
void play(Ts... x) override { /* ignore - see play_complex */
}
void stop() override {
this->then_.stop();
this->else_.stop();
}
bool is_running() override { return this->then_.is_running() || this->else_.is_running() || this->is_running_next(); }
protected:
Condition<Ts...> *condition_;
ActionList<Ts...> then_;
@ -196,37 +184,40 @@ template<typename... Ts> class WhileAction : public Action<Ts...> {
void add_then(const std::vector<Action<Ts...> *> &actions) {
this->then_.add_actions(actions);
this->then_.add_action(new LambdaAction<Ts...>([this](Ts... x) {
if (this->condition_->check_tuple(this->var_)) {
if (this->num_running_ > 0 && this->condition_->check_tuple(this->var_)) {
// play again
this->then_.play_tuple(this->var_);
if (this->num_running_ > 0) {
this->then_.play_tuple(this->var_);
}
} else {
// condition false, play next
this->play_next_tuple(this->var_);
this->play_next_tuple_(this->var_);
}
}));
}
void play(Ts... x) override { /* ignore - see play_complex */
}
void play_complex(Ts... x) override {
this->num_running_++;
// Store loop parameters
this->var_ = std::make_tuple(x...);
// Initial condition check
if (!this->condition_->check_tuple(this->var_)) {
// If new condition check failed, stop loop if running
this->then_.stop();
this->play_next_tuple(this->var_);
this->play_next_tuple_(this->var_);
return;
}
this->then_.play_tuple(this->var_);
if (this->num_running_ > 0) {
this->then_.play_tuple(this->var_);
}
}
void play(Ts... x) override { /* ignore - see play_complex */
}
void stop() override { this->then_.stop(); }
bool is_running() override { return this->then_.is_running() || this->is_running_next(); }
protected:
Condition<Ts...> *condition_;
ActionList<Ts...> then_;
@ -237,48 +228,44 @@ template<typename... Ts> class WaitUntilAction : public Action<Ts...>, public Co
public:
WaitUntilAction(Condition<Ts...> *condition) : condition_(condition) {}
void play(Ts... x) { /* ignore - see play_complex */
}
void play_complex(Ts... x) override {
this->num_running_++;
// Check if we can continue immediately.
if (this->condition_->check(x...)) {
this->triggered_ = false;
this->play_next(x...);
if (this->num_running_ > 0) {
this->play_next_(x...);
}
return;
}
this->var_ = std::make_tuple(x...);
this->triggered_ = true;
this->loop();
}
void stop() override { this->triggered_ = false; }
void loop() override {
if (!this->triggered_)
if (this->num_running_ == 0)
return;
if (!this->condition_->check_tuple(this->var_)) {
return;
}
this->triggered_ = false;
this->play_next_tuple(this->var_);
this->play_next_tuple_(this->var_);
}
float get_setup_priority() const override { return setup_priority::DATA; }
bool is_running() override { return this->triggered_ || this->is_running_next(); }
void play(Ts... x) override { /* ignore - see play_complex */
}
protected:
Condition<Ts...> *condition_;
bool triggered_{false};
std::tuple<Ts...> var_{};
};
template<typename... Ts> class UpdateComponentAction : public Action<Ts...> {
public:
UpdateComponentAction(PollingComponent *component) : component_(component) {}
void play(Ts... x) override { this->component_->update(); }
protected: