From 4fbe82a5041263c2b7a43407423de0ae545d5cc8 Mon Sep 17 00:00:00 2001 From: Vladimir Kozhevnikov Date: Tue, 6 Feb 2024 01:11:15 +0300 Subject: [PATCH] Fixes for CLANG-FORMAT + added Code owner --- CODEOWNERS | 1 + esphome/components/ds3232/ds3232.cpp | 86 ++++++++------------ esphome/components/ds3232/ds3232.h | 30 ++++--- esphome/components/ds3232/ds3232_alarm.cpp | 38 ++------- esphome/components/ds3232/ds3232_alarm.h | 16 ++-- esphome/components/ds3232/ds3232_variables.h | 48 +++++------ 6 files changed, 91 insertions(+), 128 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index db44317776..652560bd66 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -91,6 +91,7 @@ esphome/components/dht/* @OttoWinter esphome/components/display_menu_base/* @numo68 esphome/components/dps310/* @kbx81 esphome/components/ds1307/* @badbadc0ffee +esphome/components/ds3232/* @ViKozh esphome/components/dsmr/* @glmnet @zuidwijk esphome/components/duty_time/* @dudanov esphome/components/ee895/* @Stock-M diff --git a/esphome/components/ds3232/ds3232.cpp b/esphome/components/ds3232/ds3232.cpp index f763db3a5d..0788b1793e 100644 --- a/esphome/components/ds3232/ds3232.cpp +++ b/esphome/components/ds3232/ds3232.cpp @@ -89,7 +89,7 @@ void DS3232Component::setup() { void DS3232Component::update() { - if(this->late_startup_) + if (this->late_startup_) return; this->read_time(); this->read_temperature_(); @@ -103,12 +103,11 @@ float DS3232Component::get_setup_priority() const { return setup_priority::DATA void DS3232Component::reinit_osf_() { this->read_data_(); - if(!this->reg_data_.reg.osf_bit) + if (!this->reg_data_.reg.osf_bit) return; ESP_LOGD(TAG, "Found disabled oscillator. Restarting it."); this->reg_data_.reg.osf_bit = false; - if(!this->write_byte(I2C_REG_STATUS, this->reg_data_.raw_blocks.status_raw[0])) - { + if (!this->write_byte(I2C_REG_STATUS, this->reg_data_.raw_blocks.status_raw[0])) { ESP_LOGE(TAG, "Unable to restart oscillator."); return; } @@ -165,21 +164,19 @@ void DS3232Component::loop() { } this->pin_state_ = pin_state; } - switch (this->nvram_state_) - { - case DS3232NVRAMState::NEED_INITIALIZATION: - if(this->busy_) { - ESP_LOGI(TAG, "Performing planned NVRAM full reset..."); - clear_nvram_(); - } - break; + switch (this->nvram_state_) { + case DS3232NVRAMState::NEED_INITIALIZATION: + if (this->busy_) { + ESP_LOGI(TAG, "Performing planned NVRAM full reset..."); + clear_nvram_(); + } + break; case DS3232NVRAMState::NEED_RESET: - if(this->busy_) { + if (this->busy_) { ESP_LOGI(TAG, "Performing planned NVRAM factory reset..."); this->nvram_state_ = DS3232NVRAMState::OK; this->variable_init_callback_.call(); - if(this->nvram_state_ != DS3232NVRAMState::OK) - { + if (this->nvram_state_ != DS3232NVRAMState::OK) { ESP_LOGE(TAG, "NVRAM: Failed to reset to factory defaults."); } this->busy_ = false; @@ -212,10 +209,9 @@ void DS3232Component::clear_nvram_() { std::vector zeroes; zeroes.resize(write_len_, 0); - while (step < total_size) - { + while (step < total_size) { bool res = false; - if((total_size - step) < write_len) { + if ((total_size - step) < write_len) { res_ = this->write_bytes(MIN_NVRAM_ADDRESS + step_, zeroes.data(), total_size - step_); step += (total_size - step); } else { @@ -226,8 +222,7 @@ void DS3232Component::clear_nvram_() { state &= res; } - if(!state) - { + if (!state) { ESP_LOGE(TAG, "NVRAM: Unable to clear memory. Marking as failed."); this->nvram_state_ = DS3232NVRAMState::FAIL; } else { @@ -237,8 +232,7 @@ void DS3232Component::clear_nvram_() { this->nvram_info_.info.is_initialized = false; this->nvram_info_.info.maj_version = NVRAM_DATA_MAJ_VERSION; this->nvram_info_.info.min_version = NVRAM_DATA_MIN_VERSION; - if(!this->write_bytes(SVC_NVRAM_ADDRESS, this->nvram_info_.raw, sizeof(this->nvram_info_.raw))) - { + if (!this->write_bytes(SVC_NVRAM_ADDRESS, this->nvram_info_.raw, sizeof(this->nvram_info_.raw))) { ESP_LOGE(TAG, "NVRAM: Unable to write service NVRAM information. Marking as failed."); this->nvram_state_ = DS3232NVRAMState::FAIL; } @@ -247,8 +241,7 @@ void DS3232Component::clear_nvram_() { ESP_LOGD(TAG, "NVRAM: Variables has been initialized. Saving state."); this->nvram_info_.info.is_initialized = true; - if(!this->write_bytes(SVC_NVRAM_ADDRESS, this->nvram_info_.raw, sizeof(this->nvram_info_.raw))) - { + if (!this->write_bytes(SVC_NVRAM_ADDRESS, this->nvram_info_.raw, sizeof(this->nvram_info_.raw))) { ESP_LOGE(TAG, "NVRAM: Unable to write service NVRAM information. Marking as failed."); this->nvram_state_ = DS3232NVRAMState::FAIL; } @@ -267,7 +260,7 @@ bool DS3232Component::validate_mem_(uint8_t reg_id, uint8_t size, bool ignore_em } void DS3232Component::reset_memory() { - if(this->nvram_state_ == DS3232NVRAMState::INITIALIZATION) { + if (this->nvram_state_ == DS3232NVRAMState::INITIALIZATION) { ESP_LOGW(TAG, "NVRAM: Another memory reset process in progress already."); return; } @@ -276,7 +269,7 @@ void DS3232Component::reset_memory() { } void DS3232Component::reset_to_factory() { - if(this->nvram_state_ == DS3232NVRAMState::INITIALIZATION) { + if (this->nvram_state_ == DS3232NVRAMState::INITIALIZATION) { ESP_LOGW(TAG, "NVRAM: Another memory reset process in progress already."); return; } @@ -285,11 +278,11 @@ void DS3232Component::reset_to_factory() { } bool DS3232Component::read_memory(uint8_t reg_id, std::vector &data) { - if(this->nvram_state_ == DS3232NVRAMState::INITIALIZATION) { + if (this->nvram_state_ == DS3232NVRAMState::INITIALIZATION) { ESP_LOGW(TAG, "NVRAM: Memory reset process in progress. Try later."); return false; } - if(data.size() == 0) { + if (data.size() == 0) { ESP_LOGW(TAG, "NVRAM: Nothing to write to memory."); return true; } @@ -297,36 +290,33 @@ bool DS3232Component::read_memory(uint8_t reg_id, std::vector &data) { ESP_LOGE(TAG, "Invalid NVRAM memory mapping."); return false; } else { - if(!this->read_bytes(reg_id, data.data(), data.size())) { - ESP_LOGE(TAG, "NVRAM: Unable to read from %#02x register with size %u.", reg_id, data.size()); + if (!this->read_bytes(reg_id, data.data(), data.size())) { + ESP_LOGE(TAG, "NVRAM: Unable to read from %#02x register with size %u.", reg_id, data.size()); this->nvram_state_ = DS3232NVRAMState::FAIL; return false; }; - ESP_LOGD(TAG, "NVRAM: Value read from %#02x register with size %u.", reg_id, data.size()); + ESP_LOGD(TAG, "NVRAM: Value read from %#02x register with size %u.", reg_id, data.size()); return true; } } -bool DS3232Component::write_memory(const uint8_t reg_id, const std::vector &data) -{ - if(data.size() == 0) { +bool DS3232Component::write_memory(const uint8_t reg_id, const std::vector &data) { + if (data.size() == 0) { ESP_LOGW(TAG, "NVRAM: Nothing to write to memory."); return true; } - if(this->nvram_state_ == DS3232NVRAMState::INITIALIZATION) { + if (this->nvram_state_ == DS3232NVRAMState::INITIALIZATION) { ESP_LOGW(TAG, "NVRAM: Memory reset process in progress. Try later."); return false; } - if(!this->validate_mem_(reg_id, data.size(), true)) - { + if (!this->validate_mem_(reg_id, data.size(), true)) { ESP_LOGE(TAG, "Invalid NVRAM memory mapping."); return false; } - if(!this->write_bytes(reg_id, data)) - { + if (!this->write_bytes(reg_id, data)) { ESP_LOGE(TAG, "NVRAM: Unable to write to %#02x register with size %u.", reg_id, data.size()); this->nvram_state_ = DS3232NVRAMState::FAIL; return false; @@ -481,12 +471,9 @@ ds3232_alarm::DS3232Alarm DS3232Component::get_alarm_one() { ds3232_alarm::DS3232Alarm alarm = {}; alarm.enabled = reg_data_.reg.alarm_1_enable; alarm.seconds_supported = true; - alarm.mode = ds3232_alarm::DS3232Alarm::alarm_mode( - reg_data_.reg.alarm_1_mode_1, - reg_data_.reg.alarm_1_mode_2, - reg_data_.reg.alarm_1_mode_3, - reg_data_.reg.alarm_1_mode_4, - reg_data_.reg.alarm_1_use_day_of_week); + alarm.mode = ds3232_alarm::DS3232Alarm::alarm_mode(reg_data_.reg.alarm_1_mode_1, reg_data_.reg.alarm_1_mode_2, + reg_data_.reg.alarm_1_mode_3, reg_data_.reg.alarm_1_mode_4, + reg_data_.reg.alarm_1_use_day_of_week); alarm.second = reg_data_.reg.alarm_1_second + 10u * reg_data_.reg.alarm_1_second_10; alarm.minute = reg_data_.reg.alarm_1_minute + 10u * reg_data_.reg.alarm_1_minute_10; alarm.hour = reg_data_.reg.alarm_1_hour + 10u * reg_data_.reg.alarm_1_hour_10; @@ -508,12 +495,9 @@ ds3232_alarm::DS3232Alarm DS3232Component::get_alarm_two() { ds3232_alarm::DS3232Alarm alarm = {}; alarm.enabled = reg_data_.reg.alarm_2_enable; alarm.seconds_supported = false; - alarm.mode = ds3232_alarm::DS3232Alarm::alarm_mode( - false, - reg_data_.reg.alarm_2_mode_2, - reg_data_.reg.alarm_2_mode_3, - reg_data_.reg.alarm_2_mode_4, - reg_data_.reg.alarm_2_use_day_of_week); + alarm.mode = + ds3232_alarm::DS3232Alarm::alarm_mode(false, reg_data_.reg.alarm_2_mode_2, reg_data_.reg.alarm_2_mode_3, + reg_data_.reg.alarm_2_mode_4, reg_data_.reg.alarm_2_use_day_of_week); alarm.second = 0; alarm.minute = reg_data_.reg.alarm_2_minute + 10u * reg_data_.reg.alarm_2_minute_10; alarm.hour = reg_data_.reg.alarm_2_hour + 10u * reg_data_.reg.alarm_2_hour_10; diff --git a/esphome/components/ds3232/ds3232.h b/esphome/components/ds3232/ds3232.h index 9de58fb494..421ae42595 100644 --- a/esphome/components/ds3232/ds3232.h +++ b/esphome/components/ds3232/ds3232.h @@ -85,11 +85,11 @@ class DS3232Component : public time::RealTimeClock, public i2c::I2CDevice { /// @brief Perform full memory reinitialization. All available /// memory registers will be set to zeroes. /// This could help if memory structure is corrupted or faulty. - void reset_memory(); // Action + void reset_memory(); // Action /// @brief Sets all 'configuration' variables to their initial values. - void reset_to_factory(); // Action - void set_alarm_one(const ds3232_alarm::DS3232Alarm &alarm); // Action - void set_alarm_two(const ds3232_alarm::DS3232Alarm &alarm); // Action + void reset_to_factory(); // Action + void set_alarm_one(const ds3232_alarm::DS3232Alarm &alarm); // Action + void set_alarm_two(const ds3232_alarm::DS3232Alarm &alarm); // Action ds3232_alarm::DS3232Alarm get_alarm_one(); ds3232_alarm::DS3232Alarm get_alarm_two(); void clear_alarm_one(); @@ -111,8 +111,12 @@ class DS3232Component : public time::RealTimeClock, public i2c::I2CDevice { void add_on_power_change_callback(std::function &&func) { this->power_state_callback_.add(std::move(func)); } - void add_on_variable_init_required_callback(std::function &&func) { this->variable_init_callback_.add(std::move(func)); } - void add_on_variable_fail_callback(std::function &&func) { this->variable_fail_callback_.add(std::move(func)); } + void add_on_variable_init_required_callback(std::function &&func) { + this->variable_init_callback_.add(std::move(func)); + } + void add_on_variable_fail_callback(std::function &&func) { + this->variable_fail_callback_.add(std::move(func)); + } bool read_memory(uint8_t reg_id, std::vector &data); bool write_memory(uint8_t reg_id, const std::vector &data); bool is_valid_nvram(const uint8_t reg_id, uint8_t size) { return this->validate_mem_(reg_id, size, true); } @@ -151,9 +155,9 @@ class DS3232Component : public time::RealTimeClock, public i2c::I2CDevice { union DS3232NVRAMData { struct { - uint8_t magix_1 : 2; //Always should be 0b11; - uint8_t magix_2 : 6; //Always should be 'E' char. - bool is_initialized : 1; //If set to 1 then it means that nvram has initialized values. + uint8_t magix_1 : 2; // Always should be 0b11; + uint8_t magix_2 : 6; // Always should be 'E' char. + bool is_initialized : 1; // If set to 1 then it means that nvram has initialized values. uint8_t min_version : 3; uint8_t maj_version : 4; } info; @@ -292,13 +296,13 @@ class PowerStateEvent : public Trigger { }; template class FactoryResetNVRAMAction : public Action, public Parented { - public: - void play(Ts... x) override { this->parent_->reset_to_factory(); } + public: + void play(Ts... x) override { this->parent_->reset_to_factory(); } }; template class EraseNVRAMAction : public Action, public Parented { - public: - void play(Ts... x) override { this->parent_->reset_memory(); } + public: + void play(Ts... x) override { this->parent_->reset_memory(); } }; template class WriteAction : public Action, public Parented { diff --git a/esphome/components/ds3232/ds3232_alarm.cpp b/esphome/components/ds3232/ds3232_alarm.cpp index b582ee49b4..f82b412aa1 100644 --- a/esphome/components/ds3232/ds3232_alarm.cpp +++ b/esphome/components/ds3232/ds3232_alarm.cpp @@ -32,13 +32,6 @@ static const char *const FORMAT_STRING_INVALID = INVALID; // So, the recommended formatted_string length initialization: 128 symbols (35 * 3 (105) growed to 2^x(128)) static const size_t DS3232_ALARM_FORMAT_STRING_LENGTH = 128; -/// Converts alarm match bits to mode -// static AlarmMode bits_to_mode(bool use_week, bool match_day, bool match_hour, bool match_min, bool match_sec = false) { -// uint8_t mode_bits = -// 0x00001 * match_sec + 0x00010 * match_min + 0x00100 * match_hour + 0x01000 * match_day + 0x10000 * use_week; -// return static_cast(mode_bits); -// }; - DS3232AlarmMode DS3232Alarm::alarm_mode(const AlarmMode mode) { DS3232AlarmMode am = {}; am.alarm_mode = mode; @@ -46,12 +39,12 @@ DS3232AlarmMode DS3232Alarm::alarm_mode(const AlarmMode mode) { }; DS3232AlarmMode DS3232Alarm::alarm_mode(const bool bit_seconds, const bool bit_minutes, const bool bit_hours, - const bool bit_days, const bool use_weekdays) { + const bool bit_days, const bool use_weekdays) { bool weekdays_bit = use_weekdays && !(bit_seconds || bit_minutes || bit_hours); - uint8_t mode_bits = 0b00001 * bit_seconds + 0b00010 * bit_minutes + 0b00100 * bit_hours + 0b01000 * bit_days + - 0b10000 * weekdays_bit; - ESP_LOGVV(TAG, "Converted alarm mode from %.1u, %.1u, %.1u, %.1u, %.1u to bits %.2u", - bit_seconds, bit_minutes, bit_hours, bit_days, use_weekdays, mode_bits); + uint8_t mode_bits = + 0b00001 * bit_seconds + 0b00010 * bit_minutes + 0b00100 * bit_hours + 0b01000 * bit_days + 0b10000 * weekdays_bit; + ESP_LOGVV(TAG, "Converted alarm mode from %.1u, %.1u, %.1u, %.1u, %.1u to bits %.2u", bit_seconds, bit_minutes, + bit_hours, bit_days, use_weekdays, mode_bits); return DS3232Alarm::alarm_mode(static_cast(mode_bits)); }; @@ -66,21 +59,9 @@ bool DS3232Alarm::is_valid() const { } DS3232Alarm DS3232Alarm::create(const bool is_enabled, const DS3232AlarmMode mode, const bool use_weekdays, - const uint8_t day, const uint8_t hour, const uint8_t minute, - const uint8_t second, const bool is_fired, - const bool is_seconds_supported) -{ + const uint8_t day, const uint8_t hour, const uint8_t minute, const uint8_t second, + const bool is_fired, const bool is_seconds_supported) { DS3232Alarm alarm = {}; - // .enabled = is_enabled, - // .seconds_supported = is_seconds_supported, - // .mode = mode, - // .second = second, - // .minute = minute, - // .hour = hour, - // .day_of_week = (use_weekdays ? day : 1), - // .day_of_month = (use_weekdays ? 1 : day), - // .is_fired = is_fired - // }; ESP_LOGVV(TAG, "Initializing new instance of alarm:"); alarm.enabled = is_enabled; ESP_LOGVV(TAG, " Alarm state: %s", ONOFF(alarm.enabled)); @@ -105,7 +86,7 @@ DS3232Alarm DS3232Alarm::create(const bool is_enabled, const DS3232AlarmMode mod std::string DS3232Alarm::to_string() const { if (!this->is_valid()) - return std::string(INVALID); + return std::string(INVALID); char formatted_string[DS3232_ALARM_FORMAT_STRING_LENGTH]; size_t len; switch (this->mode.alarm_mode) { @@ -125,8 +106,7 @@ std::string DS3232Alarm::to_string() const { return std::string(formatted_string); case AlarmMode::MATCH_MINUTES_SECONDS: case 28: - len = - snprintf(formatted_string, sizeof(formatted_string), FORMAT_STRING_EVERY_HOUR, this->minute, this->second); + len = snprintf(formatted_string, sizeof(formatted_string), FORMAT_STRING_EVERY_HOUR, this->minute, this->second); if (len < 0) { ESP_LOGE(TAG, "Unable to format alarm data."); return std::string(INVALID); diff --git a/esphome/components/ds3232/ds3232_alarm.h b/esphome/components/ds3232/ds3232_alarm.h index c5590f71a6..ae536c241a 100644 --- a/esphome/components/ds3232/ds3232_alarm.h +++ b/esphome/components/ds3232/ds3232_alarm.h @@ -90,21 +90,19 @@ struct DS3232Alarm { /// Formats alarm into human-readable text. /// @return Textual description of alarm. -std::string to_string() const; + std::string to_string() const; /// @brief Sets target alarm mode /// @param target_mode Mode of alarm to set void set_mode(AlarmMode target_mode) { mode.alarm_mode = target_mode; } -static DS3232AlarmMode alarm_mode(AlarmMode mode); -static DS3232AlarmMode alarm_mode(bool bit_seconds = false, bool bit_minutes = false, - bool bit_hours = false, bool bit_days = false, - bool use_weekdays = false); + static DS3232AlarmMode alarm_mode(AlarmMode mode); + static DS3232AlarmMode alarm_mode(bool bit_seconds = false, bool bit_minutes = false, bool bit_hours = false, + bool bit_days = false, bool use_weekdays = false); -static DS3232Alarm create(bool is_enabled, DS3232AlarmMode mode, bool use_weekdays = true, - uint8_t day = 1, uint8_t hour = 0, uint8_t minute = 0, - uint8_t second = 0, bool is_fired = false, - bool is_seconds_supported = false); + static DS3232Alarm create(bool is_enabled, DS3232AlarmMode mode, bool use_weekdays = true, uint8_t day = 1, + uint8_t hour = 0, uint8_t minute = 0, uint8_t second = 0, bool is_fired = false, + bool is_seconds_supported = false); }; } // namespace ds3232_alarm diff --git a/esphome/components/ds3232/ds3232_variables.h b/esphome/components/ds3232/ds3232_variables.h index 28e9d5352d..fe8d9b9e60 100644 --- a/esphome/components/ds3232/ds3232_variables.h +++ b/esphome/components/ds3232/ds3232_variables.h @@ -23,7 +23,8 @@ template class DS3232Variable : public Component { parent_ = parent; } - explicit DS3232Variable(DS3232Component *parent, const uint8_t reg_id, T initial_value) : initial_value_(initial_value) { + explicit DS3232Variable(DS3232Component *parent, const uint8_t reg_id, T initial_value) + : initial_value_(initial_value) { reg_ = reg_id; parent_ = parent; } @@ -48,33 +49,32 @@ template class DS3232Variable : public Component { DS3232NVRAMState nvram_state_ = this->parent_->get_nvram_state(); - while(nvram_state_ != DS3232NVRAMState::OK) - { - if(nvram_state_ == DS3232NVRAMState::FAIL) - { + while (nvram_state_ != DS3232NVRAMState::OK) { + if (nvram_state_ == DS3232NVRAMState::FAIL) { this->log_error_("Unable to init with failed NVRAM."); this->mark_failed(); break; } - if(nvram_state_ == DS3232NVRAMState::NEED_RESET) - { + if (nvram_state_ == DS3232NVRAMState::NEED_RESET) { this->set_to_default_(); } delay_microseconds_safe(10); nvram_state_ = this->parent_->get_nvram_state(); } - if(!this->try_read_()) { + if (!this->try_read_()) { this->mark_failed_(); } else { this->is_initialized_ = true; } } - float get_setup_priority() const override { return this->parent_->get_setup_priority() - 0.5f; } //Ensure that variables will be initialized after ds3232 component. + float get_setup_priority() const override { + return this->parent_->get_setup_priority() - 0.5f; + } // Ensure that variables will be initialized after ds3232 component. void loop() override { - if(!this->try_write_()) + if (!this->try_write_()) this->mark_failed_(); } @@ -92,14 +92,14 @@ template class DS3232Variable : public Component { bool is_initialized_{false}; std::va_list llist_{}; - void log_error_(const char* log_str) { - #ifdef USE_LOGGER - auto *log = logger::global_logger; - if (log == nullptr) - return; + void log_error_(const char *log_str) { +#ifdef USE_LOGGER + auto *log = logger::global_logger; + if (log == nullptr) + return; - log->log_vprintf_(ESPHOME_LOG_LEVEL_ERROR, TAG, __LINE__, log_str, this->llist_); - #endif + log->log_vprintf_(ESPHOME_LOG_LEVEL_ERROR, TAG, __LINE__, log_str, this->llist_); +#endif } void mark_failed_() { @@ -113,8 +113,7 @@ template class DS3232Variable : public Component { std::vector buffer; buffer.resize(sizeof(T)); memcpy(buffer.data(), &this->initial_value_, sizeof(T)); - if(!this->parent_->write_memory(this->reg_, buffer)) - { + if (!this->parent_->write_memory(this->reg_, buffer)) { this->mark_failed_(); } else { memcpy(&this->value_, &this->initial_value_, sizeof(T)); @@ -153,8 +152,7 @@ template class DS3232Variable : public Component { this->log_error_("No crystal defined. Read from NVRAM failed."); return false; } - if (this->parent_->get_nvram_state() != ds3232::DS3232NVRAMState::OK) - { + if (this->parent_->get_nvram_state() != ds3232::DS3232NVRAMState::OK) { this->log_error_("Invalid NVRAM state. Unable to read data."); return false; } @@ -173,8 +171,8 @@ template class DS3232Variable : public Component { }; template T &id(DS3232Variable *value) { - value->try_read_(); - return value->value(); + value->try_read_(); + return value->value(); } template class DS3232VariableSetAction : public Action { @@ -185,9 +183,7 @@ template class DS3232VariableSetAction : public Action< TEMPLATABLE_VALUE(T, value); - void play(Ts... x) override { - this->parent_->value() = this->value_.value(x...); - } + void play(Ts... x) override { this->parent_->value() = this->value_.value(x...); } protected: C *parent_;