1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-14 17:22:20 +01:00

Optimize memory usage by lazy-allocating raw callbacks in sensors

This commit is contained in:
J. Nick Koston
2025-06-14 11:37:11 -05:00
parent ee37d2f9c8
commit 0de2696543
4 changed files with 25 additions and 8 deletions

View File

@@ -21,6 +21,7 @@ std::string state_class_to_string(StateClass state_class) {
}
Sensor::Sensor() : state(NAN), raw_state(NAN) {}
Sensor::~Sensor() { delete this->raw_callback_; }
int8_t Sensor::get_accuracy_decimals() {
if (this->accuracy_decimals_.has_value())
@@ -38,7 +39,9 @@ StateClass Sensor::get_state_class() {
void Sensor::publish_state(float state) {
this->raw_state = state;
this->raw_callback_.call(state);
if (this->raw_callback_ != nullptr) {
this->raw_callback_->call(state);
}
ESP_LOGV(TAG, "'%s': Received new state %f", this->name_.c_str(), state);
@@ -51,7 +54,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_raw_state_callback(std::function<void(float)> &&callback) {
this->raw_callback_.add(std::move(callback));
if (this->raw_callback_ == nullptr) {
this->raw_callback_ = new CallbackManager<void(float)>(); // NOLINT
}
this->raw_callback_->add(std::move(callback));
}
void Sensor::add_filter(Filter *filter) {

View File

@@ -61,6 +61,7 @@ std::string state_class_to_string(StateClass state_class);
class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBase_UnitOfMeasurement {
public:
explicit Sensor();
~Sensor();
/// Get the accuracy in decimals, using the manual override if set.
int8_t get_accuracy_decimals();
@@ -152,8 +153,8 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
void internal_send_state_to_frontend(float state);
protected:
CallbackManager<void(float)> raw_callback_; ///< Storage for raw state callbacks.
CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
CallbackManager<void(float)> *raw_callback_{nullptr}; ///< Storage for raw state callbacks (lazy allocated).
CallbackManager<void(float)> callback_; ///< Storage for filtered state callbacks.
Filter *filter_list_{nullptr}; ///< Store all active filters.

View File

@@ -6,9 +6,13 @@ namespace text_sensor {
static const char *const TAG = "text_sensor";
TextSensor::~TextSensor() { delete this->raw_callback_; }
void TextSensor::publish_state(const std::string &state) {
this->raw_state = state;
this->raw_callback_.call(state);
if (this->raw_callback_ != nullptr) {
this->raw_callback_->call(state);
}
ESP_LOGV(TAG, "'%s': Received new state %s", this->name_.c_str(), state.c_str());
@@ -53,7 +57,10 @@ void TextSensor::add_on_state_callback(std::function<void(std::string)> callback
this->callback_.add(std::move(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_ == nullptr) {
this->raw_callback_ = new CallbackManager<void(std::string)>(); // NOLINT
}
this->raw_callback_->add(std::move(callback));
}
std::string TextSensor::get_state() const { return this->state; }

View File

@@ -33,6 +33,9 @@ namespace text_sensor {
class TextSensor : public EntityBase, public EntityBase_DeviceClass {
public:
TextSensor() = default;
~TextSensor();
/// Getter-syntax for .state.
std::string get_state() const;
/// Getter-syntax for .raw_state
@@ -72,8 +75,8 @@ class TextSensor : public EntityBase, public EntityBase_DeviceClass {
void internal_send_state_to_frontend(const std::string &state);
protected:
CallbackManager<void(std::string)> raw_callback_; ///< Storage for raw state callbacks.
CallbackManager<void(std::string)> callback_; ///< Storage for filtered state callbacks.
CallbackManager<void(std::string)> *raw_callback_{nullptr}; ///< 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.