From c2d72b08f373146dfba3cbd0592bd7c7aaa10c54 Mon Sep 17 00:00:00 2001 From: Michael Davidson Date: Sun, 25 Feb 2024 21:30:45 +1100 Subject: [PATCH] Switch to using shared_ptr for Text Runs being added to the TextRunPanel --- .../graphical_layout/text_run_panel.cpp | 4 +- .../graphical_layout/text_run_panel.h | 8 ++-- .../graphical_layout/text_run_panel.py | 46 ++++++++++++++++--- 3 files changed, 45 insertions(+), 13 deletions(-) diff --git a/esphome/components/graphical_layout/text_run_panel.cpp b/esphome/components/graphical_layout/text_run_panel.cpp index e584865c8f..b793eae1e4 100644 --- a/esphome/components/graphical_layout/text_run_panel.cpp +++ b/esphome/components/graphical_layout/text_run_panel.cpp @@ -21,7 +21,7 @@ void TextRunPanel::dump_config(int indent_depth, int additional_level_depth) { LOG_STR_ARG(display::text_align_to_string(this->text_align_))); ESP_LOGCONFIG(TAG, "%*sDraw Partial Lines: %s", indent_depth, "", YESNO(this->draw_partial_lines_)); ESP_LOGCONFIG(TAG, "%*sText Runs: %i", indent_depth, "", this->text_runs_.size()); - for (TextRunBase *run : this->text_runs_) { + for (const auto &run : this->text_runs_) { std::string text = run->get_text(); ESP_LOGCONFIG(TAG, "%*sText: %s", indent_depth + additional_level_depth, "", text.c_str()); } @@ -85,7 +85,7 @@ void TextRunPanel::render_internal(display::Display *display, display::Rect boun std::vector> TextRunPanel::split_runs_into_words_() { std::vector> runs; - for (TextRunBase *run : this->text_runs_) { + for (const auto &run : this->text_runs_) { std::string text = run->get_text(); CanWrapAtCharacterArguments can_wrap_at_args(this, 0, text, ' '); diff --git a/esphome/components/graphical_layout/text_run_panel.h b/esphome/components/graphical_layout/text_run_panel.h index fbd6e446d6..6da76ba97a 100644 --- a/esphome/components/graphical_layout/text_run_panel.h +++ b/esphome/components/graphical_layout/text_run_panel.h @@ -174,7 +174,7 @@ struct RunProperties { class CalculatedTextRun { public: - CalculatedTextRun(TextRunBase *run, RunProperties run_properties) { + CalculatedTextRun(std::shared_ptr run, RunProperties run_properties) { this->run = run; this->run_properties = run_properties; } @@ -193,7 +193,7 @@ class CalculatedTextRun { std::string text{}; display::Rect bounds{}; - TextRunBase *run{nullptr}; + std::shared_ptr run{}; int16_t baseline{0}; RunProperties run_properties{}; }; @@ -258,7 +258,7 @@ class TextRunPanel : public LayoutItem { this->can_wrap_at_character_ = can_wrap_at_character; }; - void add_text_run(TextRunBase *text_run) { this->text_runs_.push_back(text_run); }; + void add_text_run(std::shared_ptr text_run) { this->text_runs_.push_back(text_run); }; void set_text_align(display::TextAlign text_align) { this->text_align_ = text_align; }; void set_min_width(int min_width) { this->min_width_ = min_width; }; void set_max_width(int max_width) { this->max_width_ = max_width; }; @@ -274,7 +274,7 @@ class TextRunPanel : public LayoutItem { void apply_alignment_to_lines_(std::vector> &lines, display::TextAlign alignment); CharacterProperties get_character_properties_(char character); - std::vector text_runs_; + std::vector> text_runs_; display::TextAlign text_align_{display::TextAlign::TOP_LEFT}; int min_width_{0}; int max_width_{0}; diff --git a/esphome/components/graphical_layout/text_run_panel.py b/esphome/components/graphical_layout/text_run_panel.py index 2295b92138..e72689a21a 100644 --- a/esphome/components/graphical_layout/text_run_panel.py +++ b/esphome/components/graphical_layout/text_run_panel.py @@ -1,4 +1,6 @@ import esphome.codegen as cg +from esphome.cpp_generator import CallExpression, MockObjClass, MockObj +from esphome.core import ID import esphome.config_validation as cv from esphome.components import font, color, sensor, text_sensor, time from esphome.components.display import display_ns @@ -10,6 +12,8 @@ from esphome.const import ( CONF_TIME_ID, ) + +SharedPtr = cg.std_ns.class_("shared_ptr") graphical_layout_ns = cg.esphome_ns.namespace("graphical_layout") TextRunPanel = graphical_layout_ns.class_("TextRunPanel") TextAlign = display_ns.enum("TextAlign", is_class=True) @@ -130,6 +134,20 @@ def get_config_schema(base_item_schema, item_type_schema): ) +def build_text_run_base_shared_ptr( + id_: ID, type: MockObjClass, *make_shared_args +) -> MockObj: + make_shared = CallExpression( + cg.RawExpression("std::make_shared"), + cg.TemplateArguments(type), + *make_shared_args, + ) + shared_ptr = cg.new_variable(id_, make_shared, SharedPtr.template(type)) + shared_ptr.op = "->" + + return shared_ptr + + async def config_to_layout_item(pvariable_builder, item_config, child_item_builder): var = await pvariable_builder(item_config) @@ -162,28 +180,42 @@ async def config_to_layout_item(pvariable_builder, item_config, child_item_build run_font = await cg.get_variable(run_config[CONF_FONT]) if run_sensor_config := run_config.get(CONF_SENSOR): sens = await cg.get_variable(run_sensor_config) - run = cg.new_Pvariable(run_config[CONF_ID], sens, run_font) + run = build_text_run_base_shared_ptr( + run_config[CONF_ID], SensorTextRun, sens, run_font + ) elif run_text_sensor_config := run_config.get(CONF_TEXT_SENSOR): text_sens = await cg.get_variable(run_text_sensor_config) - run = cg.new_Pvariable(run_config[CONF_ID], text_sens, run_font) + run = build_text_run_base_shared_ptr( + run_config[CONF_ID], TextSensorTextRun, text_sens, run_font + ) elif run_time_id_config := run_config.get(CONF_TIME_ID): time_sens = await cg.get_variable(run_time_id_config) time_format = await cg.templatable( run_config[CONF_TIME_FORMAT], args=[], output_type=cg.std_string ) use_utc_time = run_config[CONF_USE_UTC_TIME] - run = cg.new_Pvariable( - run_config[CONF_ID], time_sens, time_format, use_utc_time, run_font + run = build_text_run_base_shared_ptr( + run_config[CONF_ID], + TimeTextRun, + time_sens, + time_format, + use_utc_time, + run_font, ) elif paragraph_break_config := run_config.get(CONF_PARAGRAPH_BREAK): - run = cg.new_Pvariable( - run_config[CONF_ID], paragraph_break_config, run_font + run = build_text_run_base_shared_ptr( + run_config[CONF_ID], + ParagraphBreakTextRun, + paragraph_break_config, + run_font, ) else: run_text = await cg.templatable( run_config[CONF_TEXT], args=[], output_type=cg.std_string ) - run = cg.new_Pvariable(run_config[CONF_ID], run_text, run_font) + run = build_text_run_base_shared_ptr( + run_config[CONF_ID], TextRun, run_text, run_font + ) if run_text_formatter_config := run_config.get(CONF_TEXT_FORMATTER): run_text_formatter = await cg.process_lambda(