mirror of
https://github.com/esphome/esphome.git
synced 2026-09-24 21:44:04 +00:00
[core] Inline ContinuationAction in If/While/RepeatAction (#16040)
This commit is contained in:
@@ -273,18 +273,32 @@ template<typename... Ts> class WhileLoopContinuation : public Action<Ts...> {
|
||||
WhileAction<Ts...> *parent_;
|
||||
};
|
||||
|
||||
// Wraps a ContinuationAction when Enabled, empty otherwise.
|
||||
// Lets IfAction elide the else continuation when HasElse is false.
|
||||
template<bool Enabled, typename... Ts> struct OptionalContinuation {
|
||||
ContinuationAction<Ts...> action;
|
||||
explicit OptionalContinuation(Action<Ts...> *parent) : action(parent) {}
|
||||
};
|
||||
template<typename... Ts> struct OptionalContinuation<false, Ts...> {
|
||||
explicit OptionalContinuation(Action<Ts...> * /*parent*/) {}
|
||||
};
|
||||
|
||||
template<bool HasElse, typename... Ts> class IfAction : public Action<Ts...> {
|
||||
public:
|
||||
explicit IfAction(Condition<Ts...> *condition) : condition_(condition) {}
|
||||
|
||||
// Precondition: add_then/add_else must be called at most once per instance.
|
||||
// Codegen always batches the full action list into a single call. Calling
|
||||
// twice would re-append the same inline continuation pointer and form a
|
||||
// self-loop in the next_ chain.
|
||||
void add_then(const std::initializer_list<Action<Ts...> *> &actions) {
|
||||
this->then_.add_actions(actions);
|
||||
this->then_.add_action(new ContinuationAction<Ts...>(this));
|
||||
this->then_.add_action(&this->then_continuation_);
|
||||
}
|
||||
|
||||
void add_else(const std::initializer_list<Action<Ts...> *> &actions) requires(HasElse) {
|
||||
this->else_.add_actions(actions);
|
||||
this->else_.add_action(new ContinuationAction<Ts...>(this));
|
||||
this->else_.add_action(&this->else_continuation_.action);
|
||||
}
|
||||
|
||||
void play_complex(const Ts &...x) override {
|
||||
@@ -316,17 +330,20 @@ template<bool HasElse, typename... Ts> class IfAction : public Action<Ts...> {
|
||||
protected:
|
||||
Condition<Ts...> *condition_;
|
||||
ActionList<Ts...> then_;
|
||||
ContinuationAction<Ts...> then_continuation_{this};
|
||||
struct NoElse {};
|
||||
[[no_unique_address]] std::conditional_t<HasElse, ActionList<Ts...>, NoElse> else_;
|
||||
[[no_unique_address]] OptionalContinuation<HasElse, Ts...> else_continuation_{this};
|
||||
};
|
||||
|
||||
template<typename... Ts> class WhileAction : public Action<Ts...> {
|
||||
public:
|
||||
WhileAction(Condition<Ts...> *condition) : condition_(condition) {}
|
||||
|
||||
// Precondition: must be called at most once per instance (see IfAction::add_then).
|
||||
void add_then(const std::initializer_list<Action<Ts...> *> &actions) {
|
||||
this->then_.add_actions(actions);
|
||||
this->then_.add_action(new WhileLoopContinuation<Ts...>(this));
|
||||
this->then_.add_action(&this->loop_continuation_);
|
||||
}
|
||||
|
||||
friend class WhileLoopContinuation<Ts...>;
|
||||
@@ -354,6 +371,7 @@ template<typename... Ts> class WhileAction : public Action<Ts...> {
|
||||
protected:
|
||||
Condition<Ts...> *condition_;
|
||||
ActionList<Ts...> then_;
|
||||
WhileLoopContinuation<Ts...> loop_continuation_{this};
|
||||
};
|
||||
|
||||
// Implementation of WhileLoopContinuation::play
|
||||
@@ -386,9 +404,10 @@ template<typename... Ts> class RepeatAction : public Action<Ts...> {
|
||||
public:
|
||||
TEMPLATABLE_VALUE(uint32_t, count)
|
||||
|
||||
// Precondition: must be called at most once per instance (see IfAction::add_then).
|
||||
void add_then(const std::initializer_list<Action<uint32_t, Ts...> *> &actions) {
|
||||
this->then_.add_actions(actions);
|
||||
this->then_.add_action(new RepeatLoopContinuation<Ts...>(this));
|
||||
this->then_.add_action(&this->loop_continuation_);
|
||||
}
|
||||
|
||||
friend class RepeatLoopContinuation<Ts...>;
|
||||
@@ -409,6 +428,7 @@ template<typename... Ts> class RepeatAction : public Action<Ts...> {
|
||||
|
||||
protected:
|
||||
ActionList<uint32_t, Ts...> then_;
|
||||
RepeatLoopContinuation<Ts...> loop_continuation_{this};
|
||||
};
|
||||
|
||||
// Implementation of RepeatLoopContinuation::play
|
||||
|
||||
Reference in New Issue
Block a user