mirror of
https://github.com/esphome/esphome.git
synced 2025-07-29 22:56:37 +00:00
[api] Remove unnecessary string copies from optional access
This commit is contained in:
parent
bacb6a2c11
commit
37ca91e984
@ -243,21 +243,7 @@ void APIConnection::loop() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (state_subs_at_ >= 0) {
|
if (state_subs_at_ >= 0) {
|
||||||
const auto &subs = this->parent_->get_state_subs();
|
this->process_state_subscriptions_();
|
||||||
if (state_subs_at_ < static_cast<int>(subs.size())) {
|
|
||||||
auto &it = subs[state_subs_at_];
|
|
||||||
SubscribeHomeAssistantStateResponse resp;
|
|
||||||
resp.set_entity_id(StringRef(it.entity_id));
|
|
||||||
// attribute.value() returns temporary - must store it
|
|
||||||
std::string attribute_value = it.attribute.value();
|
|
||||||
resp.set_attribute(StringRef(attribute_value));
|
|
||||||
resp.once = it.once;
|
|
||||||
if (this->send_message(resp, SubscribeHomeAssistantStateResponse::MESSAGE_TYPE)) {
|
|
||||||
state_subs_at_++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
state_subs_at_ = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -642,17 +628,13 @@ uint16_t APIConnection::try_send_climate_state(EntityBase *entity, APIConnection
|
|||||||
if (traits.get_supports_fan_modes() && climate->fan_mode.has_value())
|
if (traits.get_supports_fan_modes() && climate->fan_mode.has_value())
|
||||||
resp.fan_mode = static_cast<enums::ClimateFanMode>(climate->fan_mode.value());
|
resp.fan_mode = static_cast<enums::ClimateFanMode>(climate->fan_mode.value());
|
||||||
if (!traits.get_supported_custom_fan_modes().empty() && climate->custom_fan_mode.has_value()) {
|
if (!traits.get_supported_custom_fan_modes().empty() && climate->custom_fan_mode.has_value()) {
|
||||||
// custom_fan_mode.value() returns temporary - must store it
|
resp.set_custom_fan_mode(StringRef(climate->custom_fan_mode.value()));
|
||||||
std::string custom_fan_mode = climate->custom_fan_mode.value();
|
|
||||||
resp.set_custom_fan_mode(StringRef(custom_fan_mode));
|
|
||||||
}
|
}
|
||||||
if (traits.get_supports_presets() && climate->preset.has_value()) {
|
if (traits.get_supports_presets() && climate->preset.has_value()) {
|
||||||
resp.preset = static_cast<enums::ClimatePreset>(climate->preset.value());
|
resp.preset = static_cast<enums::ClimatePreset>(climate->preset.value());
|
||||||
}
|
}
|
||||||
if (!traits.get_supported_custom_presets().empty() && climate->custom_preset.has_value()) {
|
if (!traits.get_supported_custom_presets().empty() && climate->custom_preset.has_value()) {
|
||||||
// custom_preset.value() returns temporary - must store it
|
resp.set_custom_preset(StringRef(climate->custom_preset.value()));
|
||||||
std::string custom_preset = climate->custom_preset.value();
|
|
||||||
resp.set_custom_preset(StringRef(custom_preset));
|
|
||||||
}
|
}
|
||||||
if (traits.get_supports_swing_modes())
|
if (traits.get_supports_swing_modes())
|
||||||
resp.swing_mode = static_cast<enums::ClimateSwingMode>(climate->swing_mode);
|
resp.swing_mode = static_cast<enums::ClimateSwingMode>(climate->swing_mode);
|
||||||
@ -1836,5 +1818,27 @@ uint16_t APIConnection::try_send_ping_request(EntityBase *entity, APIConnection
|
|||||||
return encode_message_to_buffer(req, PingRequest::MESSAGE_TYPE, conn, remaining_size, is_single);
|
return encode_message_to_buffer(req, PingRequest::MESSAGE_TYPE, conn, remaining_size, is_single);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void APIConnection::process_state_subscriptions_() {
|
||||||
|
const auto &subs = this->parent_->get_state_subs();
|
||||||
|
if (this->state_subs_at_ >= static_cast<int>(subs.size())) {
|
||||||
|
this->state_subs_at_ = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto &it = subs[this->state_subs_at_];
|
||||||
|
SubscribeHomeAssistantStateResponse resp;
|
||||||
|
resp.set_entity_id(StringRef(it.entity_id));
|
||||||
|
|
||||||
|
// Avoid string copy by directly using the optional's value if it exists
|
||||||
|
if (it.attribute.has_value()) {
|
||||||
|
resp.set_attribute(StringRef(it.attribute.value()));
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.once = it.once;
|
||||||
|
if (this->send_message(resp, SubscribeHomeAssistantStateResponse::MESSAGE_TYPE)) {
|
||||||
|
this->state_subs_at_++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace esphome::api
|
} // namespace esphome::api
|
||||||
#endif
|
#endif
|
||||||
|
@ -288,6 +288,9 @@ class APIConnection : public APIServerConnection {
|
|||||||
// Helper function to handle authentication completion
|
// Helper function to handle authentication completion
|
||||||
void complete_authentication_();
|
void complete_authentication_();
|
||||||
|
|
||||||
|
// Process state subscriptions efficiently
|
||||||
|
void process_state_subscriptions_();
|
||||||
|
|
||||||
// Non-template helper to encode any ProtoMessage
|
// Non-template helper to encode any ProtoMessage
|
||||||
static uint16_t encode_message_to_buffer(ProtoMessage &msg, uint8_t message_type, APIConnection *conn,
|
static uint16_t encode_message_to_buffer(ProtoMessage &msg, uint8_t message_type, APIConnection *conn,
|
||||||
uint32_t remaining_size, bool is_single);
|
uint32_t remaining_size, bool is_single);
|
||||||
|
@ -35,11 +35,10 @@ namespace esphome::api {
|
|||||||
*
|
*
|
||||||
* Unsafe Patterns (WILL cause crashes/corruption):
|
* Unsafe Patterns (WILL cause crashes/corruption):
|
||||||
* 1. Temporaries: msg.set_field(StringRef(obj.get_string())) // get_string() returns by value
|
* 1. Temporaries: msg.set_field(StringRef(obj.get_string())) // get_string() returns by value
|
||||||
* 2. Optional values: msg.set_field(StringRef(optional.value())) // value() returns a copy
|
* 2. Concatenation: msg.set_field(StringRef(str1 + str2)) // Result is temporary
|
||||||
* 3. Concatenation: msg.set_field(StringRef(str1 + str2)) // Result is temporary
|
|
||||||
*
|
*
|
||||||
* For unsafe patterns, store in a local variable first:
|
* For unsafe patterns, store in a local variable first:
|
||||||
* std::string temp = optional.value(); // or get_string() or str1 + str2
|
* std::string temp = get_string(); // or str1 + str2
|
||||||
* msg.set_field(StringRef(temp));
|
* msg.set_field(StringRef(temp));
|
||||||
*
|
*
|
||||||
* The send_*_response pattern ensures proper lifetime management by encoding
|
* The send_*_response pattern ensures proper lifetime management by encoding
|
||||||
|
Loading…
x
Reference in New Issue
Block a user