From 2b80effa203e148fef9c9faae862cb42d45b58b4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 3 Mar 2026 18:52:00 -1000 Subject: [PATCH] Move HAS_PROTO_MESSAGE_DUMP code from template wrappers into non-template cores MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduces per-instantiation cost of send_message and encode_message_to_buffer by moving the DumpBuffer/log code into send_message_() and encode_to_buffer(). The dump methods (message_name, dump_to) are still virtual on ProtoMessage, so they work correctly through the void* → ProtoMessage* cast. --- esphome/components/api/api_connection.cpp | 15 +++++++++++++++ esphome/components/api/api_connection.h | 11 ----------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/esphome/components/api/api_connection.cpp b/esphome/components/api/api_connection.cpp index 4ff5ead893..ff3a3771c9 100644 --- a/esphome/components/api/api_connection.cpp +++ b/esphome/components/api/api_connection.cpp @@ -1868,6 +1868,13 @@ bool APIConnection::try_to_clear_buffer(bool log_out_of_space) { } bool APIConnection::send_message_(uint32_t payload_size, uint8_t message_type, MessageEncodeFn encode_fn, const void *msg) { +#ifdef HAS_PROTO_MESSAGE_DUMP + { + auto *proto_msg = static_cast(msg); + DumpBuffer dump_buf; + this->log_send_message_(proto_msg->message_name(), proto_msg->dump_to(dump_buf)); + } +#endif auto &shared_buf = this->parent_->get_shared_buffer_ref(); this->prepare_first_message_buffer(shared_buf, payload_size); size_t write_start = shared_buf.size(); @@ -1880,6 +1887,14 @@ bool APIConnection::send_message_(uint32_t payload_size, uint8_t message_type, M // including header and footer overhead. Returns 0 if the message doesn't fit. uint16_t APIConnection::encode_to_buffer(uint32_t calculated_size, MessageEncodeFn encode_fn, const void *msg, APIConnection *conn, uint32_t remaining_size) { +#ifdef HAS_PROTO_MESSAGE_DUMP + if (conn->flags_.log_only_mode) { + auto *proto_msg = static_cast(msg); + DumpBuffer dump_buf; + conn->log_send_message_(proto_msg->message_name(), proto_msg->dump_to(dump_buf)); + return 1; + } +#endif // Cache frame sizes to avoid repeated virtual calls const uint8_t header_padding = conn->helper_->frame_header_padding(); const uint8_t footer_size = conn->helper_->frame_footer_size(); diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index f40f62ea9e..7bb6b5cf6b 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -264,10 +264,6 @@ class APIConnection final : public APIServerConnectionBase { using CalculateSizeFn = uint32_t (*)(const void *); template bool send_message(const T &msg) { -#ifdef HAS_PROTO_MESSAGE_DUMP - DumpBuffer dump_buf; - this->log_send_message_(msg.message_name(), msg.dump_to(dump_buf)); -#endif if constexpr (T::ESTIMATED_SIZE == 0) { return this->send_message_(0, T::MESSAGE_TYPE, &encode_msg_noop, &msg); } else { @@ -350,13 +346,6 @@ class APIConnection final : public APIServerConnectionBase { // Thin template wrapper — computes size, delegates buffer work to non-template helper template static uint16_t encode_message_to_buffer(T &msg, APIConnection *conn, uint32_t remaining_size) { -#ifdef HAS_PROTO_MESSAGE_DUMP - if (conn->flags_.log_only_mode) { - DumpBuffer dump_buf; - conn->log_send_message_(msg.message_name(), msg.dump_to(dump_buf)); - return 1; - } -#endif if constexpr (T::ESTIMATED_SIZE == 0) { return encode_to_buffer(0, &encode_msg_noop, &msg, conn, remaining_size); } else {