From e3fbbb2e9984f35f7e4fd9d13a0777b9d4c6f036 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 10 Feb 2026 20:45:05 -0600 Subject: [PATCH] [light] Eliminate redundant clamp in LightCall::validate_() After clamp_and_log_if_invalid() clamps the value in-place, the LightColorValues setter's clamp() is guaranteed to be a no-op. For 5 of 9 fields the compiler was inlining the setter's clamp, generating ~18 bytes of redundant float compare + conditional move per field. Use friend access to assign directly to LightColorValues fields, bypassing the setter. Saves ~204 bytes of flash on ESP32. --- esphome/components/light/light_call.cpp | 25 ++++++++++--------- esphome/components/light/light_color_values.h | 2 ++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/esphome/components/light/light_call.cpp b/esphome/components/light/light_call.cpp index 3b4e136ba5..0291b2c3c6 100644 --- a/esphome/components/light/light_call.cpp +++ b/esphome/components/light/light_call.cpp @@ -270,22 +270,23 @@ LightColorValues LightCall::validate_() { if (this->has_state()) v.set_state(this->state_); -#define VALIDATE_AND_APPLY(field, setter, name_str, ...) \ + // clamp_and_log_if_invalid already clamps in-place, so assign directly + // to avoid redundant clamp code from the setter being inlined. +#define VALIDATE_AND_APPLY(field, name_str, ...) \ if (this->has_##field()) { \ clamp_and_log_if_invalid(name, this->field##_, LOG_STR(name_str), ##__VA_ARGS__); \ - v.setter(this->field##_); \ + v.field##_ = this->field##_; \ } - VALIDATE_AND_APPLY(brightness, set_brightness, "Brightness") - VALIDATE_AND_APPLY(color_brightness, set_color_brightness, "Color brightness") - VALIDATE_AND_APPLY(red, set_red, "Red") - VALIDATE_AND_APPLY(green, set_green, "Green") - VALIDATE_AND_APPLY(blue, set_blue, "Blue") - VALIDATE_AND_APPLY(white, set_white, "White") - VALIDATE_AND_APPLY(cold_white, set_cold_white, "Cold white") - VALIDATE_AND_APPLY(warm_white, set_warm_white, "Warm white") - VALIDATE_AND_APPLY(color_temperature, set_color_temperature, "Color temperature", traits.get_min_mireds(), - traits.get_max_mireds()) + VALIDATE_AND_APPLY(brightness, "Brightness") + VALIDATE_AND_APPLY(color_brightness, "Color brightness") + VALIDATE_AND_APPLY(red, "Red") + VALIDATE_AND_APPLY(green, "Green") + VALIDATE_AND_APPLY(blue, "Blue") + VALIDATE_AND_APPLY(white, "White") + VALIDATE_AND_APPLY(cold_white, "Cold white") + VALIDATE_AND_APPLY(warm_white, "Warm white") + VALIDATE_AND_APPLY(color_temperature, "Color temperature", traits.get_min_mireds(), traits.get_max_mireds()) #undef VALIDATE_AND_APPLY diff --git a/esphome/components/light/light_color_values.h b/esphome/components/light/light_color_values.h index 97756b9f26..b26deff0c3 100644 --- a/esphome/components/light/light_color_values.h +++ b/esphome/components/light/light_color_values.h @@ -276,6 +276,8 @@ class LightColorValues { /// Set the warm white property of these light color values. In range 0.0 to 1.0. void set_warm_white(float warm_white) { this->warm_white_ = clamp(warm_white, 0.0f, 1.0f); } + friend class LightCall; + protected: float state_; ///< ON / OFF, float for transition float brightness_;