mirror of
https://github.com/esphome/esphome.git
synced 2026-09-04 03:56:04 +00:00
[binary_sensor] Reduce flash: un-inline send_state_internal, optimize set_new_state
Move send_state_internal back to .cpp to avoid duplicating it at each call site (publish_state and Filter::output). Optimize set_new_state to compare has_state + value directly instead of constructing optional<T> on stack for the comparison. Optionals are only constructed in the changed path for callbacks that need them.
This commit is contained in:
@@ -32,6 +32,7 @@ void BinarySensor::publish_initial_state(bool new_state) {
|
||||
this->invalidate_state();
|
||||
this->publish_state(new_state);
|
||||
}
|
||||
void BinarySensor::send_state_internal(bool new_state) { this->set_new_state(new_state); }
|
||||
|
||||
bool BinarySensor::set_new_state(const optional<bool> &new_state) {
|
||||
if (StatefulEntityBase::set_new_state(new_state)) {
|
||||
|
||||
@@ -57,7 +57,7 @@ class BinarySensor : public StatefulEntityBase<bool> {
|
||||
|
||||
// ========== INTERNAL METHODS ==========
|
||||
// (In most use cases you won't need these)
|
||||
void send_state_internal(bool new_state) { this->set_new_state(new_state); }
|
||||
void send_state_internal(bool new_state);
|
||||
|
||||
/// Return whether this binary sensor has outputted a state.
|
||||
virtual bool is_status_binary_sensor() const;
|
||||
|
||||
+18
-12
@@ -343,19 +343,25 @@ template<typename T> class StatefulEntityBase : public EntityBase {
|
||||
* Returns true if the state actually changed, false if it was the same.
|
||||
*/
|
||||
virtual bool set_new_state(const optional<T> &new_state) {
|
||||
optional<T> old_state = this->has_state() ? optional<T>(this->get_state()) : nullopt;
|
||||
if (old_state != new_state) {
|
||||
this->full_state_callbacks_.call(old_state, new_state);
|
||||
auto had_state = this->has_state();
|
||||
this->set_has_state(new_state.has_value());
|
||||
if (new_state.has_value()) {
|
||||
this->set_state_value_(new_state.value());
|
||||
if (this->get_trigger_on_initial_state() || had_state)
|
||||
this->state_callbacks_.call(new_state.value());
|
||||
}
|
||||
return true;
|
||||
// Compare without constructing optional — avoid unnecessary codegen
|
||||
bool had_state = this->has_state();
|
||||
if (new_state.has_value()) {
|
||||
if (had_state && this->get_state() == new_state.value())
|
||||
return false; // same value, no change
|
||||
} else {
|
||||
if (!had_state)
|
||||
return false; // already invalidated, no change
|
||||
}
|
||||
return false;
|
||||
// State changed — construct optionals only for callbacks that need them
|
||||
optional<T> old_state = had_state ? optional<T>(this->get_state()) : nullopt;
|
||||
this->full_state_callbacks_.call(old_state, new_state);
|
||||
this->set_has_state(new_state.has_value());
|
||||
if (new_state.has_value()) {
|
||||
this->set_state_value_(new_state.value());
|
||||
if (this->get_trigger_on_initial_state() || had_state)
|
||||
this->state_callbacks_.call(new_state.value());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/// Subclasses implement this to store the actual value into their own storage.
|
||||
virtual void set_state_value_(const T &value) = 0;
|
||||
|
||||
Reference in New Issue
Block a user