[light] Use constexpr template parameter for ToggleAction transition_length

Parameterize ToggleAction on a HasTransitionLength bool, mirroring the
IfAction<HasElse> pattern. When transition_length is not configured in
YAML, the TemplatableFn field is elided via [[no_unique_address]] and
LightCall::set_transition_length is skipped via if constexpr.

Saves 4 bytes RAM per toggle action instance and shrinks play() from
79 to 28 bytes when transition_length is unused.
This commit is contained in:
J. Nick Koston
2026-04-26 21:13:58 -05:00
parent e87e78c544
commit 0cebb9014f
2 changed files with 14 additions and 5 deletions
+10 -3
View File
@@ -8,20 +8,27 @@ namespace esphome::light {
enum class LimitMode { CLAMP, DO_NOTHING };
template<typename... Ts> class ToggleAction : public Action<Ts...> {
template<bool HasTransitionLength, typename... Ts> class ToggleAction : public Action<Ts...> {
public:
explicit ToggleAction(LightState *state) : state_(state) {}
TEMPLATABLE_VALUE(uint32_t, transition_length)
template<typename V> void set_transition_length(V value) requires(HasTransitionLength) {
this->transition_length_ = value;
}
void play(const Ts &...x) override {
auto call = this->state_->toggle();
call.set_transition_length(this->transition_length_.optional_value(x...));
if constexpr (HasTransitionLength) {
call.set_transition_length(this->transition_length_.optional_value(x...));
}
call.perform();
}
protected:
LightState *state_;
struct NoTransition {};
[[no_unique_address]] std::conditional_t<HasTransitionLength, TemplatableFn<uint32_t, Ts...>, NoTransition>
transition_length_{};
};
template<typename... Ts> class LightControlAction : public Action<Ts...> {
+4 -2
View File
@@ -60,8 +60,10 @@ from .types import (
)
async def light_toggle_to_code(config, action_id, template_arg, args):
paren = await cg.get_variable(config[CONF_ID])
var = cg.new_Pvariable(action_id, template_arg, paren)
if CONF_TRANSITION_LENGTH in config:
has_transition_length = CONF_TRANSITION_LENGTH in config
toggle_template_arg = cg.TemplateArguments(has_transition_length, *template_arg)
var = cg.new_Pvariable(action_id, toggle_template_arg, paren)
if has_transition_length:
template_ = await cg.templatable(
config[CONF_TRANSITION_LENGTH], args, cg.uint32
)