Simplify save_state_ compat path, move CopyFan preset copy to setup()

- save_state_(): split into two clear branches instead of conditional
  FanTraits construction trick
- CopyFan: copy source preset modes once in setup() instead of on
  every get_traits() call
This commit is contained in:
J. Nick Koston
2026-03-26 15:39:29 -10:00
parent 3328423373
commit 7c259d2f64
2 changed files with 25 additions and 11 deletions
+8 -2
View File
@@ -7,6 +7,12 @@ namespace copy {
static const char *const TAG = "copy.fan";
void CopyFan::setup() {
// Copy preset modes once from source fan — stored on Fan base class
auto source_traits = source_->get_traits();
if (source_traits.supports_preset_modes()) {
this->set_supported_preset_modes(source_traits.supported_preset_modes());
}
source_->add_on_state_callback([this]() {
this->copy_state_from_source_();
this->publish_state();
@@ -39,8 +45,8 @@ fan::FanTraits CopyFan::get_traits() {
traits.set_speed(base.supports_speed());
traits.set_supported_speed_count(base.supported_speed_count());
traits.set_direction(base.supports_direction());
// Preset modes are wired from source fan's storage via get_traits()
this->set_supported_preset_modes(base.supported_preset_modes());
// Preset modes are set once in setup() and wired via wire_preset_modes_()
this->wire_preset_modes_(traits);
return traits;
}
+17 -9
View File
@@ -297,15 +297,23 @@ void Fan::save_state_() {
state.preset_mode = FanRestoreState::NO_PRESET;
if (this->has_preset_mode()) {
// Use Fan-owned vector, or fall back to traits for deprecated path.
// Keep traits alive so the reference to compat_preset_modes_ doesn't dangle.
auto traits = this->supported_preset_modes_ ? FanTraits() : this->get_traits();
const auto &preset_modes =
this->supported_preset_modes_ ? *this->supported_preset_modes_ : traits.supported_preset_modes();
for (size_t i = 0; i < preset_modes.size(); i++) {
if (preset_modes[i] == this->preset_mode_) {
state.preset_mode = i;
break;
if (this->supported_preset_modes_) {
// New path: search Fan-owned vector directly
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;
}
}
} else {
// Compat: fall back to traits for deprecated path. Remove in 2026.11.0.
auto traits = this->get_traits();
const auto &preset_modes = traits.supported_preset_modes();
for (size_t i = 0; i < preset_modes.size(); i++) {
if (preset_modes[i] == this->preset_mode_) {
state.preset_mode = i;
break;
}
}
}
}