From 8b96696c7658ff1a7d9076487410b3dafe2aff06 Mon Sep 17 00:00:00 2001 From: Vojtech Bocek Date: Tue, 23 Apr 2024 19:06:54 +0200 Subject: [PATCH] feat: reduce memory usage --- src/builder/arm.h | 2 +- src/builder/widget.cpp | 5 ++--- src/builder/widget.h | 3 +-- src/gridui.cpp | 47 ++++++++++++++++++++++++++++++------------ src/gridui.h | 2 +- src/widgets/widget.cpp | 4 +++- 6 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/builder/arm.h b/src/builder/arm.h index 874192ca..48f395d2 100644 --- a/src/builder/arm.h +++ b/src/builder/arm.h @@ -33,7 +33,7 @@ class Arm : public Widget, public BuilderMixin { } protected: - virtual void serialize(std::stringstream& ss) { + virtual void serialize(std::ostream& ss) { Widget::serialize(ss); extra().remove("info"); } diff --git a/src/builder/widget.cpp b/src/builder/widget.cpp index 47a9eb9b..be7024c4 100644 --- a/src/builder/widget.cpp +++ b/src/builder/widget.cpp @@ -10,8 +10,7 @@ namespace builder { Widget::Widget(const char* type, WidgetState& state) : m_state(state) - , m_type(type) - , m_style(nullptr) { + , m_type(type) { } Widget::~Widget() { @@ -30,7 +29,7 @@ rbjson::Object& Widget::style() { return *res; } -void Widget::serialize(std::stringstream& ss) { +void Widget::serialize(std::ostream& ss) { ss << "{"; { ss << "\"uuid\":" << m_state.uuid() << ","; diff --git a/src/builder/widget.h b/src/builder/widget.h index bfa73cdc..5ddb5154 100644 --- a/src/builder/widget.h +++ b/src/builder/widget.h @@ -84,7 +84,7 @@ class Widget { protected: Widget(const char* type, WidgetState& state); - virtual void serialize(std::stringstream& ss); + virtual void serialize(std::ostream& ss); rbjson::Object& extra(); rbjson::Object& style(); @@ -96,7 +96,6 @@ class Widget { Widget& operator=(const Widget&) = delete; const char* m_type; - rbjson::Object* m_style; }; }; diff --git a/src/gridui.cpp b/src/gridui.cpp index 314313fe..fb6a71af 100644 --- a/src/gridui.cpp +++ b/src/gridui.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "gridui.h" #include "rbdns.h" @@ -164,34 +165,54 @@ void _GridUi::commit() { return; } - std::vector layout_json; { - std::stringstream ss; - m_layout->serialize(ss); + + char buf[256]; + + snprintf(buf, sizeof(buf), "%s/layout.json", rb_web_get_files_root()); + + std::ofstream stream; + stream.rdbuf()->pubsetbuf(buf, sizeof(buf)); + stream.open(buf, std::ofstream::trunc); + + if(stream.fail()) { + ESP_LOGE("GridUI", "failed to open %s", buf); + return; + } + + m_states.shrink_to_fit(); + + m_layout->serialize(stream); m_layout.reset(); - ss.seekp(-1, std::stringstream::cur); + stream.seekp(-1, std::ofstream::cur); - ss << ",\"widgets\": ["; + stream << ",\"widgets\": ["; for (size_t i = 0; i < m_widgets.size(); ++i) { if (i != 0) { - ss << ","; + stream << ","; } + auto& w = m_widgets[i]; - w->serialize(ss); + w->serialize(stream); w.reset(); } m_widgets.clear(); m_widgets.shrink_to_fit(); - m_states.shrink_to_fit(); - ss << "]}"; + stream << "]}"; - layout_json.resize(((size_t)ss.tellp()) + 1); - ss.get(layout_json.data(), layout_json.size()); - } + if(stream.fail()) { + ESP_LOGE("GridUI", "failed to serialize layout"); + return; + } - ESP_ERROR_CHECK(rb_web_add_file("layout.json", layout_json.data(), layout_json.size() - 1)); + stream.close(); + if(stream.fail()) { + ESP_LOGE("GridUI", "failed to write layout"); + return; + } + } esp_timer_create_args_t args = { .callback = stateChangeTask, diff --git a/src/gridui.h b/src/gridui.h index 8c9e870e..ec3e3f19 100644 --- a/src/gridui.h +++ b/src/gridui.h @@ -160,7 +160,7 @@ class _GridUi { m_states.emplace_back(std::unique_ptr(state)); auto* widget = new T(T::name(), *state); - m_widgets.push_back(std::unique_ptr(widget)); + m_widgets.emplace_back(std::unique_ptr(widget)); return widget; } diff --git a/src/widgets/widget.cpp b/src/widgets/widget.cpp index 74f3de0c..c41517ca 100644 --- a/src/widgets/widget.cpp +++ b/src/widgets/widget.cpp @@ -19,7 +19,9 @@ WidgetState::WidgetState(uint16_t uuid, float x, float y, float w, float h, uint m_data.set("y", y); m_data.set("w", w); m_data.set("h", h); - m_data.set("tab", tab); + if(tab != 0) { + m_data.set("tab", tab); + } } bool WidgetState::set(const std::string& key, rbjson::Value* value) {