[nextion] Optimize component memory usage with bitfield state management (#9373)

This commit is contained in:
Edward Firmo 2025-07-07 23:21:14 +02:00 committed by GitHub
parent 42a1f6922f
commit c4fac1a2ae
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 85 additions and 50 deletions

View File

@ -44,7 +44,7 @@ void NextionBinarySensor::set_state(bool state, bool publish, bool send_to_nexti
return;
if (send_to_nextion) {
if (this->nextion_->is_sleeping() || !this->visible_) {
if (this->nextion_->is_sleeping() || !this->component_flags_.visible) {
this->needs_to_send_update_ = true;
} else {
this->needs_to_send_update_ = false;

View File

@ -8,8 +8,8 @@ void NextionComponent::set_background_color(Color bco) {
return; // This is a variable. no need to set color
}
this->bco_ = bco;
this->bco_needs_update_ = true;
this->bco_is_set_ = true;
this->component_flags_.bco_needs_update = true;
this->component_flags_.bco_is_set = true;
this->update_component_settings();
}
@ -19,8 +19,8 @@ void NextionComponent::set_background_pressed_color(Color bco2) {
}
this->bco2_ = bco2;
this->bco2_needs_update_ = true;
this->bco2_is_set_ = true;
this->component_flags_.bco2_needs_update = true;
this->component_flags_.bco2_is_set = true;
this->update_component_settings();
}
@ -29,8 +29,8 @@ void NextionComponent::set_foreground_color(Color pco) {
return; // This is a variable. no need to set color
}
this->pco_ = pco;
this->pco_needs_update_ = true;
this->pco_is_set_ = true;
this->component_flags_.pco_needs_update = true;
this->component_flags_.pco_is_set = true;
this->update_component_settings();
}
@ -39,8 +39,8 @@ void NextionComponent::set_foreground_pressed_color(Color pco2) {
return; // This is a variable. no need to set color
}
this->pco2_ = pco2;
this->pco2_needs_update_ = true;
this->pco2_is_set_ = true;
this->component_flags_.pco2_needs_update = true;
this->component_flags_.pco2_is_set = true;
this->update_component_settings();
}
@ -49,8 +49,8 @@ void NextionComponent::set_font_id(uint8_t font_id) {
return; // This is a variable. no need to set color
}
this->font_id_ = font_id;
this->font_id_needs_update_ = true;
this->font_id_is_set_ = true;
this->component_flags_.font_id_needs_update = true;
this->component_flags_.font_id_is_set = true;
this->update_component_settings();
}
@ -58,20 +58,20 @@ void NextionComponent::set_visible(bool visible) {
if (this->variable_name_ == this->variable_name_to_send_) {
return; // This is a variable. no need to set color
}
this->visible_ = visible;
this->visible_needs_update_ = true;
this->visible_is_set_ = true;
this->component_flags_.visible = visible;
this->component_flags_.visible_needs_update = true;
this->component_flags_.visible_is_set = true;
this->update_component_settings();
}
void NextionComponent::update_component_settings(bool force_update) {
if (this->nextion_->is_sleeping() || !this->nextion_->is_setup() || !this->visible_is_set_ ||
(!this->visible_needs_update_ && !this->visible_)) {
if (this->nextion_->is_sleeping() || !this->nextion_->is_setup() || !this->component_flags_.visible_is_set ||
(!this->component_flags_.visible_needs_update && !this->component_flags_.visible)) {
this->needs_to_send_update_ = true;
return;
}
if (this->visible_needs_update_ || (force_update && this->visible_is_set_)) {
if (this->component_flags_.visible_needs_update || (force_update && this->component_flags_.visible_is_set)) {
std::string name_to_send = this->variable_name_;
size_t pos = name_to_send.find_last_of('.');
@ -79,9 +79,9 @@ void NextionComponent::update_component_settings(bool force_update) {
name_to_send = name_to_send.substr(pos + 1);
}
this->visible_needs_update_ = false;
this->component_flags_.visible_needs_update = false;
if (this->visible_) {
if (this->component_flags_.visible) {
this->nextion_->show_component(name_to_send.c_str());
this->send_state_to_nextion();
} else {
@ -90,26 +90,26 @@ void NextionComponent::update_component_settings(bool force_update) {
}
}
if (this->bco_needs_update_ || (force_update && this->bco2_is_set_)) {
if (this->component_flags_.bco_needs_update || (force_update && this->component_flags_.bco2_is_set)) {
this->nextion_->set_component_background_color(this->variable_name_.c_str(), this->bco_);
this->bco_needs_update_ = false;
this->component_flags_.bco_needs_update = false;
}
if (this->bco2_needs_update_ || (force_update && this->bco2_is_set_)) {
if (this->component_flags_.bco2_needs_update || (force_update && this->component_flags_.bco2_is_set)) {
this->nextion_->set_component_pressed_background_color(this->variable_name_.c_str(), this->bco2_);
this->bco2_needs_update_ = false;
this->component_flags_.bco2_needs_update = false;
}
if (this->pco_needs_update_ || (force_update && this->pco_is_set_)) {
if (this->component_flags_.pco_needs_update || (force_update && this->component_flags_.pco_is_set)) {
this->nextion_->set_component_foreground_color(this->variable_name_.c_str(), this->pco_);
this->pco_needs_update_ = false;
this->component_flags_.pco_needs_update = false;
}
if (this->pco2_needs_update_ || (force_update && this->pco2_is_set_)) {
if (this->component_flags_.pco2_needs_update || (force_update && this->component_flags_.pco2_is_set)) {
this->nextion_->set_component_pressed_foreground_color(this->variable_name_.c_str(), this->pco2_);
this->pco2_needs_update_ = false;
this->component_flags_.pco2_needs_update = false;
}
if (this->font_id_needs_update_ || (force_update && this->font_id_is_set_)) {
if (this->component_flags_.font_id_needs_update || (force_update && this->component_flags_.font_id_is_set)) {
this->nextion_->set_component_font(this->variable_name_.c_str(), this->font_id_);
this->font_id_needs_update_ = false;
this->component_flags_.font_id_needs_update = false;
}
}
} // namespace nextion

View File

@ -21,29 +21,64 @@ class NextionComponent : public NextionComponentBase {
void set_visible(bool visible);
protected:
/**
* @brief Constructor initializes component state with visible=true (default state)
*/
NextionComponent() {
component_flags_ = {}; // Zero-initialize all state
component_flags_.visible = 1; // Set default visibility to true
}
NextionBase *nextion_;
bool bco_needs_update_ = false;
bool bco_is_set_ = false;
Color bco_;
bool bco2_needs_update_ = false;
bool bco2_is_set_ = false;
Color bco2_;
bool pco_needs_update_ = false;
bool pco_is_set_ = false;
Color pco_;
bool pco2_needs_update_ = false;
bool pco2_is_set_ = false;
Color pco2_;
// Color and styling properties
Color bco_; // Background color
Color bco2_; // Pressed background color
Color pco_; // Foreground color
Color pco2_; // Pressed foreground color
uint8_t font_id_ = 0;
bool font_id_needs_update_ = false;
bool font_id_is_set_ = false;
bool visible_ = true;
bool visible_needs_update_ = false;
bool visible_is_set_ = false;
/**
* @brief Component state management using compact bitfield structure
*
* Stores all component state flags and properties in a single 16-bit bitfield
* for efficient memory usage and improved cache locality.
*
* Each component property maintains two state flags:
* - needs_update: Indicates the property requires synchronization with the display
* - is_set: Tracks whether the property has been explicitly configured
*
* The visible field stores both the update flags and the actual visibility state.
*/
struct ComponentState {
// Background color flags
uint16_t bco_needs_update : 1;
uint16_t bco_is_set : 1;
// void send_state_to_nextion() = 0;
// Pressed background color flags
uint16_t bco2_needs_update : 1;
uint16_t bco2_is_set : 1;
// Foreground color flags
uint16_t pco_needs_update : 1;
uint16_t pco_is_set : 1;
// Pressed foreground color flags
uint16_t pco2_needs_update : 1;
uint16_t pco2_is_set : 1;
// Font ID flags
uint16_t font_id_needs_update : 1;
uint16_t font_id_is_set : 1;
// Visibility flags
uint16_t visible_needs_update : 1;
uint16_t visible_is_set : 1;
uint16_t visible : 1; // Actual visibility state
// Reserved bits for future expansion
uint16_t reserved : 3;
} component_flags_;
};
} // namespace nextion
} // namespace esphome

View File

@ -53,7 +53,7 @@ void NextionSensor::set_state(float state, bool publish, bool send_to_nextion) {
if (this->wave_chan_id_ == UINT8_MAX) {
if (send_to_nextion) {
if (this->nextion_->is_sleeping() || !this->visible_) {
if (this->nextion_->is_sleeping() || !this->component_flags_.visible) {
this->needs_to_send_update_ = true;
} else {
this->needs_to_send_update_ = false;

View File

@ -28,7 +28,7 @@ void NextionSwitch::set_state(bool state, bool publish, bool send_to_nextion) {
return;
if (send_to_nextion) {
if (this->nextion_->is_sleeping() || !this->visible_) {
if (this->nextion_->is_sleeping() || !this->component_flags_.visible) {
this->needs_to_send_update_ = true;
} else {
this->needs_to_send_update_ = false;

View File

@ -26,7 +26,7 @@ void NextionTextSensor::set_state(const std::string &state, bool publish, bool s
return;
if (send_to_nextion) {
if (this->nextion_->is_sleeping() || !this->visible_) {
if (this->nextion_->is_sleeping() || !this->component_flags_.visible) {
this->needs_to_send_update_ = true;
} else {
this->nextion_->add_no_result_to_queue_with_set(this, state);