mirror of
https://github.com/esphome/esphome.git
synced 2025-10-21 11:13:46 +01:00
no vector
This commit is contained in:
@@ -506,7 +506,7 @@ message ListEntitiesLightResponse {
|
|||||||
string name = 3;
|
string name = 3;
|
||||||
reserved 4; // Deprecated: was string unique_id
|
reserved 4; // Deprecated: was string unique_id
|
||||||
|
|
||||||
repeated ColorMode supported_color_modes = 12 [(fixed_vector) = true];
|
repeated ColorMode supported_color_modes = 12 [(enum_as_bitmask) = true];
|
||||||
// next four supports_* are for legacy clients, newer clients should use color modes
|
// next four supports_* are for legacy clients, newer clients should use color modes
|
||||||
// Deprecated in API version 1.6
|
// Deprecated in API version 1.6
|
||||||
bool legacy_supports_brightness = 5 [deprecated=true];
|
bool legacy_supports_brightness = 5 [deprecated=true];
|
||||||
|
@@ -70,4 +70,13 @@ extend google.protobuf.FieldOptions {
|
|||||||
// init(size) before adding elements. This eliminates std::vector template overhead
|
// init(size) before adding elements. This eliminates std::vector template overhead
|
||||||
// and is ideal when the exact size is known before populating the array.
|
// and is ideal when the exact size is known before populating the array.
|
||||||
optional bool fixed_vector = 50013 [default=false];
|
optional bool fixed_vector = 50013 [default=false];
|
||||||
|
|
||||||
|
// enum_as_bitmask: Encode repeated enum fields as a uint32_t bitmask
|
||||||
|
// When set on a repeated enum field, the field will be stored as a single uint32_t
|
||||||
|
// where each bit represents whether that enum value is present. This is ideal for
|
||||||
|
// enums with ≤32 values and eliminates all vector template instantiation overhead.
|
||||||
|
// The enum values should be sequential starting from 0.
|
||||||
|
// Encoding: bit N set means enum value N is present in the set.
|
||||||
|
// Example: {ColorMode::RGB, ColorMode::WHITE} → bitmask with bits 5 and 6 set
|
||||||
|
optional bool enum_as_bitmask = 50014 [default=false];
|
||||||
}
|
}
|
||||||
|
@@ -471,8 +471,10 @@ void ListEntitiesLightResponse::encode(ProtoWriteBuffer buffer) const {
|
|||||||
buffer.encode_string(1, this->object_id_ref_);
|
buffer.encode_string(1, this->object_id_ref_);
|
||||||
buffer.encode_fixed32(2, this->key);
|
buffer.encode_fixed32(2, this->key);
|
||||||
buffer.encode_string(3, this->name_ref_);
|
buffer.encode_string(3, this->name_ref_);
|
||||||
for (auto &it : this->supported_color_modes) {
|
for (uint8_t bit = 0; bit < 32; bit++) {
|
||||||
buffer.encode_uint32(12, static_cast<uint32_t>(it), true);
|
if (this->supported_color_modes & (1U << bit)) {
|
||||||
|
buffer.encode_uint32(12, bit, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buffer.encode_float(9, this->min_mireds);
|
buffer.encode_float(9, this->min_mireds);
|
||||||
buffer.encode_float(10, this->max_mireds);
|
buffer.encode_float(10, this->max_mireds);
|
||||||
@@ -492,9 +494,11 @@ void ListEntitiesLightResponse::calculate_size(ProtoSize &size) const {
|
|||||||
size.add_length(1, this->object_id_ref_.size());
|
size.add_length(1, this->object_id_ref_.size());
|
||||||
size.add_fixed32(1, this->key);
|
size.add_fixed32(1, this->key);
|
||||||
size.add_length(1, this->name_ref_.size());
|
size.add_length(1, this->name_ref_.size());
|
||||||
if (!this->supported_color_modes.empty()) {
|
if (this->supported_color_modes != 0) {
|
||||||
for (const auto &it : this->supported_color_modes) {
|
for (uint8_t bit = 0; bit < 32; bit++) {
|
||||||
size.add_uint32_force(1, static_cast<uint32_t>(it));
|
if (this->supported_color_modes & (1U << bit)) {
|
||||||
|
size.add_uint32_force(1, static_cast<uint32_t>(bit));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
size.add_float(1, this->min_mireds);
|
size.add_float(1, this->min_mireds);
|
||||||
|
@@ -790,7 +790,7 @@ class ListEntitiesLightResponse final : public InfoResponseProtoMessage {
|
|||||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||||
const char *message_name() const override { return "list_entities_light_response"; }
|
const char *message_name() const override { return "list_entities_light_response"; }
|
||||||
#endif
|
#endif
|
||||||
FixedVector<enums::ColorMode> supported_color_modes{};
|
uint32_t supported_color_modes{};
|
||||||
float min_mireds{0.0f};
|
float min_mireds{0.0f};
|
||||||
float max_mireds{0.0f};
|
float max_mireds{0.0f};
|
||||||
std::vector<std::string> effects{};
|
std::vector<std::string> effects{};
|
||||||
|
@@ -913,9 +913,9 @@ void ListEntitiesLightResponse::dump_to(std::string &out) const {
|
|||||||
dump_field(out, "object_id", this->object_id_ref_);
|
dump_field(out, "object_id", this->object_id_ref_);
|
||||||
dump_field(out, "key", this->key);
|
dump_field(out, "key", this->key);
|
||||||
dump_field(out, "name", this->name_ref_);
|
dump_field(out, "name", this->name_ref_);
|
||||||
for (const auto &it : this->supported_color_modes) {
|
out.append(" supported_color_modes: 0x");
|
||||||
dump_field(out, "supported_color_modes", static_cast<enums::ColorMode>(it), 4);
|
out.append(uint32_to_string(this->supported_color_modes));
|
||||||
}
|
out.append("\n");
|
||||||
dump_field(out, "min_mireds", this->min_mireds);
|
dump_field(out, "min_mireds", this->min_mireds);
|
||||||
dump_field(out, "max_mireds", this->max_mireds);
|
dump_field(out, "max_mireds", this->max_mireds);
|
||||||
for (const auto &it : this->effects) {
|
for (const auto &it : this->effects) {
|
||||||
|
@@ -1418,6 +1418,8 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
self._use_pointer = bool(self._container_type)
|
self._use_pointer = bool(self._container_type)
|
||||||
# Check if this should use FixedVector instead of std::vector
|
# Check if this should use FixedVector instead of std::vector
|
||||||
self._use_fixed_vector = get_field_opt(field, pb.fixed_vector, False)
|
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
|
# 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
|
# but we can't call create_field_type_info as it would cause recursion
|
||||||
@@ -1434,6 +1436,9 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def cpp_type(self) -> str:
|
def cpp_type(self) -> str:
|
||||||
|
if self._use_bitmask:
|
||||||
|
# For bitmask fields, store as a single uint32_t
|
||||||
|
return "uint32_t"
|
||||||
if self._use_pointer and self._container_type:
|
if self._use_pointer and self._container_type:
|
||||||
# For pointer fields, use the specified 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>)
|
# If the container type already includes the element type (e.g., std::set<climate::ClimateMode>)
|
||||||
@@ -1466,6 +1471,12 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
# Pointer fields don't support decoding
|
# Pointer fields don't support decoding
|
||||||
if self._use_pointer:
|
if self._use_pointer:
|
||||||
return None
|
return None
|
||||||
|
if self._use_bitmask:
|
||||||
|
# For bitmask fields, decode enum value and set corresponding bit
|
||||||
|
content = self._ti.decode_varint
|
||||||
|
if content is None:
|
||||||
|
return None
|
||||||
|
return f"case {self.number}: this->{self.field_name} |= (1U << static_cast<uint8_t>({content})); break;"
|
||||||
content = self._ti.decode_varint
|
content = self._ti.decode_varint
|
||||||
if content is None:
|
if content is None:
|
||||||
return None
|
return None
|
||||||
@@ -1519,6 +1530,18 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def encode_content(self) -> str:
|
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
|
||||||
|
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:
|
if self._use_pointer:
|
||||||
# For pointer fields, just dereference (pointer should never be null in our use case)
|
# 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"
|
o = f"for (const auto &it : *this->{self.field_name}) {{\n"
|
||||||
@@ -1538,6 +1561,13 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def dump_content(self) -> str:
|
def dump_content(self) -> str:
|
||||||
|
if self._use_bitmask:
|
||||||
|
# For bitmask fields, dump the hex value of the bitmask
|
||||||
|
return (
|
||||||
|
f'out.append(" {self.field_name}: 0x");\n'
|
||||||
|
f"out.append(uint32_to_string(this->{self.field_name}));\n"
|
||||||
|
f'out.append("\\n");'
|
||||||
|
)
|
||||||
if self._use_pointer:
|
if self._use_pointer:
|
||||||
# For pointer fields, dereference and use the existing helper
|
# For pointer fields, dereference and use the existing helper
|
||||||
return _generate_array_dump_content(
|
return _generate_array_dump_content(
|
||||||
@@ -1554,6 +1584,18 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
# For repeated fields, we always need to pass force=True to the underlying type's calculation
|
# 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
|
# 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)
|
||||||
|
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
|
# Handle message types separately as they use a dedicated helper
|
||||||
if isinstance(self._ti, MessageType):
|
if isinstance(self._ti, MessageType):
|
||||||
field_id_size = self._ti.calculate_field_id_size()
|
field_id_size = self._ti.calculate_field_id_size()
|
||||||
|
Reference in New Issue
Block a user