Optimize memory usage by lazy-allocating raw callbacks in sensors (#9077)

This commit is contained in:
J. Nick Koston 2025-06-14 22:28:15 -05:00 committed by GitHub
parent 4305c44440
commit cb019fff9a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 23 additions and 8 deletions

View File

@ -38,7 +38,9 @@ StateClass Sensor::get_state_class() {
void Sensor::publish_state(float state) { void Sensor::publish_state(float state) {
this->raw_state = state; this->raw_state = state;
this->raw_callback_.call(state); if (this->raw_callback_) {
this->raw_callback_->call(state);
}
ESP_LOGV(TAG, "'%s': Received new state %f", this->name_.c_str(), state); ESP_LOGV(TAG, "'%s': Received new state %f", this->name_.c_str(), state);
@ -51,7 +53,10 @@ void Sensor::publish_state(float state) {
void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); } void Sensor::add_on_state_callback(std::function<void(float)> &&callback) { this->callback_.add(std::move(callback)); }
void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) { void Sensor::add_on_raw_state_callback(std::function<void(float)> &&callback) {
this->raw_callback_.add(std::move(callback)); if (!this->raw_callback_) {
this->raw_callback_ = std::make_unique<CallbackManager<void(float)>>();
}
this->raw_callback_->add(std::move(callback));
} }
void Sensor::add_filter(Filter *filter) { void Sensor::add_filter(Filter *filter) {

View File

@ -7,6 +7,7 @@
#include "esphome/components/sensor/filter.h" #include "esphome/components/sensor/filter.h"
#include <vector> #include <vector>
#include <memory>
namespace esphome { namespace esphome {
namespace sensor { namespace sensor {
@ -149,8 +150,8 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
void internal_send_state_to_frontend(float state); void internal_send_state_to_frontend(float state);
protected: protected:
CallbackManager<void(float)> raw_callback_; ///< Storage for raw state callbacks. std::unique_ptr<CallbackManager<void(float)>> raw_callback_; ///< Storage for raw state callbacks (lazy allocated).
CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks. CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
Filter *filter_list_{nullptr}; ///< Store all active filters. Filter *filter_list_{nullptr}; ///< Store all active filters.

View File

@ -8,7 +8,9 @@ static const char *const TAG = "text_sensor";
void TextSensor::publish_state(const std::string &state) { void TextSensor::publish_state(const std::string &state) {
this->raw_state = state; this->raw_state = state;
this->raw_callback_.call(state); if (this->raw_callback_) {
this->raw_callback_->call(state);
}
ESP_LOGV(TAG, "'%s': Received new state %s", this->name_.c_str(), state.c_str()); ESP_LOGV(TAG, "'%s': Received new state %s", this->name_.c_str(), state.c_str());
@ -53,7 +55,10 @@ void TextSensor::add_on_state_callback(std::function<void(std::string)> callback
this->callback_.add(std::move(callback)); this->callback_.add(std::move(callback));
} }
void TextSensor::add_on_raw_state_callback(std::function<void(std::string)> callback) { void TextSensor::add_on_raw_state_callback(std::function<void(std::string)> callback) {
this->raw_callback_.add(std::move(callback)); if (!this->raw_callback_) {
this->raw_callback_ = std::make_unique<CallbackManager<void(std::string)>>();
}
this->raw_callback_->add(std::move(callback));
} }
std::string TextSensor::get_state() const { return this->state; } std::string TextSensor::get_state() const { return this->state; }

View File

@ -6,6 +6,7 @@
#include "esphome/components/text_sensor/filter.h" #include "esphome/components/text_sensor/filter.h"
#include <vector> #include <vector>
#include <memory>
namespace esphome { namespace esphome {
namespace text_sensor { namespace text_sensor {
@ -33,6 +34,8 @@ namespace text_sensor {
class TextSensor : public EntityBase, public EntityBase_DeviceClass { class TextSensor : public EntityBase, public EntityBase_DeviceClass {
public: public:
TextSensor() = default;
/// Getter-syntax for .state. /// Getter-syntax for .state.
std::string get_state() const; std::string get_state() const;
/// Getter-syntax for .raw_state /// Getter-syntax for .raw_state
@ -70,8 +73,9 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass {
void internal_send_state_to_frontend(const std::string &state); void internal_send_state_to_frontend(const std::string &state);
protected: protected:
CallbackManager<void(std::string)> raw_callback_; ///< Storage for raw state callbacks. std::unique_ptr<CallbackManager<void(std::string)>>
CallbackManager<void(std::string)> callback_; ///< Storage for filtered state callbacks. raw_callback_; ///< Storage for raw state callbacks (lazy allocated).
CallbackManager<void(std::string)> callback_; ///< Storage for filtered state callbacks.
Filter *filter_list_{nullptr}; ///< Store all active filters. Filter *filter_list_{nullptr}; ///< Store all active filters.
}; };