mirror of
https://github.com/esphome/esphome.git
synced 2026-06-01 17:57:37 +08:00
[automation] Remove actions_end_ pointer from ActionList to save RAM (#15283)
This commit is contained in:
+21
-18
@@ -419,44 +419,48 @@ template<typename... Ts> class Action {
|
|||||||
template<typename... Ts> class ActionList {
|
template<typename... Ts> class ActionList {
|
||||||
public:
|
public:
|
||||||
void add_action(Action<Ts...> *action) {
|
void add_action(Action<Ts...> *action) {
|
||||||
if (this->actions_end_ == nullptr) {
|
// Walk to end of chain - action lists are short and only built during setup()
|
||||||
this->actions_begin_ = action;
|
Action<Ts...> **tail = &this->actions_;
|
||||||
} else {
|
while (*tail != nullptr)
|
||||||
this->actions_end_->next_ = action;
|
tail = &(*tail)->next_;
|
||||||
}
|
*tail = action;
|
||||||
this->actions_end_ = action;
|
|
||||||
}
|
}
|
||||||
void add_actions(const std::initializer_list<Action<Ts...> *> &actions) {
|
void add_actions(const std::initializer_list<Action<Ts...> *> &actions) {
|
||||||
|
// Find tail once, then append all actions in a single pass
|
||||||
|
Action<Ts...> **tail = &this->actions_;
|
||||||
|
while (*tail != nullptr)
|
||||||
|
tail = &(*tail)->next_;
|
||||||
for (auto *action : actions) {
|
for (auto *action : actions) {
|
||||||
this->add_action(action);
|
*tail = action;
|
||||||
|
tail = &action->next_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Force-inline: part of the Trigger→Automation→ActionList forwarding
|
// Force-inline: part of the Trigger→Automation→ActionList forwarding
|
||||||
// chain collapsed to reduce automation call stack depth.
|
// chain collapsed to reduce automation call stack depth.
|
||||||
inline void play(const Ts &...x) ESPHOME_ALWAYS_INLINE {
|
inline void play(const Ts &...x) ESPHOME_ALWAYS_INLINE {
|
||||||
if (this->actions_begin_ != nullptr)
|
if (this->actions_ != nullptr)
|
||||||
this->actions_begin_->play_complex(x...);
|
this->actions_->play_complex(x...);
|
||||||
}
|
}
|
||||||
void play_tuple(const std::tuple<Ts...> &tuple) {
|
void play_tuple(const std::tuple<Ts...> &tuple) {
|
||||||
this->play_tuple_(tuple, std::make_index_sequence<sizeof...(Ts)>{});
|
this->play_tuple_(tuple, std::make_index_sequence<sizeof...(Ts)>{});
|
||||||
}
|
}
|
||||||
void stop() {
|
void stop() {
|
||||||
if (this->actions_begin_ != nullptr)
|
if (this->actions_ != nullptr)
|
||||||
this->actions_begin_->stop_complex();
|
this->actions_->stop_complex();
|
||||||
}
|
}
|
||||||
bool empty() const { return this->actions_begin_ == nullptr; }
|
bool empty() const { return this->actions_ == nullptr; }
|
||||||
|
|
||||||
/// Check if any action in this action list is currently running.
|
/// Check if any action in this action list is currently running.
|
||||||
bool is_running() {
|
bool is_running() {
|
||||||
if (this->actions_begin_ == nullptr)
|
if (this->actions_ == nullptr)
|
||||||
return false;
|
return false;
|
||||||
return this->actions_begin_->is_running();
|
return this->actions_->is_running();
|
||||||
}
|
}
|
||||||
/// Return the number of actions in this action list that are currently running.
|
/// Return the number of actions in this action list that are currently running.
|
||||||
int num_running() {
|
int num_running() {
|
||||||
if (this->actions_begin_ == nullptr)
|
if (this->actions_ == nullptr)
|
||||||
return 0;
|
return 0;
|
||||||
return this->actions_begin_->num_running_total();
|
return this->actions_->num_running_total();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -464,8 +468,7 @@ template<typename... Ts> class ActionList {
|
|||||||
this->play(std::get<S>(tuple)...);
|
this->play(std::get<S>(tuple)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
Action<Ts...> *actions_begin_{nullptr};
|
Action<Ts...> *actions_{nullptr};
|
||||||
Action<Ts...> *actions_end_{nullptr};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename... Ts> class Automation {
|
template<typename... Ts> class Automation {
|
||||||
|
|||||||
Reference in New Issue
Block a user