mirror of
https://github.com/esphome/esphome.git
synced 2026-09-15 17:18:40 +00:00
Use leak-on-purpose raw pointer for Fan-owned preset modes vector
Fan entities live for the entire program lifetime, so the preset modes vector never needs to be freed. Use a raw pointer (null by default, allocated on first set_supported_preset_modes() call) instead of an inline std::vector member. This saves 24 bytes of RAM per Fan instance for components that don't use preset modes (binary, bedjet, tuya, etc.).
This commit is contained in:
@@ -148,9 +148,9 @@ const char *Fan::find_preset_mode_(const char *preset_mode) {
|
||||
}
|
||||
|
||||
const char *Fan::find_preset_mode_(const char *preset_mode, size_t len) {
|
||||
if (preset_mode == nullptr || len == 0)
|
||||
if (preset_mode == nullptr || len == 0 || !this->supported_preset_modes_)
|
||||
return nullptr;
|
||||
for (const char *mode : this->supported_preset_modes_) {
|
||||
for (const char *mode : *this->supported_preset_modes_) {
|
||||
if (strncmp(mode, preset_mode, len) == 0 && mode[len] == '\0')
|
||||
return mode;
|
||||
}
|
||||
@@ -274,10 +274,10 @@ void Fan::save_state_() {
|
||||
state.direction = this->direction;
|
||||
state.preset_mode = FanRestoreState::NO_PRESET;
|
||||
|
||||
if (this->has_preset_mode()) {
|
||||
if (this->has_preset_mode() && this->supported_preset_modes_) {
|
||||
// Find index of current preset mode (pointer comparison is safe since preset is from our vector)
|
||||
for (size_t i = 0; i < this->supported_preset_modes_.size(); i++) {
|
||||
if (this->supported_preset_modes_[i] == this->preset_mode_) {
|
||||
for (size_t i = 0; i < this->supported_preset_modes_->size(); i++) {
|
||||
if ((*this->supported_preset_modes_)[i] == this->preset_mode_) {
|
||||
state.preset_mode = i;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -132,10 +132,15 @@ class Fan : public EntityBase {
|
||||
|
||||
/// Set the supported preset modes (stored on Fan, referenced by FanTraits via pointer).
|
||||
void set_supported_preset_modes(std::initializer_list<const char *> preset_modes) {
|
||||
this->supported_preset_modes_ = preset_modes;
|
||||
if (!this->supported_preset_modes_)
|
||||
this->supported_preset_modes_ =
|
||||
new std::vector<const char *>(); // NOLINT - intentional leak, entity lives forever
|
||||
*this->supported_preset_modes_ = preset_modes;
|
||||
}
|
||||
void set_supported_preset_modes(const std::vector<const char *> &preset_modes) {
|
||||
this->supported_preset_modes_ = preset_modes;
|
||||
if (!this->supported_preset_modes_)
|
||||
this->supported_preset_modes_ = new std::vector<const char *>(); // NOLINT
|
||||
*this->supported_preset_modes_ = preset_modes;
|
||||
}
|
||||
|
||||
/// Set the restore mode of this fan.
|
||||
@@ -179,8 +184,8 @@ class Fan : public EntityBase {
|
||||
ESPPreferenceObject rtc_;
|
||||
FanRestoreMode restore_mode_;
|
||||
|
||||
/// Preset mode storage — owned by Fan, referenced by FanTraits via pointer.
|
||||
std::vector<const char *> supported_preset_modes_;
|
||||
/// Preset mode storage — allocated on first use, never freed (entity lives forever).
|
||||
std::vector<const char *> *supported_preset_modes_{nullptr};
|
||||
|
||||
private:
|
||||
const char *preset_mode_{nullptr};
|
||||
|
||||
Reference in New Issue
Block a user