The base class loop() only drained the overflow buffer. Rename to
make intent clear and inline it so the compiler can optimize across
the call boundary. Make loop() pure virtual since subclasses always
override it.
The TCP send overflow buffer code was embedded directly in
APIFrameHelper, making it appear to be part of the primary send path.
In reality, it is rarely used in production — only when the kernel TCP
send buffer is full due to a slow client, congested network, or heavy
logging. Extract it into a dedicated APIOverflowBuffer class with clear
documentation about its purpose and usage frequency.
- Add std::launder to reinterpret_cast in inline callback path for
formal C++20 correctness (generates identical code)
- Fix static_assert comment: sizeof equality ensures round-trip through
uintptr_t, not absence of trap representations per se
- Document that call() is only valid on Callbacks from create()
Convert rotary_encoder register_listener, canbus add_callback,
sdl add_key_listener, and udp add_listener from std::function to
templates to avoid the heap-allocation fallback path.
MQTT backend set_on_* methods are virtual and cannot be templatized.
Pass wrapping lambdas directly to CallbackManager::add() instead of
first wrapping in std::function. The lambdas capture [this, callback]
(two pointers) so they hit the heap path either way, but this avoids
double-wrapping and the extra std::function overhead.
Also fix "deallaction" typo.
Convert haier, nextion, microphone, ezo, uart, speaker, zigbee,
and hlk_fm22x callback methods that were missed by the initial
conversion (they used add_*_callback instead of add_on_*_callback).
Use (*ptr)(args...) instead of ptr->operator()(args...) so the
inline path works correctly for function pointers, which are
trivially copyable and pointer-sized but lack operator().
Replace char-by-char loops with __builtin_memcpy in the inline
Callback storage path. Generates identical code but is cleaner
and avoids clang-analyzer false positives without NOLINT annotations.
Convert all remaining component add_on_*_callback methods from
std::function to templates so lambdas flow through without wrapping.
This avoids a heap allocation regression where passing std::function
through Callback::create would heap-allocate the std::function itself.
Also add NOLINT annotations for clang-analyzer false positive on
byte-wise copy in Callback::create.