diff --git a/esphome/components/binary_sensor/binary_sensor.cpp b/esphome/components/binary_sensor/binary_sensor.cpp index 564cb48f64..fe7e169fea 100644 --- a/esphome/components/binary_sensor/binary_sensor.cpp +++ b/esphome/components/binary_sensor/binary_sensor.cpp @@ -32,6 +32,10 @@ void BinarySensor::publish_initial_state(bool new_state) { this->invalidate_state(); this->publish_state(new_state); } +// Defined out-of-line to prevent set_new_state template from being inlined at each call site, +// which would duplicate ~189 bytes of template code per caller (publish_state, Filter::output, etc.) +void BinarySensor::send_state_internal(bool new_state) { this->set_new_state(new_state); } +void BinarySensor::invalidate_state() { this->set_new_state({}); } void BinarySensor::on_state_changed_(const optional &old_state, const optional &new_state, bool had_state) { StatefulEntityBase::on_state_changed_(old_state, new_state, had_state); diff --git a/esphome/components/binary_sensor/binary_sensor.h b/esphome/components/binary_sensor/binary_sensor.h index 31e8f92b96..7cd8a44a0f 100644 --- a/esphome/components/binary_sensor/binary_sensor.h +++ b/esphome/components/binary_sensor/binary_sensor.h @@ -57,7 +57,8 @@ class BinarySensor : public StatefulEntityBase { // ========== INTERNAL METHODS ========== // (In most use cases you won't need these) - void send_state_internal(bool new_state) { this->set_new_state(new_state); } + /// Defined in .cpp to avoid inlining set_new_state template code at every call site. + void send_state_internal(bool new_state); /// Return whether this binary sensor has outputted a state. virtual bool is_status_binary_sensor() const; diff --git a/esphome/core/entity_base.h b/esphome/core/entity_base.h index b6785a9aab..202f386234 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -320,7 +320,8 @@ template class StatefulEntityBase : public EntityBase { /// Return the current state if available, otherwise return the provided default. T get_state_default(T default_value) const { return this->has_state() ? this->get_state() : default_value; } /// Clear the state — sets has_state() to false and fires callbacks with nullopt. - void invalidate_state() { this->set_new_state({}); } + /// Defined out-of-line in subclass .cpp to avoid inlining set_new_state template code at every call site. + void invalidate_state(); template void add_full_state_callback(F &&callback) { this->full_state_callbacks_.add(std::forward(callback));