Resolve conflict in component.cpp: keep destructor removed (moved
to header as = default) and keep #ifdef USE_SETUP_PRIORITY_OVERRIDE
guard from dev.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The LWIP raw socket factory only supports TCP but silently ignored the
type parameter, returning a TCP socket for SOCK_DGRAM requests. This
caused components expecting UDP to fail silently with no indication of
why. Return nullptr with EPROTOTYPE and log an error instead.
When leave_() decremented consumers to 0 without removing the entry,
a subsequent join_() would find it, increment 0->1, and return early
without rejoining the IGMP multicast group. Now join_() only skips
the IGMP rejoin when consumers was already > 0.
Replace std::map<int, int> with std::vector<UniverseConsumer> for
tracking universe reference counts. This eliminates red-black tree
overhead for what is typically 1-10 entries.
Co-Authored-By: J. Nick Koston <nick@koston.org>
The socket abstraction layer on ESP8266/RP2040 (USE_SOCKET_IMPL_LWIP_TCP)
only supports TCP. When E1.31 was migrated from WiFiUDP to sockets, it
silently broke on these platforms since SOCK_DGRAM requests get TCP sockets
that never receive UDP data.
Restore WiFiUDP as the transport on LWIP_TCP platforms while keeping the
socket-based implementation on BSD/LWIP socket platforms (ESP32, etc.).
This follows the same dual-path pattern used by the udp and wake_on_lan
components.
Replace the LogListener abstract class (single pure virtual method) with
a lightweight LogCallback struct containing a function pointer + instance
pointer. This eliminates a vtable sub-table and thunk from every class
that previously inherited LogListener.
Savings per former LogListener implementer:
- 12 bytes vtable (sub-table header + thunk slot)
- 4 bytes vtable (on_log in primary table)
- ~23 bytes thunk code
- ~39 bytes total per class
Affected classes: APIServer, WebServer, MQTTClientComponent, Syslog,
BLENUS, LoggerMessageTrigger (6 classes, ~234 bytes total).
The non-capturing lambdas used at registration sites decay to plain
function pointers at compile time -- zero closure/std::function overhead.
Neither method is overridden anywhere in the codebase.
Removing virtual eliminates one vtable slot per method
from every Component-derived class (~100+ vtables),
saving ~800+ bytes of flash globally.