Remove the virtual keyword from set_update_interval and inline the
trivial setter in the header. No component in the tree actually
overrides this on PollingComponent — the only apparent override was
in sds011 which extends Component (not PollingComponent), so it was
just a name-hiding no-op that is also removed here.
This allows the compiler to inline the setter at all 8 call sites
generated by register_component, eliminating function call overhead
and removing a vtable entry.
Move set_gate_move_threshold_number and set_gate_still_threshold_number
definitions into the header. These are single-line array assignments
called 14 times each (once per gate), and inlining them eliminates
function call overhead, saving ~52 bytes of flash.
Replace floating-point comparison (value != 0.0f) with integer bit-pattern
check via a shared float_to_raw() helper in both encode_float() and
calc_float(). This avoids software float library calls on platforms without
hardware FPU (ESP8266, some LibreTiny chips) and ensures both functions
use identical zero-check logic so size calculation always matches encoding.
Callback::create() can store callables inline (no heap allocation)
when they fit in sizeof(void*) — i.e., a single [this] capture on
32-bit platforms. Many automation triggers captured [this, parent]
in their callback lambdas, doubling the capture size and forcing
heap allocation.
Store the parent/state pointer as a class member and capture only
[this] in the lambda. This trades 4 bytes of member storage for
avoiding a permanent heap allocation per callback registration.
Components changed: cover, valve, lock, fan, media_player, datetime,
display_menu_base, graphical_display_menu, esp32_improv, mqtt_fan.
The notify_state_deferred_ lambda captured [this, state, progress, error]
(16 bytes on 32-bit), exceeding std::function SBO and forcing a heap
allocation on every OTA progress update.
Pack the three values into a single uint32_t:
- state (8 bits) + error (8 bits) + progress as fixed-point (16 bits)
The lambda now captures [this, packed] (8 bytes), fitting in SBO.
Progress resolution of 0.01% is more than adequate for OTA reporting.
The set_timeout lambda captured a psk_t (std::array<uint8_t, 32>) by
value, making the lambda 36 bytes — well beyond the std::function
small buffer optimization threshold, forcing a heap allocation.
Re-read the PSK from preferences inside the timeout callback instead.
The PSK was just saved to flash moments before the timeout was
scheduled, so re-reading it is reliable and avoids the large capture.
Extract load_and_apply_noise_psk_() helper to deduplicate the
load-from-preferences-and-apply pattern used in both setup() and
the timeout callback.