Commit Graph
27309 Commits
Author SHA1 Message Date
J. Nick Koston 576b1c3ff0 Fix fan fixture: use C++17 namespace style 2026-03-26 15:25:13 -10:00
J. Nick Koston 991c34a4f3 Fix fixtures: remove unnecessary build flags, use C++17 namespace style 2026-03-26 15:24:38 -10:00
J. Nick Koston c8d842586a Fix fan fixture: remove unnecessary build flags 2026-03-26 15:23:44 -10:00
J. Nick Koston 2f93ba0d71 Add integration test for deprecated FanTraits compat layer 2026-03-26 15:21:11 -10:00
J. Nick Koston 602bcd2c97 Add integration test for deprecated ClimateTraits compat layer 2026-03-26 15:19:45 -10:00
J. Nick Koston e77cdb5971 [light] Validate effect names during config validation instead of codegen (#15107) 2026-03-26 15:13:44 -10:00
J. Nick Koston 90e6c0d7c7 [core] Remove indirection from ControllerRegistry dispatch (#15173) 2026-03-26 15:09:16 -10:00
J. Nick Koston 240e53afce [fan] Add benchmarks for fan component (#15210) 2026-03-26 14:35:09 -10:00
J. Nick Koston 413202e02e Restore deleted std::string overloads for clear compile-time diagnostics 2026-03-26 14:31:06 -10:00
J. Nick Koston c42cfac50f Fix dangling reference in save_state_, restore deleted string overloads
1. save_state_() bound a reference to supported_preset_modes() from
   a temporary FanTraits returned by get_traits(). When the compat
   path fired, the temporary was destroyed and the reference dangled.
   Fix: keep the FanTraits alive for the loop duration.

2. Restore deleted std::vector<std::string> / initializer_list<std::string>
   overloads to preserve clear compile-time diagnostics.
2026-03-26 14:28:55 -10:00
J. Nick Koston 027cb0c35c Fix compat: use owned vectors instead of heap leak
Replace new-and-leak deprecated setters with plain owned vector members
on ClimateTraits. Copies copy the vector (same cost as before this PR).
No heap leak, no dangling pointer, no smart pointer overhead.

All compat paths (getters, find, supports) check the owned vector as
fallback when the pointer path is not set.
2026-03-26 14:11:15 -10:00
J. Nick Koston 56f0d3f7f5 Fix compat: use owned vector instead of leak, wire preset modes in subclasses
- Deprecated FanTraits setters store in an owned compat_preset_modes_
  vector (same copy cost as pre-PR). No heap leak, no dangling pointer.
- Subclass get_traits() calls wire_preset_modes_() to attach the
  Fan-owned pointer to the returned traits.
- Getter/find/supports all check compat vector as fallback.
2026-03-26 14:08:07 -10:00
J. Nick Koston 4838c61a8c Move preset modes pointer to private, consolidate empty vector to cpp
- Move supported_preset_modes_ pointer and ensure helper to private
- Move static EMPTY_VECTOR from inline header getter to a single
  file-scope constant in fan.cpp (avoids duplication per TU)
- Add 2026.11.0 removal comments on all compat code paths
2026-03-26 14:02:27 -10:00
J. Nick Koston ebc4421ba6 Move custom mode pointers to private, consolidate empty vector to cpp
- Move supported_custom_fan_modes_ and supported_custom_presets_ pointers
  and ensure helpers to private section
- Move static EMPTY_VECTOR from inline header getters to a single
  file-scope constant in climate_traits.cpp (avoids duplication per TU)
- Add 2026.11.0 removal comments on all compat code paths
2026-03-26 14:01:08 -10:00
J. Nick Koston df8edfe346 Merge branch 'dev' into alarm-control-panel-trigger-trampoline 2026-03-26 13:53:12 -10:00
J. Nick Koston 2d56b089ed Merge branch 'dev' into lock-trigger-trampoline 2026-03-26 13:53:03 -10:00
J. Nick Koston 147c96ce33 Merge branch 'dev' into safe-mode-trigger-trampoline 2026-03-26 13:52:52 -10:00
J. Nick Koston 0fb9699257 Merge branch 'dev' into ld2450-trigger-trampoline 2026-03-26 13:52:41 -10:00
J. Nick Koston 5be5f16662 Fix compat: heap-allocate deprecated vector, add find fallback
Two bugs fixed from Copilot review:

1. Dangling pointer on copy: deprecated setters stored data in an
   OwnedPresetModes struct on FanTraits. If the traits object was
   copied, the copy's pointer dangled. Fix: deprecated setters now
   heap-allocate (intentional leak). Pointer survives any copy.
   Remove the OwnedPresetModes wrapper entirely.

2. find_preset_mode_ / save_state_ only searched the Fan-owned
   vector, breaking external components using the deprecated traits
   setters. Fix: fall back to get_traits() when the entity vector
   is null.
2026-03-26 13:52:41 -10:00
J. Nick Koston 5ea1c08975 Merge branch 'dev' into media-player-trigger-trampoline 2026-03-26 13:52:30 -10:00
J. Nick Koston 79228c7c0e Merge branch 'dev' into rtttl-trigger-trampoline 2026-03-26 13:52:22 -10:00
J. Nick Koston fa8a609bcc [automation] Eliminate trigger trampolines with deduplicated forwarder structs (#15174) 2026-03-26 13:50:50 -10:00
J. Nick Koston 5a9e55707b Fix compat: heap-allocate deprecated vectors, add find fallback
Two bugs fixed from Copilot review:

1. Dangling pointer on copy: deprecated setters stored data in an
   OwnedCustomModes struct on ClimateTraits. If the traits object was
   copied (when NRVO doesn't apply), the copy's pointer dangled.
   Fix: deprecated setters now heap-allocate (intentional leak, same
   pattern as Climate entity). Pointer survives any copy. Remove the
   OwnedCustomModes wrapper entirely.

2. find_custom_fan_mode_ / find_custom_preset_ only searched the
   Climate-owned vectors, breaking external components using the
   deprecated traits setters. Fix: fall back to get_traits() when
   the entity vector is null.
2026-03-26 13:50:18 -10:00
J. Nick Koston 554d97ff04 Fix clang-tidy: add braces around if statements, extract ensure helper 2026-03-26 13:33:15 -10:00
J. Nick Koston c283e11ffa Fix clang-tidy: add braces around if statements, extract ensure helpers 2026-03-26 13:32:32 -10:00
J. Nick Koston 4ff0d30e07 Use leak-on-purpose raw pointer for Fan-owned preset modes vector
Fan entities live for the entire program lifetime, so the preset
modes vector never needs to be freed. Use a raw pointer (null by
default, allocated on first set_supported_preset_modes() call)
instead of an inline std::vector member.

This saves 24 bytes of RAM per Fan instance for components that
don't use preset modes (binary, bedjet, tuya, etc.).
2026-03-26 13:24:58 -10:00
J. Nick Koston 805bc4c9a8 Use leak-on-purpose raw pointers for Climate-owned vectors
Climate entities live for the entire program lifetime, so the custom
mode vectors never need to be freed. Use raw pointers (null by default,
allocated on first set_supported_custom_*() call) instead of inline
std::vector members.

This saves 48 bytes of RAM per Climate instance (two empty vectors)
for components that don't use custom modes (bang_bang, pid, etc.),
and avoids any copy overhead in get_traits().
2026-03-26 13:22:46 -10:00
J. Nick Koston df58091d1d Make compat owned vector skip-on-copy to eliminate copy overhead
Wrap the deprecated owned vector in a struct with a no-op copy
constructor. FanTraits copies (which happen on every get_traits()
call) don't pay the 24-byte cost of copying an empty vector.
2026-03-26 13:14:52 -10:00
J. Nick Koston ba57555b6f Make compat owned vectors skip-on-copy to eliminate copy overhead
Wrap the deprecated owned vectors in a struct with a no-op copy
constructor. This way ClimateTraits copies (which happen on every
get_traits() call) don't pay the 48-byte cost of copying two empty
vectors. The compat data only matters for the original traits object
where the deprecated setter was called.
2026-03-26 13:13:16 -10:00
J. Nick Koston b2290891a3 Revert benchmark changes — keep identical to base for apples-to-apples comparison 2026-03-26 13:11:24 -10:00
J. Nick Koston fe395ac41d Use plain vector compat members, add custom modes benchmark
The owned vectors add 48 bytes to ClimateTraits copies — this is the
cost of backward compat and will be removed in 2026.11.0.

Add ClimatePublish_WithCustomModes benchmark to show the improvement
for climate devices that use custom fan modes and presets (the case
that previously heap-allocated on every publish).
2026-03-26 13:10:47 -10:00
J. Nick Koston 3f1dfd0f3f Fix deprecation dates: 2026.5.0 deprecated, 2026.11.0 removed 2026-03-26 13:05:33 -10:00
J. Nick Koston 237cfdebfc [fan] Store preset mode vector on Fan entity, not FanTraits
FanTraits contained a std::vector<const char *> for preset modes.
Every get_traits() call reconstructed this vector, causing heap
allocations on every publish_state() and control()/perform() call.

Move the vector storage to the Fan base class and have FanTraits hold
a const pointer instead. Internal callers (save_state_, find_preset_mode_)
search the Fan-owned vector directly, avoiding traits reconstruction.

The old FanTraits setters are preserved as deprecated compatibility
overloads (removed in 2026.11.0) that self-own the data, so external
components continue to compile — they just get a deprecation warning
and still heap-allocate until they migrate.
2026-03-26 13:04:59 -10:00
J. Nick Koston a723ca31ed Add deprecated compat layer, restore const ref return type
Keep the old set_supported_custom_fan_modes() and
set_supported_custom_presets() overloads on ClimateTraits as deprecated
compatibility shims. They self-own the data so external components
continue to compile without changes (heap alloc but functional).

Restores get_supported_custom_fan_modes() / get_supported_custom_presets()
to return const vector & (not pointer) for full backward compat.
2026-03-26 13:02:22 -10:00
J. Nick Koston 236d1ea88f Fix: use inline function for empty vector to avoid EMPTY macro clash and static local overhead 2026-03-26 12:56:30 -10:00
J. Nick Koston 013d832475 Fix clang-tidy: rename static constant empty to EMPTY 2026-03-26 12:42:15 -10:00
J. Nick Koston 854e8d90cb Fix copy lock namespace qualification for LockState 2026-03-26 12:39:44 -10:00
J. Nick Koston 7ae1f2f6d7 [climate] Store custom mode vectors on Climate entity, not ClimateTraits
ClimateTraits contained two std::vector<const char *> members for custom
fan modes and custom presets. Every get_traits() / traits() call
reconstructed these vectors, causing heap allocations on every
publish_state() and control()/perform() call — the hottest paths in the
climate component.

Move the vector storage to the Climate base class and have ClimateTraits
hold const pointers instead. get_traits() wires the pointers
automatically. This eliminates all heap allocation from ClimateTraits
copies, making the struct trivially copyable (floats + bitmasks +
2 pointers).

Additionally, set_custom_fan_mode_() and set_custom_preset_() no longer
need to call get_traits() just to search for a mode — they search the
Climate-owned vectors directly, removing another traits rebuild from the
control/perform path.
2026-03-26 12:38:25 -10:00
J. Nick Koston 24cc9bdb13 Update copy lock to accept LockState callback parameter 2026-03-26 12:31:14 -10:00
J. Nick Koston ce64d9ea4c Merge branch 'lock-trigger-trampoline' into integration 2026-03-26 10:37:29 -10:00
J. Nick Koston 0adb0f8426 Merge branch 'ld2450-trigger-trampoline' into integration 2026-03-26 10:37:18 -10:00
J. Nick Koston 05b2fda36f Merge branch 'media-player-trigger-trampoline' into integration 2026-03-26 10:37:12 -10:00
J. Nick Koston 491e065843 Merge branch 'alarm-control-panel-trigger-trampoline' into integration 2026-03-26 10:37:06 -10:00
J. Nick Koston 9073574bbd Merge branch 'safe-mode-trigger-trampoline' into integration 2026-03-26 10:37:01 -10:00
J. Nick Koston 4737407585 Merge branch 'rtttl-trigger-trampoline' into integration 2026-03-26 10:36:56 -10:00
J. Nick Koston bf575dd1c4 Merge branch 'eliminate-trigger-trampolines' into safe-mode-trigger-trampoline 2026-03-26 10:36:14 -10:00
J. Nick Koston 92bd8b85f3 Merge branch 'eliminate-trigger-trampolines' into alarm-control-panel-trigger-trampoline 2026-03-26 10:35:54 -10:00
J. Nick Koston 0ddda2561c Merge branch 'eliminate-trigger-trampolines' into lock-trigger-trampoline 2026-03-26 10:35:47 -10:00
J. Nick Koston 596f90ea0c Merge branch 'eliminate-trigger-trampolines' into ld2450-trigger-trampoline 2026-03-26 10:35:30 -10:00
J. Nick Koston 1a29edf836 Merge branch 'eliminate-trigger-trampolines' into media-player-trigger-trampoline 2026-03-26 10:35:22 -10:00