Bitfield component_source_index_ (9 bits) and warn_if_blocking_over_
(7 bits) into the same 16 bits. This doubles the max unique component
source names from 255 to 511 without increasing Component size.
The blocking warn threshold max drops from 2550ms to 1270ms which is
more than sufficient since it starts at 50ms and ratchets up.
Fixes test warnings when many components are compiled together:
WARNING Too many unique component source names (max 255)
- TriggerForwarder::operator() now takes const Ts&... to avoid
copies of non-trivial types (e.g., std::string).
- Revert lock to trigger-based pattern: LockStateForwarder holds
two pointers (automation + lock), exceeding sizeof(void*) which
would cause Callback::create to heap-allocate.
- Remove forwarder_extra_args from API since lock was the only user.
Replace bool_filter with generic forwarder parameter that accepts
any struct type. Components can define their own forwarders with
custom fields (e.g., LockStateForwarder needs both automation and
lock entity pointers).
Migrates number (NumberStateTrigger) and lock (LockStateTrigger)
to prove the API is flexible enough for diverse patterns.
Replace per-site lambda generation with TriggerForwarder<Ts...>,
TriggerOnTrueForwarder, and TriggerOnFalseForwarder structs. The
compiler generates one operator() per forwarder type shared across
all call sites, avoiding flash duplication from unique lambdas.
Also cleans up API: replaces condition/callback_args with
bool_filter using TRIGGER_ON_TRUE/TRIGGER_ON_FALSE constants.
Tests the lambda output format for all variations used by
build_callback_automation: no args, typed args, conditions,
multiple args, and empty capture.
- Test empty name returns 0
- Test deduplication returns same index
- Test overflow warns and returns 0
- Remove duplicate index==0 check in get_component_log_str() since
component_source_lookup() already handles it
- Drop 9-bit index scheme in favor of plain uint8_t (max 255 unique
source names, overflow warns in Python and returns 0)
- Add friend declarations for setup()/original_setup() so generated
code can call protected set_component_source_()
- Move get_component_log_str() out of line
- Fix test mocks to provide CORE.data dict
Embed component namespace in storage variable names so analyze-memory
can reliably attribute them. Display as "storage for {id}" in reports
and always show regardless of size threshold.