[select] Eliminate string allocation in state callbacks (#12505)

Co-authored-by: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com>
This commit is contained in:
J. Nick Koston
2025-12-17 15:19:26 -07:00
committed by GitHub
parent dc8f7abce2
commit 91c504061b
5 changed files with 12 additions and 10 deletions

View File

@@ -7,7 +7,7 @@ namespace copy {
static const char *const TAG = "copy.select"; static const char *const TAG = "copy.select";
void CopySelect::setup() { void CopySelect::setup() {
source_->add_on_state_callback([this](const std::string &value, size_t index) { this->publish_state(index); }); source_->add_on_state_callback([this](size_t index) { this->publish_state(index); });
traits.set_options(source_->traits.get_options()); traits.set_options(source_->traits.get_options());

View File

@@ -21,8 +21,7 @@ void MQTTSelectComponent::setup() {
call.set_option(state); call.set_option(state);
call.perform(); call.perform();
}); });
this->select_->add_on_state_callback( this->select_->add_on_state_callback([this](size_t index) { this->publish_state(this->select_->option_at(index)); });
[this](const std::string &state, size_t index) { this->publish_state(this->select_->option_at(index)); });
} }
void MQTTSelectComponent::dump_config() { void MQTTSelectComponent::dump_config() {

View File

@@ -8,9 +8,13 @@ namespace esphome::select {
class SelectStateTrigger : public Trigger<std::string, size_t> { class SelectStateTrigger : public Trigger<std::string, size_t> {
public: public:
explicit SelectStateTrigger(Select *parent) { explicit SelectStateTrigger(Select *parent) : parent_(parent) {
parent->add_on_state_callback([this](const std::string &value, size_t index) { this->trigger(value, index); }); parent->add_on_state_callback(
[this](size_t index) { this->trigger(std::string(this->parent_->option_at(index)), index); });
} }
protected:
Select *parent_;
}; };
template<typename... Ts> class SelectSetAction : public Action<Ts...> { template<typename... Ts> class SelectSetAction : public Action<Ts...> {

View File

@@ -32,8 +32,7 @@ void Select::publish_state(size_t index) {
this->state = option; // Update deprecated member for backward compatibility this->state = option; // Update deprecated member for backward compatibility
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
ESP_LOGD(TAG, "'%s': Sending state %s (index %zu)", this->get_name().c_str(), option, index); ESP_LOGD(TAG, "'%s': Sending state %s (index %zu)", this->get_name().c_str(), option, index);
// Callback signature requires std::string, create temporary for compatibility this->state_callback_.call(index);
this->state_callback_.call(std::string(option), index);
#if defined(USE_SELECT) && defined(USE_CONTROLLER_REGISTRY) #if defined(USE_SELECT) && defined(USE_CONTROLLER_REGISTRY)
ControllerRegistry::notify_select_update(this); ControllerRegistry::notify_select_update(this);
#endif #endif
@@ -41,7 +40,7 @@ void Select::publish_state(size_t index) {
const char *Select::current_option() const { return this->has_state() ? this->option_at(this->active_index_) : ""; } const char *Select::current_option() const { return this->has_state() ? this->option_at(this->active_index_) : ""; }
void Select::add_on_state_callback(std::function<void(std::string, size_t)> &&callback) { void Select::add_on_state_callback(std::function<void(size_t)> &&callback) {
this->state_callback_.add(std::move(callback)); this->state_callback_.add(std::move(callback));
} }

View File

@@ -75,7 +75,7 @@ class Select : public EntityBase {
/// Return the option value at the provided index offset (as const char* from flash). /// Return the option value at the provided index offset (as const char* from flash).
const char *option_at(size_t index) const; const char *option_at(size_t index) const;
void add_on_state_callback(std::function<void(std::string, size_t)> &&callback); void add_on_state_callback(std::function<void(size_t)> &&callback);
protected: protected:
friend class SelectCall; friend class SelectCall;
@@ -111,7 +111,7 @@ class Select : public EntityBase {
} }
} }
CallbackManager<void(std::string, size_t)> state_callback_; CallbackManager<void(size_t)> state_callback_;
}; };
} // namespace esphome::select } // namespace esphome::select