From dcc2118d19add0417bf373021b38253e8a599a0c Mon Sep 17 00:00:00 2001 From: philmoz Date: Mon, 28 Aug 2023 12:55:15 +1000 Subject: [PATCH] chore(color): Replace dynamic_cast with virtual functions, disable RTTI to reduce FLASH usage (#3885) * Replace dynamic_cast with virtual functions and disable RTTI. * Cleanup TopBar class hierarchy. * Fix compiler warning. --- radio/src/CMakeLists.txt | 2 +- radio/src/gui/colorlcd/layout.cpp | 1 + .../gui/colorlcd/layouts/layout_factory_impl.h | 2 ++ radio/src/gui/colorlcd/layouts/topbar_impl.cpp | 18 +++++++++--------- radio/src/gui/colorlcd/layouts/topbar_impl.h | 12 ++++++------ radio/src/gui/colorlcd/screen_setup.cpp | 12 ++++++------ radio/src/gui/colorlcd/topbar.cpp | 6 +++--- radio/src/gui/colorlcd/topbar.h | 10 ++-------- radio/src/gui/colorlcd/view_main.cpp | 4 ++-- radio/src/gui/colorlcd/view_main.h | 6 +++--- radio/src/gui/colorlcd/widget.cpp | 7 +++---- radio/src/gui/colorlcd/widget.h | 2 ++ radio/src/gui/colorlcd/widgets_container.h | 3 +++ radio/src/lua/lua_widget_factory.h | 2 ++ radio/src/lua/widgets.cpp | 2 +- radio/src/thirdparty/libopenui/src/window.h | 3 +++ 16 files changed, 49 insertions(+), 43 deletions(-) diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 1e59d512c..890b80730 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -508,7 +508,7 @@ set(COMMON_FLAGS "${COMMON_FLAGS} -O${OPT} ${FPU_FLAGS}") set(COMMON_FLAGS "${COMMON_FLAGS} ${WARNING_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COMMON_FLAGS} -Wimplicit") -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMMON_FLAGS} -fno-rtti") # these are in addition to CMAKE_CXX_FLAGS set(CMAKE_EXE_LINKER_FLAGS "-lm -T${RADIO_SRC_DIR}/${LINKER_SCRIPT}") diff --git a/radio/src/gui/colorlcd/layout.cpp b/radio/src/gui/colorlcd/layout.cpp index 085e8f92c..cddf6fabe 100644 --- a/radio/src/gui/colorlcd/layout.cpp +++ b/radio/src/gui/colorlcd/layout.cpp @@ -21,6 +21,7 @@ #include "opentx.h" #include "view_main.h" +#include "topbar_impl.h" WidgetsContainer * customScreens[MAX_CUSTOM_SCREENS] = {}; diff --git a/radio/src/gui/colorlcd/layouts/layout_factory_impl.h b/radio/src/gui/colorlcd/layouts/layout_factory_impl.h index 2488d0a61..56d0d6251 100644 --- a/radio/src/gui/colorlcd/layouts/layout_factory_impl.h +++ b/radio/src/gui/colorlcd/layouts/layout_factory_impl.h @@ -113,6 +113,8 @@ class Layout: public LayoutBase // Updates settings for trims, sliders, pots, etc... void adjustLayout() override; + bool isLayout() override { return true; } + protected: const LayoutFactory * factory = nullptr; std::unique_ptr decoration; diff --git a/radio/src/gui/colorlcd/layouts/topbar_impl.cpp b/radio/src/gui/colorlcd/layouts/topbar_impl.cpp index 1fe83a107..d6d8d7b23 100644 --- a/radio/src/gui/colorlcd/layouts/topbar_impl.cpp +++ b/radio/src/gui/colorlcd/layouts/topbar_impl.cpp @@ -24,17 +24,17 @@ constexpr uint32_t TOPBAR_REFRESH = 1000 / 10; // 10 Hz -TopbarImpl::TopbarImpl(Window * parent) : - TopbarImplBase(parent, {0, 0, LCD_W, MENU_HEADER_HEIGHT}, &g_model.topbarData) +TopBar::TopBar(Window * parent) : + TopBarBase(parent, {0, 0, LCD_W, MENU_HEADER_HEIGHT}, &g_model.topbarData) { } -unsigned int TopbarImpl::getZonesCount() const +unsigned int TopBar::getZonesCount() const { return MAX_TOPBAR_ZONES; } -rect_t TopbarImpl::getZone(unsigned int index) const +rect_t TopBar::getZone(unsigned int index) const { if (index == MAX_TOPBAR_ZONES - 1) { coord_t size = LCD_W - 48 - (MAX_TOPBAR_ZONES - 1) * (TOPBAR_ZONE_WIDTH + TOPBAR_ZONE_HMARGIN); @@ -49,7 +49,7 @@ rect_t TopbarImpl::getZone(unsigned int index) const }; } -void TopbarImpl::setVisible(float visible) // 0.0 -> 1.0 +void TopBar::setVisible(float visible) // 0.0 -> 1.0 { if (visible == 0.0) { setTop(-(int)MENU_HEADER_HEIGHT); @@ -63,7 +63,7 @@ void TopbarImpl::setVisible(float visible) // 0.0 -> 1.0 } } -coord_t TopbarImpl::getVisibleHeight(float visible) const // 0.0 -> 1.0 +coord_t TopBar::getVisibleHeight(float visible) const // 0.0 -> 1.0 { if (visible == 0.0) { return 0; @@ -76,13 +76,13 @@ coord_t TopbarImpl::getVisibleHeight(float visible) const // 0.0 -> 1.0 return (coord_t)h; } -void TopbarImpl::paint(BitmapBuffer * dc) +void TopBar::paint(BitmapBuffer * dc) { dc->drawSolidFilledRect(0, 0, width(), height(), COLOR_THEME_SECONDARY1); EdgeTxTheme::instance()->drawHeaderIcon(dc, ICON_EDGETX); } -void TopbarImpl::checkEvents() +void TopBar::checkEvents() { uint32_t now = RTOS_GET_MS(); if (now - lastRefresh >= TOPBAR_REFRESH) { @@ -91,7 +91,7 @@ void TopbarImpl::checkEvents() } } -void TopbarImpl::removeWidget(unsigned int index) +void TopBar::removeWidget(unsigned int index) { bool mark = false; diff --git a/radio/src/gui/colorlcd/layouts/topbar_impl.h b/radio/src/gui/colorlcd/layouts/topbar_impl.h index 385fbdbae..94e1753b2 100644 --- a/radio/src/gui/colorlcd/layouts/topbar_impl.h +++ b/radio/src/gui/colorlcd/layouts/topbar_impl.h @@ -24,14 +24,12 @@ #include "topbar.h" #include "layouts/layout_factory_impl.h" -typedef WidgetsContainerImpl TopbarImplBase; +typedef WidgetsContainerImpl TopBarBase; -class TopbarImpl: - public TopbarImplBase, - public Topbar +class TopBar: public TopBarBase { public: - explicit TopbarImpl(Window * parent); + explicit TopBar(Window * parent); #if defined(DEBUG_WINDOWS) std::string getName() const override @@ -42,7 +40,7 @@ class TopbarImpl: void load() override { - TopbarImplBase::load(); + TopBarBase::load(); } unsigned int getZonesCount() const override; @@ -56,6 +54,8 @@ class TopbarImpl: void checkEvents() override; + bool isTopBar() override { return true; } + void removeWidget(unsigned int index) override; protected: diff --git a/radio/src/gui/colorlcd/screen_setup.cpp b/radio/src/gui/colorlcd/screen_setup.cpp index 0f312314e..161e556cc 100644 --- a/radio/src/gui/colorlcd/screen_setup.cpp +++ b/radio/src/gui/colorlcd/screen_setup.cpp @@ -238,9 +238,9 @@ void ScreenSetupPage::build(FormWindow * window) auto idx = customScreenIndex; LayoutChoice::LayoutFactoryGetter getFactory = [idx] () -> const LayoutFactory * { - auto layout = dynamic_cast(customScreens[idx]); - if (!layout) return nullptr; - return layout->getFactory(); + auto layout = customScreens[idx]; + if (!layout->isLayout()) return nullptr; + return ((Layout*)layout)->getFactory(); }; LayoutChoice::LayoutFactorySetter setLayout = @@ -298,10 +298,10 @@ void ScreenSetupPage::buildLayoutOptions() layoutOptions->setFlexLayout(); // Layout options... - auto layout = dynamic_cast(customScreens[customScreenIndex]); - if (!layout) return; + auto layout = customScreens[customScreenIndex]; + if (!layout->isLayout()) return; - auto factory = layout->getFactory(); + auto factory = ((Layout*)layout)->getFactory(); if (!factory) return; int index = 0; diff --git a/radio/src/gui/colorlcd/topbar.cpp b/radio/src/gui/colorlcd/topbar.cpp index 6578b8f75..1f1cd83b1 100644 --- a/radio/src/gui/colorlcd/topbar.cpp +++ b/radio/src/gui/colorlcd/topbar.cpp @@ -29,9 +29,9 @@ #include "widgets_setup.h" -Topbar * TopbarFactory::create(Window * parent) +TopBar * TopbarFactory::create(Window * parent) { - return new TopbarImpl(parent); + return new TopBar(parent); } SetupTopBarWidgetsPage::SetupTopBarWidgetsPage(): @@ -48,7 +48,7 @@ SetupTopBarWidgetsPage::SetupTopBarWidgetsPage(): // adopt the dimensions of the main view setRect(viewMain->getRect()); - auto topbar = dynamic_cast(viewMain->getTopbar()); + auto topbar = viewMain->getTopbar(); for (unsigned i = 0; i < topbar->getZonesCount(); i++) { auto rect = topbar->getZone(i); new SetupWidgetsPageSlot(this, rect, topbar, i); diff --git a/radio/src/gui/colorlcd/topbar.h b/radio/src/gui/colorlcd/topbar.h index 53e50b446..7deee38e1 100644 --- a/radio/src/gui/colorlcd/topbar.h +++ b/radio/src/gui/colorlcd/topbar.h @@ -29,18 +29,12 @@ constexpr coord_t TOPBAR_ZONE_HMARGIN = 3; constexpr coord_t TOPBAR_ZONE_HEIGHT = MENU_HEADER_HEIGHT - 2 * TOPBAR_ZONE_VMARGIN; class ScreenMenu; -class TopbarImpl; - -class Topbar -{ - public: - virtual void load() = 0; -}; +class TopBar; class TopbarFactory { public: - static Topbar* create(Window* parent); + static TopBar* create(Window* parent); }; class SetupTopBarWidgetsPage : public FormWindow diff --git a/radio/src/gui/colorlcd/view_main.cpp b/radio/src/gui/colorlcd/view_main.cpp index aeca7c41d..9012faa7a 100644 --- a/radio/src/gui/colorlcd/view_main.cpp +++ b/radio/src/gui/colorlcd/view_main.cpp @@ -84,7 +84,7 @@ ViewMain::ViewMain(): lv_obj_add_event_cb(lvobj, ViewMain::long_pressed, LV_EVENT_LONG_PRESSED, nullptr); // create last to be on top - topbar = dynamic_cast(TopbarFactory::create(this)); + topbar = TopbarFactory::create(this); } ViewMain::~ViewMain() @@ -167,7 +167,7 @@ void ViewMain::previousMainView() saveViewId(view); } -Topbar* ViewMain::getTopbar() +TopBar* ViewMain::getTopbar() { return topbar; } diff --git a/radio/src/gui/colorlcd/view_main.h b/radio/src/gui/colorlcd/view_main.h index 2125190df..279546de3 100644 --- a/radio/src/gui/colorlcd/view_main.h +++ b/radio/src/gui/colorlcd/view_main.h @@ -77,8 +77,8 @@ class ViewMain: public Window void nextMainView(); void previousMainView(); - Topbar* getTopbar(); - + TopBar* getTopbar(); + void onEvent(event_t event) override; void onClicked() override; void onCancel() override; @@ -87,7 +87,7 @@ class ViewMain: public Window static ViewMain * _instance; lv_obj_t* tile_view = nullptr; - TopbarImpl* topbar = nullptr; + TopBar* topbar = nullptr; bool widget_select = false; lv_timer_t* widget_select_timer = nullptr; ViewMainMenu* viewMainMenu = nullptr; diff --git a/radio/src/gui/colorlcd/widget.cpp b/radio/src/gui/colorlcd/widget.cpp index 87adb93ec..69f2e7b20 100644 --- a/radio/src/gui/colorlcd/widget.cpp +++ b/radio/src/gui/colorlcd/widget.cpp @@ -39,7 +39,7 @@ Widget::Widget(const WidgetFactory* factory, Window* parent, lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_SCROLLABLE); lv_obj_clear_flag(lvobj, LV_OBJ_FLAG_CLICK_FOCUSABLE); - if (dynamic_cast(parent)) + if (parent->isTopBar()) fsAllowed = false; setPressHandler([&]() -> uint8_t { @@ -112,9 +112,8 @@ void Widget::setFullscreen(bool enable) if (!enable) { // Reset all zones in container - auto container = dynamic_cast(parent); - if (container) - container->updateZones(); + if (parent->isWidgetsContainer()) + ((WidgetsContainer*)parent)->updateZones(); setWindowFlags(getWindowFlags() & ~OPAQUE); lv_obj_set_style_bg_opa(lvobj, LV_OPA_0, LV_PART_MAIN); diff --git a/radio/src/gui/colorlcd/widget.h b/radio/src/gui/colorlcd/widget.h index c31f63b19..683996a7b 100644 --- a/radio/src/gui/colorlcd/widget.h +++ b/radio/src/gui/colorlcd/widget.h @@ -180,6 +180,8 @@ class WidgetFactory virtual Widget * create(Window* parent, const rect_t & rect, Widget::PersistentData * persistentData, bool init = true) const = 0; + virtual bool isLuaWidgetFactory() const { return false; } + protected: const char * name; const char * displayName; diff --git a/radio/src/gui/colorlcd/widgets_container.h b/radio/src/gui/colorlcd/widgets_container.h index b6c2fd5c0..d9d7a0277 100644 --- a/radio/src/gui/colorlcd/widgets_container.h +++ b/radio/src/gui/colorlcd/widgets_container.h @@ -89,6 +89,9 @@ class WidgetsContainer: public Window virtual void adjustLayout() = 0; virtual void updateZones() = 0; virtual void updateFromTheme() = 0; + + virtual bool isLayout() { return false; } + bool isWidgetsContainer() override { return true; } }; diff --git a/radio/src/lua/lua_widget_factory.h b/radio/src/lua/lua_widget_factory.h index b8d97f832..6ea269da0 100644 --- a/radio/src/lua/lua_widget_factory.h +++ b/radio/src/lua/lua_widget_factory.h @@ -37,6 +37,8 @@ class LuaWidgetFactory : public WidgetFactory Widget::PersistentData* persistentData, bool init = true) const override; + bool isLuaWidgetFactory() const override { return true; } + protected: void translateOptions(ZoneOption * options); diff --git a/radio/src/lua/widgets.cpp b/radio/src/lua/widgets.cpp index db1f864d0..0a773a570 100644 --- a/radio/src/lua/widgets.cpp +++ b/radio/src/lua/widgets.cpp @@ -376,7 +376,7 @@ void luaUnregisterWidgets() { std::list regWidgets(getRegisteredWidgets()); for (auto w : regWidgets) { - if (dynamic_cast(w)) { + if (w->isLuaWidgetFactory()) { delete w; } } diff --git a/radio/src/thirdparty/libopenui/src/window.h b/radio/src/thirdparty/libopenui/src/window.h index e259c5d4a..0eb72d082 100644 --- a/radio/src/thirdparty/libopenui/src/window.h +++ b/radio/src/thirdparty/libopenui/src/window.h @@ -201,6 +201,9 @@ class Window inline lv_obj_t *getLvObj() { return lvobj; } + virtual bool isTopBar() { return false; } + virtual bool isWidgetsContainer() { return false; } + protected: static std::list trash;