mirror of
https://github.com/esphome/esphome.git
synced 2025-10-23 12:13:49 +01:00
fixes
This commit is contained in:
@@ -1415,11 +1415,15 @@ class RepeatedTypeInfo(TypeInfo):
|
||||
super().__init__(field)
|
||||
# Check if this is a pointer field by looking for container_pointer option
|
||||
self._container_type = get_field_opt(field, pb.container_pointer, "")
|
||||
self._use_pointer = bool(self._container_type)
|
||||
# Check for non-template container pointer
|
||||
self._container_no_template = get_field_opt(
|
||||
field, pb.container_pointer_no_template, ""
|
||||
)
|
||||
self._use_pointer = bool(self._container_type) or bool(
|
||||
self._container_no_template
|
||||
)
|
||||
# Check if this should use FixedVector instead of std::vector
|
||||
self._use_fixed_vector = get_field_opt(field, pb.fixed_vector, False)
|
||||
# Check if this should be encoded as a bitmask
|
||||
self._use_bitmask = get_field_opt(field, pb.enum_as_bitmask, False)
|
||||
|
||||
# For repeated fields, we need to get the base type info
|
||||
# but we can't call create_field_type_info as it would cause recursion
|
||||
@@ -1436,15 +1440,18 @@ class RepeatedTypeInfo(TypeInfo):
|
||||
|
||||
@property
|
||||
def cpp_type(self) -> str:
|
||||
if self._use_bitmask:
|
||||
# For bitmask fields, store as a single uint32_t
|
||||
return "uint32_t"
|
||||
if self._container_no_template:
|
||||
# Non-template container: use type as-is without appending template parameters
|
||||
return f"const {self._container_no_template}*"
|
||||
if self._use_pointer and self._container_type:
|
||||
# For pointer fields, use the specified container type
|
||||
# If the container type already includes the element type (e.g., std::set<climate::ClimateMode>)
|
||||
# use it as-is, otherwise append the element type
|
||||
# Two cases:
|
||||
# 1. "std::set<climate::ClimateMode>" - Full type with template params, use as-is
|
||||
# 2. "std::set" - No <>, append the element type
|
||||
if "<" in self._container_type and ">" in self._container_type:
|
||||
# Has template parameters specified, use as-is
|
||||
return f"const {self._container_type}*"
|
||||
# No <> at all, append element type
|
||||
return f"const {self._container_type}<{self._ti.cpp_type}>*"
|
||||
if self._use_fixed_vector:
|
||||
return f"FixedVector<{self._ti.cpp_type}>"
|
||||
@@ -1471,11 +1478,6 @@ class RepeatedTypeInfo(TypeInfo):
|
||||
# Pointer fields don't support decoding
|
||||
if self._use_pointer:
|
||||
return None
|
||||
if self._use_bitmask:
|
||||
# Bitmask fields don't support decoding (only used for device->client messages)
|
||||
raise RuntimeError(
|
||||
f"enum_as_bitmask fields do not support decoding: {self.field_name}"
|
||||
)
|
||||
content = self._ti.decode_varint
|
||||
if content is None:
|
||||
return None
|
||||
@@ -1529,21 +1531,6 @@ class RepeatedTypeInfo(TypeInfo):
|
||||
|
||||
@property
|
||||
def encode_content(self) -> str:
|
||||
if self._use_bitmask:
|
||||
# For bitmask fields, iterate through set bits and encode each enum value
|
||||
# The bitmask is stored as uint32_t where bit N represents enum value N
|
||||
# Note: We iterate through all 32 bits to support the full range of enum_as_bitmask
|
||||
# (enums with up to 32 values). Specific uses may have fewer values, but the
|
||||
# generated code is general-purpose.
|
||||
assert isinstance(self._ti, EnumType), (
|
||||
"enum_as_bitmask only works with enum fields"
|
||||
)
|
||||
o = "for (uint8_t bit = 0; bit < 32; bit++) {\n"
|
||||
o += f" if (this->{self.field_name} & (1U << bit)) {{\n"
|
||||
o += f" buffer.{self._ti.encode_func}({self.number}, bit, true);\n"
|
||||
o += " }\n"
|
||||
o += "}"
|
||||
return o
|
||||
if self._use_pointer:
|
||||
# For pointer fields, just dereference (pointer should never be null in our use case)
|
||||
o = f"for (const auto &it : *this->{self.field_name}) {{\n"
|
||||
@@ -1563,13 +1550,6 @@ class RepeatedTypeInfo(TypeInfo):
|
||||
|
||||
@property
|
||||
def dump_content(self) -> str:
|
||||
if self._use_bitmask:
|
||||
# For bitmask fields, dump the hex value of the bitmask
|
||||
return (
|
||||
f"char buffer[64];\n"
|
||||
f'snprintf(buffer, sizeof(buffer), " {self.field_name}: 0x%08" PRIX32 "\\n", this->{self.field_name});\n'
|
||||
f"out.append(buffer);"
|
||||
)
|
||||
if self._use_pointer:
|
||||
# For pointer fields, dereference and use the existing helper
|
||||
return _generate_array_dump_content(
|
||||
@@ -1586,21 +1566,6 @@ class RepeatedTypeInfo(TypeInfo):
|
||||
# For repeated fields, we always need to pass force=True to the underlying type's calculation
|
||||
# This is because the encode method always sets force=true for repeated fields
|
||||
|
||||
if self._use_bitmask:
|
||||
# For bitmask fields, iterate through set bits and calculate size
|
||||
# Each set bit encodes one enum value (as varint)
|
||||
# Note: We iterate through all 32 bits to support the full range of enum_as_bitmask
|
||||
# (enums with up to 32 values). Specific uses may have fewer values, but the
|
||||
# generated code is general-purpose.
|
||||
o = f"if ({name} != 0) {{\n"
|
||||
o += " for (uint8_t bit = 0; bit < 32; bit++) {\n"
|
||||
o += f" if ({name} & (1U << bit)) {{\n"
|
||||
o += f" {self._ti.get_size_calculation('bit', True)}\n"
|
||||
o += " }\n"
|
||||
o += " }\n"
|
||||
o += "}"
|
||||
return o
|
||||
|
||||
# Handle message types separately as they use a dedicated helper
|
||||
if isinstance(self._ti, MessageType):
|
||||
field_id_size = self._ti.calculate_field_id_size()
|
||||
|
||||
Reference in New Issue
Block a user