mirror of
https://github.com/esphome/esphome.git
synced 2026-10-14 02:02:51 +00:00
Compute the object id hash when an external caller passes 0
This commit is contained in:
@@ -68,7 +68,14 @@ void EntityBase::configure_entity_(const char *name, uint32_t object_id_hash, ui
|
||||
this->object_id_hash_ = fnv1_hash_object_id(fallback.c_str(), fallback.size());
|
||||
} else {
|
||||
this->flags_.has_own_name = true;
|
||||
// Static name - codegen precomputes the hash
|
||||
// Static name - codegen precomputes the hash; external register_* callers may pass 0
|
||||
if (object_id_hash == 0) {
|
||||
#ifdef USE_ESP8266
|
||||
object_id_hash = fnv1_hash_object_id_P(this->name_.progmem_ptr(), this->name_.size());
|
||||
#else
|
||||
object_id_hash = fnv1_hash_object_id(this->name_.progmem_ptr(), this->name_.size());
|
||||
#endif
|
||||
}
|
||||
this->object_id_hash_ = object_id_hash;
|
||||
}
|
||||
// Unpack entity string table indices and flags from entity_fields.
|
||||
|
||||
@@ -1145,6 +1145,18 @@ inline uint32_t fnv1_hash_object_id(const char *str, size_t len) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
/// fnv1_hash_object_id() for a string in flash (PROGMEM).
|
||||
inline uint32_t fnv1_hash_object_id_P(PGM_P str, size_t len) {
|
||||
uint32_t hash = FNV1_OFFSET_BASIS;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
hash *= FNV1_PRIME;
|
||||
hash ^= static_cast<uint8_t>(to_sanitized_char(to_snake_case_char(static_cast<char>(pgm_read_byte(str + i)))));
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_ESP8266
|
||||
// ESP8266: Use vsnprintf_P to keep format strings in flash (PROGMEM)
|
||||
// Format strings must be wrapped with PSTR() macro
|
||||
|
||||
@@ -13,4 +13,21 @@ namespace esphome::core::testing {
|
||||
static_assert(std::is_same_v<decltype(std::declval<const EntityBase &>().get_name()), const StringRef &>);
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
class TestEntity : public EntityBase {
|
||||
public:
|
||||
void configure(const char *name, uint32_t object_id_hash) { this->configure_entity_(name, object_id_hash, 0); }
|
||||
};
|
||||
|
||||
TEST(EntityBaseName, ZeroHashIsComputedFromTheName) {
|
||||
TestEntity entity;
|
||||
entity.configure("Living Room Temp", 0);
|
||||
EXPECT_EQ(entity.get_object_id_hash(), fnv1_hash_object_id("Living Room Temp", 16));
|
||||
}
|
||||
|
||||
TEST(EntityBaseName, PrecomputedHashIsKept) {
|
||||
TestEntity entity;
|
||||
entity.configure("Living Room Temp", 0x1234);
|
||||
EXPECT_EQ(entity.get_object_id_hash(), 0x1234u);
|
||||
}
|
||||
|
||||
} // namespace esphome::core::testing
|
||||
|
||||
Reference in New Issue
Block a user