mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 02:02:51 +00:00
[light] Keep one copy of the color mode lookup table in flash (#20394)
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include "esphome/core/finite_set_mask.h"
|
||||
#include "esphome/core/hal.h"
|
||||
|
||||
namespace esphome::light {
|
||||
|
||||
@@ -108,8 +109,9 @@ constexpr ColorModeHelper operator|(ColorModeHelper lhs, ColorMode rhs) {
|
||||
using color_mode_bitmask_t = uint16_t;
|
||||
|
||||
// Lookup table for ColorMode bit mapping
|
||||
// This array defines the canonical order of color modes (bit 0-9)
|
||||
constexpr ColorMode COLOR_MODE_LOOKUP[] = {
|
||||
// This array defines the canonical order of color modes (bit 0-9). One shared copy in flash; read it at run time
|
||||
// through color_mode_at().
|
||||
inline constexpr ColorMode COLOR_MODE_LOOKUP[] PROGMEM = {
|
||||
ColorMode::UNKNOWN, // bit 0
|
||||
ColorMode::ON_OFF, // bit 1
|
||||
ColorMode::BRIGHTNESS, // bit 2
|
||||
@@ -122,6 +124,12 @@ constexpr ColorMode COLOR_MODE_LOOKUP[] = {
|
||||
ColorMode::RGB_COLD_WARM_WHITE, // bit 9
|
||||
};
|
||||
|
||||
constexpr ColorMode color_mode_at(unsigned bit) {
|
||||
if (__builtin_is_constant_evaluated())
|
||||
return COLOR_MODE_LOOKUP[bit];
|
||||
return static_cast<ColorMode>(progmem_read_byte(reinterpret_cast<const uint8_t *>(&COLOR_MODE_LOOKUP[bit])));
|
||||
}
|
||||
|
||||
/// Bit mapping policy for ColorMode
|
||||
/// Uses lookup table for non-contiguous enum values
|
||||
struct ColorModeBitPolicy {
|
||||
@@ -129,17 +137,15 @@ struct ColorModeBitPolicy {
|
||||
static constexpr int MAX_BITS = sizeof(COLOR_MODE_LOOKUP) / sizeof(COLOR_MODE_LOOKUP[0]);
|
||||
|
||||
static constexpr unsigned to_bit(ColorMode mode) {
|
||||
// Linear search through lookup table
|
||||
// Compiler optimizes this to efficient code since array is constexpr
|
||||
for (int i = 0; i < MAX_BITS; ++i) {
|
||||
if (COLOR_MODE_LOOKUP[i] == mode)
|
||||
if (color_mode_at(i) == mode)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static constexpr ColorMode from_bit(unsigned bit) {
|
||||
return (bit < MAX_BITS) ? COLOR_MODE_LOOKUP[bit] : ColorMode::UNKNOWN;
|
||||
return (bit < MAX_BITS) ? color_mode_at(bit) : ColorMode::UNKNOWN;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -157,7 +163,7 @@ constexpr uint16_t compute_capability_bitmask(ColorCapability capability) {
|
||||
// Check each ColorMode to see if it has this capability
|
||||
constexpr int color_mode_count = sizeof(COLOR_MODE_LOOKUP) / sizeof(COLOR_MODE_LOOKUP[0]);
|
||||
for (int bit = 0; bit < color_mode_count; ++bit) {
|
||||
uint8_t mode_val = static_cast<uint8_t>(COLOR_MODE_LOOKUP[bit]);
|
||||
uint8_t mode_val = static_cast<uint8_t>(color_mode_at(bit));
|
||||
if ((mode_val & cap_bit) != 0) {
|
||||
mask |= (1 << bit);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user