From 27d38baf0defc4cdde8c3c195c04d0c954c680ed Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 22 Mar 2026 16:36:17 -1000 Subject: [PATCH] [binary_sensor] Fix invalidate_state: keep inline on base, hide on BinarySensor invalidate_state() can't be declaration-only on a template class. Keep it inline on StatefulEntityBase, and add a hiding declaration on BinarySensor with an out-of-line definition in the .cpp to prevent template bloat from automation.h and filter.cpp callers. --- esphome/components/binary_sensor/binary_sensor.h | 4 +++- esphome/core/entity_base.h | 4 +--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/esphome/components/binary_sensor/binary_sensor.h b/esphome/components/binary_sensor/binary_sensor.h index 11dccf7c0db..109fdb0f1ad 100644 --- a/esphome/components/binary_sensor/binary_sensor.h +++ b/esphome/components/binary_sensor/binary_sensor.h @@ -57,8 +57,10 @@ class BinarySensor : public StatefulEntityBase { // ========== INTERNAL METHODS ========== // (In most use cases you won't need these) - /// Defined in .cpp to avoid inlining set_new_state template code at every call site. + /// Defined in .cpp to avoid inlining set_new_state_ template code at every call site. void send_state_internal(bool new_state); + /// Hides base class inline version to prevent template bloat from automation.h and filter.cpp callers. + void invalidate_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 de3499a6c32..7cf6804c4cf 100644 --- a/esphome/core/entity_base.h +++ b/esphome/core/entity_base.h @@ -303,7 +303,6 @@ void log_entity_unit_of_measurement(const char *tag, const char *prefix, const E * - set_state_value(): store a new value (called only when the state actually changes) * - get_trigger_on_initial_state() / set_trigger_on_initial_state(): control initial callback behavior * - on_state_changed() (optional override): called after state updates, for logging/notifications - * - invalidate_state(): must be defined out-of-line in subclass .cpp to avoid template bloat * * This class does not store the state value — subclasses own their storage. Whether a state * has been set is tracked by EntityBase::has_state(). @@ -322,8 +321,7 @@ 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. - /// Defined out-of-line in subclass .cpp to avoid inlining set_new_state_ template code at every call site. - void invalidate_state(); + void invalidate_state() { this->set_new_state_({}); } template void add_full_state_callback(F &&callback) { this->full_state_callbacks_.add(std::forward(callback));