mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 08:55:36 +00:00
[binary_sensor] Reduce flash: cache get_state(), guard full_state_callbacks call
- Cache get_state() result to avoid calling the virtual method twice (once for comparison, once for old_state construction) - Move full_state_callbacks_.call() inside the !empty() guard so both the optional construction and the call are skipped when no callbacks - Swap to had_state || get_trigger_on_initial_state() so the virtual call is skipped on the common path (every change except the first) Saves ~21 bytes of flash in set_new_state.
This commit is contained in:
@@ -347,24 +347,29 @@ template<typename T> class StatefulEntityBase : public EntityBase {
|
||||
virtual bool set_new_state(const optional<T> &new_state) {
|
||||
// Access flags_ directly to avoid function call overhead in this hot path
|
||||
bool had_state = this->flags_.has_state;
|
||||
// Cache get_state() result to avoid calling the virtual method twice
|
||||
T current{};
|
||||
if (had_state)
|
||||
current = this->get_state();
|
||||
if (new_state.has_value()) {
|
||||
if (had_state && this->get_state() == new_state.value())
|
||||
if (had_state && current == new_state.value())
|
||||
return false; // same value, no change
|
||||
} else if (!had_state) {
|
||||
return false; // already invalidated, no change
|
||||
}
|
||||
// State changed — update storage before firing callbacks so callback code
|
||||
// can inspect the entity's current state via get_state()/has_state()
|
||||
// Only construct old_state optional when full_state_callbacks need it
|
||||
optional<T> old_state;
|
||||
if (!this->full_state_callbacks_.empty())
|
||||
old_state = had_state ? optional<T>(this->get_state()) : nullopt;
|
||||
this->flags_.has_state = new_state.has_value();
|
||||
if (new_state.has_value()) {
|
||||
this->set_state_value(new_state.value());
|
||||
}
|
||||
this->full_state_callbacks_.call(old_state, new_state);
|
||||
if (new_state.has_value() && (this->get_trigger_on_initial_state() || had_state))
|
||||
// Only construct old_state and call full_state_callbacks when callbacks are registered
|
||||
if (!this->full_state_callbacks_.empty()) {
|
||||
optional<T> old_state = had_state ? optional<T>(current) : nullopt;
|
||||
this->full_state_callbacks_.call(old_state, new_state);
|
||||
}
|
||||
// had_state first: on every change except the first, skips the virtual call
|
||||
if (new_state.has_value() && (had_state || this->get_trigger_on_initial_state()))
|
||||
this->state_callbacks_.call(new_state.value());
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user