1
0
mirror of https://github.com/esphome/esphome.git synced 2025-09-01 19:02:18 +01:00

[mapping] Use custom allocator (#9972)

This commit is contained in:
Clyde Stubbs
2025-08-29 10:52:37 +10:00
committed by GitHub
parent 461ce69296
commit bc960cf6d2
12 changed files with 152 additions and 59 deletions

View File

@@ -10,7 +10,8 @@ from esphome.loader import get_component
CODEOWNERS = ["@clydebarrow"]
MULTI_CONF = True
map_ = cg.std_ns.class_("map")
mapping_ns = cg.esphome_ns.namespace("mapping")
mapping_class = mapping_ns.class_("Mapping")
CONF_ENTRIES = "entries"
CONF_CLASS = "class"
@@ -29,7 +30,11 @@ class IndexType:
INDEX_TYPES = {
"int": IndexType(cv.int_, cg.int_, int),
"string": IndexType(cv.string, cg.std_string, str),
"string": IndexType(
cv.string,
cg.std_string,
str,
),
}
@@ -47,7 +52,7 @@ def to_schema(value):
BASE_SCHEMA = cv.Schema(
{
cv.Required(CONF_ID): cv.declare_id(map_),
cv.Required(CONF_ID): cv.declare_id(mapping_class),
cv.Required(CONF_FROM): cv.one_of(*INDEX_TYPES, lower=True),
cv.Required(CONF_TO): cv.string,
},
@@ -123,12 +128,15 @@ async def to_code(config):
if list(entries.values())[0].op != ".":
value_type = value_type.operator("ptr")
varid = config[CONF_ID]
varid.type = map_.template(index_type, value_type)
varid.type = mapping_class.template(
index_type,
value_type,
)
var = MockObj(varid, ".")
decl = VariableDeclarationExpression(varid.type, "", varid)
add_global(decl)
CORE.register_variable(varid, var)
for key, value in entries.items():
cg.add(var.insert((key, value)))
cg.add(var.set(key, value))
return var

View File

@@ -0,0 +1,69 @@
#pragma once
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include <map>
#include <string>
namespace esphome::mapping {
using alloc_string_t = std::basic_string<char, std::char_traits<char>, RAMAllocator<char>>;
/**
*
* Mapping class with custom allocator.
* Additionally, when std::string is used as key or value, it will be replaced with a custom string type
* that uses RAMAllocator.
* @tparam K The type of the key in the mapping.
* @tparam V The type of the value in the mapping. Should be a basic type or pointer.
*/
static const char *const TAG = "mapping";
template<typename K, typename V> class Mapping {
public:
// Constructor
Mapping() = default;
using key_t = const std::conditional_t<std::is_same_v<K, std::string>,
alloc_string_t, // if K is std::string, custom string type
K>;
using value_t = std::conditional_t<std::is_same_v<V, std::string>,
alloc_string_t, // if V is std::string, custom string type
V>;
void set(const K &key, const V &value) { this->map_[key_t{key}] = value; }
V get(const K &key) const {
auto it = this->map_.find(key_t{key});
if (it != this->map_.end()) {
return V{it->second};
}
if constexpr (std::is_pointer_v<K>) {
esph_log_e(TAG, "Key '%p' not found in mapping", key);
} else if constexpr (std::is_same_v<K, std::string>) {
esph_log_e(TAG, "Key '%s' not found in mapping", key.c_str());
} else {
esph_log_e(TAG, "Key '%s' not found in mapping", to_string(key).c_str());
}
return {};
}
// index map overload
V operator[](K key) { return this->get(key); }
// convenience function for strings to get a C-style string
template<typename T = V, std::enable_if_t<std::is_same_v<T, std::string>, int> = 0>
const char *operator[](K key) const {
auto it = this->map_.find(key_t{key});
if (it != this->map_.end()) {
return it->second.c_str(); // safe since value remains in map
}
return "";
}
protected:
std::map<key_t, value_t, std::less<key_t>, RAMAllocator<std::pair<key_t, value_t>>> map_;
};
} // namespace esphome::mapping

View File

@@ -0,0 +1 @@
*.ttf -text

View File

@@ -50,6 +50,14 @@ mapping:
red: red_id
blue: blue_id
green: green_id
- id: string_map_2
from: string
to: string
entries:
one: "one"
two: "two"
three: "three"
seventy-seven: "seventy-seven"
color:
- id: red_id
@@ -65,7 +73,14 @@ color:
green: 0.0
blue: 1.0
font:
- file: "$component_dir/helvetica.ttf"
id: font_id
size: 20
display:
lambda: |-
it.image(0, 0, id(weather_map)[0]);
it.image(0, 100, id(weather_map)[1]);
std::string value = id(int_map)[2];
it.print(0, 0, id(font_id), TextAlign::TOP_LEFT, value.c_str());
it.image(0, 0, id(weather_map)["clear-night"]);
it.image(0, 100, id(weather_map)["sunny"]);

Binary file not shown.

View File

@@ -4,14 +4,14 @@ spi:
mosi_pin: 17
miso_pin: 15
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 12
dc_pin: 13
reset_pin: 21
invert_colors: false
packages:
map: !include common.yaml
display:
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 12
dc_pin: 13
reset_pin: 21
invert_colors: false

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 5
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 8
dc_pin: 9
reset_pin: 10
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 8
dc_pin: 9
reset_pin: 10
invert_colors: false
packages:
map: !include common.yaml

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 5
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 8
dc_pin: 9
reset_pin: 10
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 8
dc_pin: 9
reset_pin: 10
invert_colors: false
packages:
map: !include common.yaml

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 15
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 12
dc_pin: 13
reset_pin: 21
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 12
dc_pin: 13
reset_pin: 21
invert_colors: false
packages:
map: !include common.yaml

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 12
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 5
dc_pin: 15
reset_pin: 16
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 5
dc_pin: 15
reset_pin: 16
invert_colors: false
packages:
map: !include common.yaml

View File

@@ -1,12 +1,12 @@
display:
- platform: sdl
id: sdl_display
update_interval: 1s
auto_clear_enabled: false
show_test_card: true
dimensions:
width: 450
height: 600
platform: sdl
id: sdl_display
update_interval: 1s
auto_clear_enabled: false
show_test_card: true
dimensions:
width: 450
height: 600
packages:
map: !include common.yaml

View File

@@ -5,13 +5,13 @@ spi:
miso_pin: 4
display:
- platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 20
dc_pin: 21
reset_pin: 22
invert_colors: false
platform: ili9xxx
id: main_lcd
model: ili9342
cs_pin: 20
dc_pin: 21
reset_pin: 22
invert_colors: false
packages:
map: !include common.yaml