mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 08:55:36 +00:00
Store entity string indices as 3 uint8_t fields in struct padding
Replace uint32_t entity_string_packed_ with 3 separate uint8_t fields (device_class_idx_, uom_idx_, icon_idx_) placed after the 1-byte EntityFlags struct. These fill the 3 padding bytes that the compiler would insert anyway for alignment, saving 4 bytes per entity with zero layout overhead. The set_entity_strings(uint32_t) API is preserved — it unpacks into the individual fields.
This commit is contained in:
@@ -50,25 +50,22 @@ __attribute__((weak)) const char *entity_device_class_lookup(uint16_t) { return
|
||||
__attribute__((weak)) const char *entity_uom_lookup(uint16_t) { return ""; }
|
||||
__attribute__((weak)) const char *entity_icon_lookup(uint16_t) { return ""; }
|
||||
|
||||
// Entity device class (from packed index)
|
||||
// Entity device class (from index)
|
||||
StringRef EntityBase::get_device_class_ref() const {
|
||||
return StringRef(
|
||||
entity_device_class_lookup((this->entity_string_packed_ >> ENTITY_STR_DC_SHIFT) & ENTITY_STR_DC_MASK));
|
||||
return StringRef(entity_device_class_lookup(this->device_class_idx_));
|
||||
}
|
||||
std::string EntityBase::get_device_class() const { return std::string(this->get_device_class_ref().c_str()); }
|
||||
|
||||
// Entity unit of measurement (from packed index)
|
||||
StringRef EntityBase::get_unit_of_measurement_ref() const {
|
||||
return StringRef(entity_uom_lookup((this->entity_string_packed_ >> ENTITY_STR_UOM_SHIFT) & ENTITY_STR_UOM_MASK));
|
||||
}
|
||||
// Entity unit of measurement (from index)
|
||||
StringRef EntityBase::get_unit_of_measurement_ref() const { return StringRef(entity_uom_lookup(this->uom_idx_)); }
|
||||
std::string EntityBase::get_unit_of_measurement() const {
|
||||
return std::string(this->get_unit_of_measurement_ref().c_str());
|
||||
}
|
||||
|
||||
// Entity icon (from packed index)
|
||||
// Entity icon (from index)
|
||||
StringRef EntityBase::get_icon_ref() const {
|
||||
#ifdef USE_ENTITY_ICON
|
||||
return StringRef(entity_icon_lookup((this->entity_string_packed_ >> ENTITY_STR_ICON_SHIFT) & ENTITY_STR_ICON_MASK));
|
||||
return StringRef(entity_icon_lookup(this->icon_idx_));
|
||||
#else
|
||||
return StringRef(entity_icon_lookup(0));
|
||||
#endif
|
||||
|
||||
+12
-14
@@ -14,21 +14,12 @@
|
||||
|
||||
namespace esphome {
|
||||
|
||||
// Extern lookup functions for packed entity string tables.
|
||||
// Extern lookup functions for entity string tables.
|
||||
// Generated code provides strong definitions; weak defaults return "".
|
||||
extern const char *entity_device_class_lookup(uint16_t index);
|
||||
extern const char *entity_uom_lookup(uint16_t index);
|
||||
extern const char *entity_icon_lookup(uint16_t index);
|
||||
|
||||
// Bit layout for entity_string_packed_:
|
||||
// [31..24] reserved | [23..16] icon (8 bits) | [15..8] UoM (8 bits) | [7..0] device_class (8 bits)
|
||||
static constexpr uint8_t ENTITY_STR_DC_SHIFT = 0;
|
||||
static constexpr uint8_t ENTITY_STR_UOM_SHIFT = 8;
|
||||
static constexpr uint8_t ENTITY_STR_ICON_SHIFT = 16;
|
||||
static constexpr uint8_t ENTITY_STR_DC_MASK = 0xFF;
|
||||
static constexpr uint8_t ENTITY_STR_UOM_MASK = 0xFF;
|
||||
static constexpr uint8_t ENTITY_STR_ICON_MASK = 0xFF;
|
||||
|
||||
// Maximum device name length - keep in sync with validate_hostname() in esphome/core/config.py
|
||||
static constexpr size_t ESPHOME_DEVICE_NAME_MAX_LEN = 31;
|
||||
|
||||
@@ -104,9 +95,13 @@ class EntityBase {
|
||||
this->flags_.entity_category = static_cast<uint8_t>(entity_category);
|
||||
}
|
||||
|
||||
// Set packed entity string indices — one call per entity from codegen.
|
||||
// Bit layout: [23..16] icon (8 bits) | [15..8] UoM (8 bits) | [7..0] device_class (8 bits)
|
||||
void set_entity_strings(uint32_t packed) { this->entity_string_packed_ = packed; }
|
||||
// Set entity string table indices — one call per entity from codegen.
|
||||
// Packed: [23..16] icon | [15..8] UoM | [7..0] device_class (each 8 bits)
|
||||
void set_entity_strings(uint32_t packed) {
|
||||
this->device_class_idx_ = packed & 0xFF;
|
||||
this->uom_idx_ = (packed >> 8) & 0xFF;
|
||||
this->icon_idx_ = (packed >> 16) & 0xFF;
|
||||
}
|
||||
|
||||
// Get device class as StringRef (from packed index)
|
||||
StringRef get_device_class_ref() const;
|
||||
@@ -199,7 +194,6 @@ class EntityBase {
|
||||
void calc_object_id_();
|
||||
|
||||
StringRef name_;
|
||||
uint32_t entity_string_packed_{0}; // bits 0-7: device_class, 8-15: uom, 16-23: icon, 24-31: reserved
|
||||
uint32_t object_id_hash_{};
|
||||
#ifdef USE_DEVICES
|
||||
Device *device_{};
|
||||
@@ -214,6 +208,10 @@ class EntityBase {
|
||||
uint8_t entity_category : 2; // Supports up to 4 categories
|
||||
uint8_t reserved : 2; // Reserved for future use
|
||||
} flags_{};
|
||||
// String table indices — packed into the 3 padding bytes after flags_
|
||||
uint8_t device_class_idx_{};
|
||||
uint8_t uom_idx_{};
|
||||
uint8_t icon_idx_{};
|
||||
};
|
||||
|
||||
/// Log entity icon if set (for use in dump_config)
|
||||
|
||||
@@ -31,21 +31,16 @@ _KEY_DC_IDX = "_entity_dc_idx"
|
||||
_KEY_UOM_IDX = "_entity_uom_idx"
|
||||
_KEY_ICON_IDX = "_entity_icon_idx"
|
||||
|
||||
# Bit layout for entity_string_packed_ (must match C++ constants in entity_base.h):
|
||||
#
|
||||
# uint32_t entity_string_packed_:
|
||||
# [31 ...... 24][23 ...... 16][15 ....... 8][7 ........ 0]
|
||||
# reserved (8) icon (8) UoM (8) device_class (8)
|
||||
# max 255 max 255 max 255
|
||||
#
|
||||
# Bit layout for set_entity_strings(packed) — must match C++ setter in entity_base.h:
|
||||
# [23..16] icon (8 bits) | [15..8] UoM (8 bits) | [7..0] device_class (8 bits)
|
||||
_DC_SHIFT = 0
|
||||
_UOM_SHIFT = 8
|
||||
_ICON_SHIFT = 16
|
||||
|
||||
# Maximum unique strings per category (must match bit widths above)
|
||||
_MAX_DEVICE_CLASSES = 0xFF # 8 bits → 255
|
||||
_MAX_UNITS = 0xFF # 8 bits → 255
|
||||
_MAX_ICONS = 0xFF # 8 bits → 255
|
||||
# Maximum unique strings per category (8-bit index, 0 = not set)
|
||||
_MAX_DEVICE_CLASSES = 0xFF # 255
|
||||
_MAX_UNITS = 0xFF # 255
|
||||
_MAX_ICONS = 0xFF # 255
|
||||
|
||||
|
||||
@dataclass
|
||||
|
||||
Reference in New Issue
Block a user