mirror of
https://github.com/esphome/esphome.git
synced 2026-06-24 14:19:03 +00:00
[api] Move APIConnection inlines into api_connection_buffer.h
Pull encode_to_buffer and get_batch_delay_ms_ out of the tail of api_server.h into a dedicated api_connection_buffer.h so api_server.h no longer carries APIConnection method bodies. api_connection.cpp includes api_connection_buffer.h instead of api_server.h; the new header pulls api_server.h in to keep APIServer complete at the inline-definition site. No behavioral change; just file organisation on top of the previous include-cycle break.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#include "api_connection.h"
|
||||
#ifdef USE_API
|
||||
#include "api_server.h" // brings APIServer complete for encode_to_buffer/get_batch_delay_ms_
|
||||
// Pulls in api_server.h (APIServer complete) and the inline encode_to_buffer
|
||||
// and get_batch_delay_ms_ definitions that need it.
|
||||
#include "api_connection_buffer.h"
|
||||
#ifdef USE_API_NOISE
|
||||
#include "api_frame_helper_noise.h"
|
||||
#endif
|
||||
|
||||
@@ -38,8 +38,8 @@ class ComponentIterator;
|
||||
namespace esphome::api {
|
||||
|
||||
// Forward declaration to break the api_connection.h <-> api_server.h include cycle.
|
||||
// APIServer is only used through pointers/references in this header; methods that
|
||||
// need the complete type are defined inline at the bottom of api_server.h.
|
||||
// APIServer is only used through pointers/references in this header; the few
|
||||
// inline methods that need the complete type are defined in api_connection_buffer.h.
|
||||
class APIServer;
|
||||
|
||||
// Keepalive timeout in milliseconds
|
||||
@@ -419,8 +419,9 @@ class APIConnection final : public APIServerConnectionBase {
|
||||
|
||||
// Core batch encoding logic. Computes header size, checks fit, resizes buffer, encodes.
|
||||
// ALWAYS_INLINE so the compiler can devirtualize encode_fn at hot call sites.
|
||||
// Definition is at the bottom of api_server.h, where APIServer is a complete type
|
||||
// (needed for conn->parent_->get_shared_buffer_ref()). Callers must include api_server.h.
|
||||
// Definition lives in api_connection_buffer.h, where APIServer is a complete type
|
||||
// (needed for conn->parent_->get_shared_buffer_ref()). Callers must include
|
||||
// api_connection_buffer.h.
|
||||
static uint16_t ESPHOME_ALWAYS_INLINE encode_to_buffer(uint32_t calculated_size, MessageEncodeFn encode_fn,
|
||||
const void *msg, APIConnection *conn, uint32_t remaining_size);
|
||||
|
||||
@@ -766,7 +767,7 @@ class APIConnection final : public APIServerConnectionBase {
|
||||
// Read by process_batch_multi_ to pass into MessageInfo.
|
||||
uint8_t batch_header_size_{0};
|
||||
|
||||
// Definition at the bottom of api_server.h (needs APIServer complete).
|
||||
// Definition in api_connection_buffer.h (needs APIServer complete).
|
||||
uint32_t get_batch_delay_ms_() const;
|
||||
// Message will use 8 more bytes than the minimum size, and typical
|
||||
// MTU is 1500. Sometimes users will see as low as 1460 MTU.
|
||||
|
||||
61
esphome/components/api/api_connection_buffer.h
Normal file
61
esphome/components/api/api_connection_buffer.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#pragma once
|
||||
|
||||
#include "esphome/core/defines.h"
|
||||
#ifdef USE_API
|
||||
|
||||
// Inline definitions for APIConnection members that need the complete
|
||||
// APIServer type (currently encode_to_buffer for the hot batch-send path and
|
||||
// get_batch_delay_ms_). Pulled into a dedicated header so api_server.h does
|
||||
// not have to carry APIConnection method bodies and api_connection.h can
|
||||
// keep just a forward declaration of APIServer, breaking the include cycle
|
||||
// that previously forced a custom std::unique_ptr deleter on libc++.
|
||||
//
|
||||
// Include this header from translation units that call encode_to_buffer or
|
||||
// any other APIConnection inline that touches APIServer.
|
||||
|
||||
#include "api_connection.h"
|
||||
#include "api_server.h"
|
||||
|
||||
namespace esphome::api {
|
||||
|
||||
inline uint16_t ESPHOME_ALWAYS_INLINE 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<const ProtoMessage *>(msg);
|
||||
DumpBuffer dump_buf;
|
||||
conn->log_send_message_(proto_msg->message_name(), proto_msg->dump_to(dump_buf));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
const uint8_t footer_size = conn->helper_->frame_footer_size();
|
||||
|
||||
// First message uses max padding (already in buffer), subsequent use exact header size
|
||||
size_t to_add;
|
||||
if (conn->flags_.batch_first_message) {
|
||||
conn->flags_.batch_first_message = false;
|
||||
conn->batch_header_size_ = conn->helper_->frame_header_padding();
|
||||
to_add = calculated_size;
|
||||
} else {
|
||||
conn->batch_header_size_ = conn->helper_->frame_header_size(calculated_size, conn->batch_message_type_);
|
||||
to_add = calculated_size + conn->batch_header_size_ + footer_size;
|
||||
}
|
||||
|
||||
// Check if it fits (using actual header size, not max padding)
|
||||
uint16_t total_calculated_size = calculated_size + conn->batch_header_size_ + footer_size;
|
||||
if (total_calculated_size > remaining_size)
|
||||
return 0;
|
||||
|
||||
auto &shared_buf = conn->parent_->get_shared_buffer_ref();
|
||||
shared_buf.resize(shared_buf.size() + to_add);
|
||||
ProtoWriteBuffer buffer{&shared_buf, shared_buf.size() - calculated_size};
|
||||
encode_fn(msg, buffer PROTO_ENCODE_DEBUG_INIT(&shared_buf));
|
||||
|
||||
return total_calculated_size;
|
||||
}
|
||||
|
||||
inline uint32_t APIConnection::get_batch_delay_ms_() const { return this->parent_->get_batch_delay(); }
|
||||
|
||||
} // namespace esphome::api
|
||||
#endif
|
||||
@@ -357,49 +357,5 @@ template<typename... Ts> class APIConnectedCondition : public Condition<Ts...> {
|
||||
}
|
||||
};
|
||||
|
||||
// Inline definitions for APIConnection members declared in api_connection.h
|
||||
// that need the complete APIServer type. Defined here, after APIServer is
|
||||
// complete, so api_connection.h can break the include cycle by only
|
||||
// forward-declaring APIServer.
|
||||
|
||||
inline uint16_t ESPHOME_ALWAYS_INLINE 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<const ProtoMessage *>(msg);
|
||||
DumpBuffer dump_buf;
|
||||
conn->log_send_message_(proto_msg->message_name(), proto_msg->dump_to(dump_buf));
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
const uint8_t footer_size = conn->helper_->frame_footer_size();
|
||||
|
||||
// First message uses max padding (already in buffer), subsequent use exact header size
|
||||
size_t to_add;
|
||||
if (conn->flags_.batch_first_message) {
|
||||
conn->flags_.batch_first_message = false;
|
||||
conn->batch_header_size_ = conn->helper_->frame_header_padding();
|
||||
to_add = calculated_size;
|
||||
} else {
|
||||
conn->batch_header_size_ = conn->helper_->frame_header_size(calculated_size, conn->batch_message_type_);
|
||||
to_add = calculated_size + conn->batch_header_size_ + footer_size;
|
||||
}
|
||||
|
||||
// Check if it fits (using actual header size, not max padding)
|
||||
uint16_t total_calculated_size = calculated_size + conn->batch_header_size_ + footer_size;
|
||||
if (total_calculated_size > remaining_size)
|
||||
return 0;
|
||||
|
||||
auto &shared_buf = conn->parent_->get_shared_buffer_ref();
|
||||
shared_buf.resize(shared_buf.size() + to_add);
|
||||
ProtoWriteBuffer buffer{&shared_buf, shared_buf.size() - calculated_size};
|
||||
encode_fn(msg, buffer PROTO_ENCODE_DEBUG_INIT(&shared_buf));
|
||||
|
||||
return total_calculated_size;
|
||||
}
|
||||
|
||||
inline uint32_t APIConnection::get_batch_delay_ms_() const { return this->parent_->get_batch_delay(); }
|
||||
|
||||
} // namespace esphome::api
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user