From a593c531164f4971bd8394c9dd252dcc0a6061f2 Mon Sep 17 00:00:00 2001 From: Atul R Date: Sun, 15 Dec 2019 23:36:04 +0530 Subject: [PATCH] Throttle flex layout calculation calls to improve performance (#268) * Throttling multiple calls to setGeometry * Lint --- CMakeLists.txt | 1 + src/cpp/include/nodegui/Extras/Utils/nutils.h | 2 +- .../{flexlayout.h => flexlayout.hpp} | 11 +++++++++++ .../nodegui/core/FlexLayout/flexlayout_wrap.h | 2 +- src/cpp/lib/core/FlexLayout/flexlayout.cpp | 19 ++++++++++++++++++- 5 files changed, 32 insertions(+), 3 deletions(-) rename src/cpp/include/nodegui/core/FlexLayout/{flexlayout.h => flexlayout.hpp} (89%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 836b2a2a6..ad414f486 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,6 +83,7 @@ add_library(${CORE_WIDGETS_ADDON} SHARED "${PROJECT_SOURCE_DIR}/src/cpp/lib/core/FlexLayout/flexlayout_wrap.cpp" # Custom widgets (include them for automoc since they contain Q_OBJECT) "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtCore/QObject/nobject.hpp" + "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/core/FlexLayout/flexlayout.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtGui/QMovie/nmovie.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QWidget/nwidget.hpp" "${PROJECT_SOURCE_DIR}/src/cpp/include/nodegui/QtWidgets/QLabel/nlabel.hpp" diff --git a/src/cpp/include/nodegui/Extras/Utils/nutils.h b/src/cpp/include/nodegui/Extras/Utils/nutils.h index f646993b6..d57737b2f 100644 --- a/src/cpp/include/nodegui/Extras/Utils/nutils.h +++ b/src/cpp/include/nodegui/Extras/Utils/nutils.h @@ -5,7 +5,7 @@ #include #include -#include "core/FlexLayout/flexlayout.h" +#include "core/FlexLayout/flexlayout.hpp" #include "core/FlexLayout/flexutils.h" namespace extrautils { diff --git a/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h b/src/cpp/include/nodegui/core/FlexLayout/flexlayout.hpp similarity index 89% rename from src/cpp/include/nodegui/core/FlexLayout/flexlayout.h rename to src/cpp/include/nodegui/core/FlexLayout/flexlayout.hpp index 96c0f889a..fe5e3b46c 100644 --- a/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h +++ b/src/cpp/include/nodegui/core/FlexLayout/flexlayout.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include "core/Events/eventwidget_macro.h" #include "deps/yoga/YGNode.h" @@ -19,6 +20,7 @@ YGNodeNew(); FlexLayout * flayout = new FlexLayout(container,root); */ class FlexLayout : public QLayout, public EventWidget { + Q_OBJECT private: YGNodeRef node; YGNodeRef getRootNode(YGNodeRef node) const; @@ -26,6 +28,13 @@ class FlexLayout : public QLayout, public EventWidget { void restoreNodeMinStyle(YGValue &previousMinWidth, YGValue &previousMinHeight); + // performance memebers + QTimer throttleTimer; + QRect cachedRect; + // end of performance memeber + private slots: + void performLayout(); + public: FlexLayout(QWidget *parentWidget = nullptr, YGNodeRef parentNode = nullptr); ~FlexLayout() override; @@ -45,3 +54,5 @@ class FlexLayout : public QLayout, public EventWidget { EVENTWIDGET_IMPLEMENTATIONS(QLayout) }; + +// class FlexLayoutWorker: public Q \ No newline at end of file diff --git a/src/cpp/include/nodegui/core/FlexLayout/flexlayout_wrap.h b/src/cpp/include/nodegui/core/FlexLayout/flexlayout_wrap.h index 9b313ff3f..630799cc5 100644 --- a/src/cpp/include/nodegui/core/FlexLayout/flexlayout_wrap.h +++ b/src/cpp/include/nodegui/core/FlexLayout/flexlayout_wrap.h @@ -6,7 +6,7 @@ #include #include "QtWidgets/QLayout/qlayout_macro.h" -#include "flexlayout.h" +#include "flexlayout.hpp" class FlexLayoutWrap : public Napi::ObjectWrap { private: diff --git a/src/cpp/lib/core/FlexLayout/flexlayout.cpp b/src/cpp/lib/core/FlexLayout/flexlayout.cpp index 49156d4e9..1287093aa 100644 --- a/src/cpp/lib/core/FlexLayout/flexlayout.cpp +++ b/src/cpp/lib/core/FlexLayout/flexlayout.cpp @@ -1,8 +1,9 @@ -#include "core/FlexLayout/flexlayout.h" +#include "core/FlexLayout/flexlayout.hpp" #include #include +#include "Extras/Utils/nutils.h" #include "core/FlexLayout/flexitem.h" #include "core/FlexLayout/flexutils.h" #include "core/YogaWidget/yogawidget.h" @@ -10,6 +11,12 @@ FlexLayout::FlexLayout(QWidget* parentWidget, YGNodeRef parentNode) : QLayout(parentWidget) { this->node = parentNode; + // Throttle the setGeometry calls that may happen when dealing with huge + // lists. + this->throttleTimer.setTimerType(Qt::PreciseTimer); + this->throttleTimer.setSingleShot(true); + QObject::connect(&this->throttleTimer, &QTimer::timeout, this, + &FlexLayout::performLayout); } FlexLayout::~FlexLayout() { @@ -147,9 +154,19 @@ QSize FlexLayout::minimumSize() const { } void FlexLayout::setGeometry(const QRect& rect) { + this->cachedRect = rect; + if (this->throttleTimer.isActive()) { + return; + } + this->throttleTimer.start(10); + // This will call performLayout and throttle requests between 10ms. +} + +void FlexLayout::performLayout() { if (!this->node) { return; } + QRect rect = this->cachedRect; if (!rect.isValid() || rect != geometry()) { bool isSizeControlled = flexutils::isFlexNodeSizeControlled(this->node); YGValue prevStyleMinWidth = YGNodeStyleGetMinWidth(this->node);