mirror of
https://github.com/emsesp/EMS-ESP32.git
synced 2026-07-29 10:02:48 +00:00
Reduce DeviceValue heap usage with on-demand custom name
Store the per-entity custom_fullname as a heap-allocated string that is only created when a custom name is actually set, instead of an inline std::string on every DeviceValue. Saves ~20 bytes per entity (hundreds to ~1000 entities), reclaiming internal heap on no-PSRAM boards. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -47,7 +47,6 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
||||
, numeric_operator(numeric_operator)
|
||||
, short_name(short_name)
|
||||
, fullname(fullname)
|
||||
, custom_fullname(custom_fullname)
|
||||
, uom(uom)
|
||||
, has_cmd(has_cmd)
|
||||
, min(min)
|
||||
@@ -60,7 +59,12 @@ DeviceValue::DeviceValue(uint8_t device_type,
|
||||
options_size = Helpers::count_items(options);
|
||||
}
|
||||
|
||||
// set the min/max
|
||||
// store the custom name on the heap, but only if one was actually provided
|
||||
if (!custom_fullname.empty()) {
|
||||
custom_fullname_ = std::make_unique<std::string>(custom_fullname);
|
||||
}
|
||||
|
||||
// set the min/max (reads back the custom name set above)
|
||||
set_custom_minmax();
|
||||
|
||||
/*
|
||||
@@ -343,11 +347,12 @@ bool DeviceValue::get_min_max(int16_t & dv_set_min, uint32_t & dv_set_max) {
|
||||
|
||||
// extract custom min from custom_fullname
|
||||
bool DeviceValue::get_custom_min(int16_t & val) {
|
||||
auto min_pos = custom_fullname.find('>');
|
||||
bool has_min = (min_pos != std::string::npos);
|
||||
const auto & cf = custom_fullname();
|
||||
auto min_pos = cf.find('>');
|
||||
bool has_min = (min_pos != std::string::npos);
|
||||
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
|
||||
if (has_min) {
|
||||
int32_t v = Helpers::atoint(custom_fullname.substr(min_pos + 1).c_str());
|
||||
int32_t v = Helpers::atoint(cf.substr(min_pos + 1).c_str());
|
||||
if (fahrenheit) {
|
||||
v = (v - (32 * (fahrenheit - 1))) / 1.8; // reset to °C
|
||||
}
|
||||
@@ -361,11 +366,12 @@ bool DeviceValue::get_custom_min(int16_t & val) {
|
||||
|
||||
// extract custom max from custom_fullname
|
||||
bool DeviceValue::get_custom_max(uint32_t & val) {
|
||||
auto max_pos = custom_fullname.find('<');
|
||||
bool has_max = (max_pos != std::string::npos);
|
||||
const auto & cf = custom_fullname();
|
||||
auto max_pos = cf.find('<');
|
||||
bool has_max = (max_pos != std::string::npos);
|
||||
uint8_t fahrenheit = !EMSESP::system_.fahrenheit() ? 0 : (uom == DeviceValueUOM::DEGREES) ? 2 : (uom == DeviceValueUOM::DEGREES_R) ? 1 : 0;
|
||||
if (has_max) {
|
||||
int32_t v = Helpers::atoint(custom_fullname.substr(max_pos + 1).c_str());
|
||||
int32_t v = Helpers::atoint(cf.substr(max_pos + 1).c_str());
|
||||
if (fahrenheit) {
|
||||
v = (v - (32 * (fahrenheit - 1))) / 1.8; // reset to °C
|
||||
}
|
||||
@@ -383,14 +389,32 @@ void DeviceValue::set_custom_minmax() {
|
||||
get_custom_max(max);
|
||||
}
|
||||
|
||||
std::string DeviceValue::get_custom_fullname() const {
|
||||
auto min_pos = custom_fullname.find('>');
|
||||
auto max_pos = custom_fullname.find('<');
|
||||
auto minmax_pos = min_pos < max_pos ? min_pos : max_pos;
|
||||
if (minmax_pos != std::string::npos) {
|
||||
return custom_fullname.substr(0, minmax_pos);
|
||||
// raw stored custom name (empty string if none was set)
|
||||
const std::string & DeviceValue::custom_fullname() const {
|
||||
static const std::string empty_string;
|
||||
return custom_fullname_ ? *custom_fullname_ : empty_string;
|
||||
}
|
||||
|
||||
// set or clear the custom name, only allocating heap when there's actually a name
|
||||
void DeviceValue::set_custom_fullname(const std::string & name) {
|
||||
if (name.empty()) {
|
||||
custom_fullname_.reset();
|
||||
} else if (custom_fullname_) {
|
||||
*custom_fullname_ = name;
|
||||
} else {
|
||||
custom_fullname_ = std::make_unique<std::string>(name);
|
||||
}
|
||||
return custom_fullname;
|
||||
}
|
||||
|
||||
std::string DeviceValue::get_custom_fullname() const {
|
||||
const auto & cf = custom_fullname();
|
||||
auto min_pos = cf.find('>');
|
||||
auto max_pos = cf.find('<');
|
||||
auto minmax_pos = min_pos < max_pos ? min_pos : max_pos;
|
||||
if (minmax_pos != std::string::npos) {
|
||||
return cf.substr(0, minmax_pos);
|
||||
}
|
||||
return cf;
|
||||
}
|
||||
|
||||
// returns the translated fullname or the custom fullname (if provided)
|
||||
|
||||
Reference in New Issue
Block a user