diff --git a/esphome/components/api/api_connection.h b/esphome/components/api/api_connection.h index 7bb6b5cf6b7..302ea75f68a 100644 --- a/esphome/components/api/api_connection.h +++ b/esphome/components/api/api_connection.h @@ -267,7 +267,7 @@ class APIConnection final : public APIServerConnectionBase { if constexpr (T::ESTIMATED_SIZE == 0) { return this->send_message_(0, T::MESSAGE_TYPE, &encode_msg_noop, &msg); } else { - return this->send_message_(msg.calculate_size(), T::MESSAGE_TYPE, &encode_msg, &msg); + return this->send_message_(msg.calculate_size(), T::MESSAGE_TYPE, &proto_encode_msg, &msg); } } @@ -324,11 +324,6 @@ class APIConnection final : public APIServerConnectionBase { void process_state_subscriptions_(); #endif - // Encode thunk — converts void* back to concrete type for direct encode() call - template static void encode_msg(const void *msg, ProtoWriteBuffer &buffer) { - static_cast(msg)->encode(buffer); - } - // Size thunk — converts void* back to concrete type for direct calculate_size() call template static uint32_t calc_size(const void *msg) { return static_cast(msg)->calculate_size(); @@ -349,7 +344,7 @@ class APIConnection final : public APIServerConnectionBase { if constexpr (T::ESTIMATED_SIZE == 0) { return encode_to_buffer(0, &encode_msg_noop, &msg, conn, remaining_size); } else { - return encode_to_buffer(msg.calculate_size(), &encode_msg, &msg, conn, remaining_size); + return encode_to_buffer(msg.calculate_size(), &proto_encode_msg, &msg, conn, remaining_size); } } @@ -362,7 +357,7 @@ class APIConnection final : public APIServerConnectionBase { template static uint16_t fill_and_encode_entity_state(EntityBase *entity, T &msg, APIConnection *conn, uint32_t remaining_size) { - return fill_and_encode_entity_state(entity, msg, &calc_size, &encode_msg, conn, remaining_size); + return fill_and_encode_entity_state(entity, msg, &calc_size, &proto_encode_msg, conn, remaining_size); } // Non-template core — fills info fields, allocates buffers, and encodes @@ -374,7 +369,7 @@ class APIConnection final : public APIServerConnectionBase { template static uint16_t fill_and_encode_entity_info(EntityBase *entity, T &msg, APIConnection *conn, uint32_t remaining_size) { - return fill_and_encode_entity_info(entity, msg, &calc_size, &encode_msg, conn, remaining_size); + return fill_and_encode_entity_info(entity, msg, &calc_size, &proto_encode_msg, conn, remaining_size); } // Non-template core — fills device_class, then delegates to fill_and_encode_entity_info @@ -388,8 +383,8 @@ class APIConnection final : public APIServerConnectionBase { static uint16_t fill_and_encode_entity_info_with_device_class(EntityBase *entity, T &msg, StringRef &device_class_field, APIConnection *conn, uint32_t remaining_size) { - return fill_and_encode_entity_info_with_device_class(entity, msg, device_class_field, &calc_size, &encode_msg, - conn, remaining_size); + return fill_and_encode_entity_info_with_device_class(entity, msg, device_class_field, &calc_size, + &proto_encode_msg, conn, remaining_size); } #ifdef USE_VOICE_ASSISTANT diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index 5d2c101cc4d..36b2fd25d9f 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -933,12 +933,15 @@ inline void ProtoWriteBuffer::encode_packed_sint32(uint32_t field_id, const std: } } +// Encode thunk — converts void* back to concrete type for direct encode() call +template void proto_encode_msg(const void *msg, ProtoWriteBuffer &buf) { + static_cast(msg)->encode(buf); +} + // Implementation of encode_message - must be after ProtoMessage is defined template inline void ProtoWriteBuffer::encode_message(uint32_t field_id, const T &value, bool force) { uint32_t msg_length_bytes = value.calculate_size(); - this->encode_message( - field_id, msg_length_bytes, &value, - [](const void *msg, ProtoWriteBuffer &buf) { static_cast(msg)->encode(buf); }, force); + this->encode_message(field_id, msg_length_bytes, &value, &proto_encode_msg, force); } // Non-template core for encode_message