From 185c1dec43d397c61d5b7568286518d34b5244a5 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Wed, 19 Nov 2025 22:24:00 -0600 Subject: [PATCH] cleanup --- esphome/components/api/api_server.cpp | 81 ++++++++++++--------------- esphome/components/api/api_server.h | 7 +++ 2 files changed, 42 insertions(+), 46 deletions(-) diff --git a/esphome/components/api/api_server.cpp b/esphome/components/api/api_server.cpp index aac45804b8..3b073038c6 100644 --- a/esphome/components/api/api_server.cpp +++ b/esphome/components/api/api_server.cpp @@ -431,72 +431,61 @@ void APIServer::handle_action_response(uint32_t call_id, bool success, const std #endif // USE_API_HOMEASSISTANT_SERVICES #ifdef USE_API_HOMEASSISTANT_STATES -// New const char* overload (for internal components - zero allocation) -void APIServer::subscribe_home_assistant_state(const char *entity_id, const char *attribute, - std::function f) { +// Helper to add subscription (reduces duplication) +void APIServer::add_state_subscription_(const char *entity_id, const char *attribute, + std::function f, bool once) { this->state_subs_.push_back(HomeAssistantStateSubscription{ .entity_id_ = entity_id, .attribute_ = attribute, .callback_ = std::move(f), - .once_ = false, + .once_ = once, .has_attribute_ = (attribute != nullptr), // entity_id_copy_ and attribute_copy_ remain nullptr (no heap allocation) }); } +// Helper to add subscription with heap-allocated strings (reduces duplication) +void APIServer::add_state_subscription_(std::string entity_id, optional attribute, + std::function f, bool once) { + HomeAssistantStateSubscription sub; + // Allocate heap storage for the strings + sub.entity_id_copy_ = std::make_unique(std::move(entity_id)); + sub.entity_id_ = sub.entity_id_copy_->c_str(); + + if (attribute.has_value()) { + sub.attribute_copy_ = std::make_unique(std::move(attribute.value())); + sub.attribute_ = sub.attribute_copy_->c_str(); + sub.has_attribute_ = true; + } else { + sub.attribute_ = nullptr; + sub.has_attribute_ = false; + } + + sub.callback_ = std::move(f); + sub.once_ = once; + this->state_subs_.push_back(std::move(sub)); +} + +// New const char* overload (for internal components - zero allocation) +void APIServer::subscribe_home_assistant_state(const char *entity_id, const char *attribute, + std::function f) { + this->add_state_subscription_(entity_id, attribute, std::move(f), false); +} + void APIServer::get_home_assistant_state(const char *entity_id, const char *attribute, std::function f) { - this->state_subs_.push_back(HomeAssistantStateSubscription{ - .entity_id_ = entity_id, - .attribute_ = attribute, - .callback_ = std::move(f), - .once_ = true, - .has_attribute_ = (attribute != nullptr), - // entity_id_copy_ and attribute_copy_ remain nullptr (no heap allocation) - }); + this->add_state_subscription_(entity_id, attribute, std::move(f), true); } // Existing std::string overload (for custom_api_device.h - heap allocation) void APIServer::subscribe_home_assistant_state(std::string entity_id, optional attribute, std::function f) { - HomeAssistantStateSubscription sub; - // Allocate heap storage for the strings - sub.entity_id_copy_ = std::make_unique(std::move(entity_id)); - sub.entity_id_ = sub.entity_id_copy_->c_str(); - - if (attribute.has_value()) { - sub.attribute_copy_ = std::make_unique(std::move(attribute.value())); - sub.attribute_ = sub.attribute_copy_->c_str(); - sub.has_attribute_ = true; - } else { - sub.attribute_ = nullptr; - sub.has_attribute_ = false; - } - - sub.callback_ = std::move(f); - sub.once_ = false; - this->state_subs_.push_back(std::move(sub)); + this->add_state_subscription_(std::move(entity_id), std::move(attribute), std::move(f), false); } void APIServer::get_home_assistant_state(std::string entity_id, optional attribute, std::function f) { - HomeAssistantStateSubscription sub; - // Allocate heap storage for the strings - sub.entity_id_copy_ = std::make_unique(std::move(entity_id)); - sub.entity_id_ = sub.entity_id_copy_->c_str(); - - if (attribute.has_value()) { - sub.attribute_copy_ = std::make_unique(std::move(attribute.value())); - sub.attribute_ = sub.attribute_copy_->c_str(); - sub.has_attribute_ = true; - } else { - sub.attribute_ = nullptr; - sub.has_attribute_ = false; - } - - sub.callback_ = std::move(f); - sub.once_ = true; - this->state_subs_.push_back(std::move(sub)); + this->add_state_subscription_(std::move(entity_id), std::move(attribute), std::move(f), true); } const std::vector &APIServer::get_state_subs() const { diff --git a/esphome/components/api/api_server.h b/esphome/components/api/api_server.h index 736b8e2b06..697142cbe5 100644 --- a/esphome/components/api/api_server.h +++ b/esphome/components/api/api_server.h @@ -197,6 +197,13 @@ class APIServer : public Component, public Controller { bool update_noise_psk_(const SavedNoisePsk &new_psk, const LogString *save_log_msg, const LogString *fail_log_msg, const psk_t &active_psk, bool make_active); #endif // USE_API_NOISE +#ifdef USE_API_HOMEASSISTANT_STATES + // Helper methods to reduce code duplication + void add_state_subscription_(const char *entity_id, const char *attribute, std::function f, + bool once); + void add_state_subscription_(std::string entity_id, optional attribute, + std::function f, bool once); +#endif // USE_API_HOMEASSISTANT_STATES // Pointers and pointer-like types first (4 bytes each) std::unique_ptr socket_ = nullptr; #ifdef USE_API_CLIENT_CONNECTED_TRIGGER