Throttle flex layout calculation calls to improve performance (#268)

* Throttling multiple calls to setGeometry

* Lint
This commit is contained in:
Atul R 2019-12-15 23:36:04 +05:30 committed by GitHub
parent 6c92f02edd
commit a593c53116
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 32 additions and 3 deletions

View File

@ -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"

View File

@ -5,7 +5,7 @@
#include <QPointer>
#include <QVariant>
#include "core/FlexLayout/flexlayout.h"
#include "core/FlexLayout/flexlayout.hpp"
#include "core/FlexLayout/flexutils.h"
namespace extrautils {

View File

@ -1,6 +1,7 @@
#pragma once
#include <QLayout>
#include <QTimer>
#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

View File

@ -6,7 +6,7 @@
#include <QPointer>
#include "QtWidgets/QLayout/qlayout_macro.h"
#include "flexlayout.h"
#include "flexlayout.hpp"
class FlexLayoutWrap : public Napi::ObjectWrap<FlexLayoutWrap> {
private:

View File

@ -1,8 +1,9 @@
#include "core/FlexLayout/flexlayout.h"
#include "core/FlexLayout/flexlayout.hpp"
#include <QDebug>
#include <QWidget>
#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);