mirror of
https://github.com/esphome/esphome.git
synced 2026-09-20 19:48:39 +00:00
Use leak-on-purpose raw pointers for Climate-owned vectors
Climate entities live for the entire program lifetime, so the custom mode vectors never need to be freed. Use raw pointers (null by default, allocated on first set_supported_custom_*() call) instead of inline std::vector members. This saves 48 bytes of RAM per Climate instance (two empty vectors) for components that don't use custom modes (bang_bang, pid, etc.), and avoids any copy overhead in get_traits().
This commit is contained in:
@@ -485,10 +485,10 @@ void Climate::publish_state() {
|
||||
ClimateTraits Climate::get_traits() {
|
||||
auto traits = this->traits();
|
||||
// Wire custom mode pointers from Climate-owned storage
|
||||
if (!this->supported_custom_fan_modes_.empty())
|
||||
traits.set_supported_custom_fan_modes(&this->supported_custom_fan_modes_);
|
||||
if (!this->supported_custom_presets_.empty())
|
||||
traits.set_supported_custom_presets(&this->supported_custom_presets_);
|
||||
if (this->supported_custom_fan_modes_)
|
||||
traits.set_supported_custom_fan_modes(this->supported_custom_fan_modes_);
|
||||
if (this->supported_custom_presets_)
|
||||
traits.set_supported_custom_presets(this->supported_custom_presets_);
|
||||
#ifdef USE_CLIMATE_VISUAL_OVERRIDES
|
||||
if (!std::isnan(this->visual_min_temperature_override_)) {
|
||||
traits.set_visual_min_temperature(this->visual_min_temperature_override_);
|
||||
@@ -706,7 +706,8 @@ const char *Climate::find_custom_fan_mode_(const char *custom_fan_mode) {
|
||||
}
|
||||
|
||||
const char *Climate::find_custom_fan_mode_(const char *custom_fan_mode, size_t len) {
|
||||
return vector_find(this->supported_custom_fan_modes_, custom_fan_mode, len);
|
||||
return this->supported_custom_fan_modes_ ? vector_find(*this->supported_custom_fan_modes_, custom_fan_mode, len)
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
const char *Climate::find_custom_preset_(const char *custom_preset) {
|
||||
@@ -714,7 +715,7 @@ const char *Climate::find_custom_preset_(const char *custom_preset) {
|
||||
}
|
||||
|
||||
const char *Climate::find_custom_preset_(const char *custom_preset, size_t len) {
|
||||
return vector_find(this->supported_custom_presets_, custom_preset, len);
|
||||
return this->supported_custom_presets_ ? vector_find(*this->supported_custom_presets_, custom_preset, len) : nullptr;
|
||||
}
|
||||
|
||||
void Climate::dump_traits_(const char *tag) {
|
||||
|
||||
@@ -236,24 +236,37 @@ class Climate : public EntityBase {
|
||||
|
||||
/// Set the supported custom fan modes (stored on Climate, referenced by ClimateTraits).
|
||||
void set_supported_custom_fan_modes(std::initializer_list<const char *> modes) {
|
||||
this->supported_custom_fan_modes_ = modes;
|
||||
if (!this->supported_custom_fan_modes_)
|
||||
this->supported_custom_fan_modes_ =
|
||||
new std::vector<const char *>(); // NOLINT - intentional leak, entity lives forever
|
||||
*this->supported_custom_fan_modes_ = modes;
|
||||
}
|
||||
void set_supported_custom_fan_modes(const std::vector<const char *> &modes) {
|
||||
this->supported_custom_fan_modes_ = modes;
|
||||
if (!this->supported_custom_fan_modes_)
|
||||
this->supported_custom_fan_modes_ = new std::vector<const char *>(); // NOLINT
|
||||
*this->supported_custom_fan_modes_ = modes;
|
||||
}
|
||||
template<size_t N> void set_supported_custom_fan_modes(const char *const (&modes)[N]) {
|
||||
this->supported_custom_fan_modes_.assign(modes, modes + N);
|
||||
if (!this->supported_custom_fan_modes_)
|
||||
this->supported_custom_fan_modes_ = new std::vector<const char *>(); // NOLINT
|
||||
this->supported_custom_fan_modes_->assign(modes, modes + N);
|
||||
}
|
||||
|
||||
/// Set the supported custom presets (stored on Climate, referenced by ClimateTraits).
|
||||
void set_supported_custom_presets(std::initializer_list<const char *> presets) {
|
||||
this->supported_custom_presets_ = presets;
|
||||
if (!this->supported_custom_presets_)
|
||||
this->supported_custom_presets_ = new std::vector<const char *>(); // NOLINT
|
||||
*this->supported_custom_presets_ = presets;
|
||||
}
|
||||
void set_supported_custom_presets(const std::vector<const char *> &presets) {
|
||||
this->supported_custom_presets_ = presets;
|
||||
if (!this->supported_custom_presets_)
|
||||
this->supported_custom_presets_ = new std::vector<const char *>(); // NOLINT
|
||||
*this->supported_custom_presets_ = presets;
|
||||
}
|
||||
template<size_t N> void set_supported_custom_presets(const char *const (&presets)[N]) {
|
||||
this->supported_custom_presets_.assign(presets, presets + N);
|
||||
if (!this->supported_custom_presets_)
|
||||
this->supported_custom_presets_ = new std::vector<const char *>(); // NOLINT
|
||||
this->supported_custom_presets_->assign(presets, presets + N);
|
||||
}
|
||||
|
||||
/// Check if a custom fan mode is currently active.
|
||||
@@ -366,11 +379,11 @@ class Climate : public EntityBase {
|
||||
LazyCallbackManager<void(ClimateCall &)> control_callback_{};
|
||||
ESPPreferenceObject rtc_;
|
||||
|
||||
/** Custom mode storage - owned by Climate, referenced by ClimateTraits via pointer.
|
||||
/** Custom mode storage — allocated on first use, never freed (entity lives forever).
|
||||
* Pointers in these vectors must point to string literals or static data.
|
||||
*/
|
||||
std::vector<const char *> supported_custom_fan_modes_;
|
||||
std::vector<const char *> supported_custom_presets_;
|
||||
std::vector<const char *> *supported_custom_fan_modes_{nullptr};
|
||||
std::vector<const char *> *supported_custom_presets_{nullptr};
|
||||
|
||||
#ifdef USE_CLIMATE_VISUAL_OVERRIDES
|
||||
float visual_min_temperature_override_{NAN};
|
||||
|
||||
Reference in New Issue
Block a user