mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-19 10:58:51 +00:00
Add RefreshDeferrer
This commit is contained in:
parent
3728f977a2
commit
b8c92a460d
@ -219,7 +219,8 @@ SOURCES += \
|
|||||||
widgets/ComboQuickFilterView.cpp \
|
widgets/ComboQuickFilterView.cpp \
|
||||||
dialogs/HexdumpRangeDialog.cpp \
|
dialogs/HexdumpRangeDialog.cpp \
|
||||||
common/QtResImporter.cpp \
|
common/QtResImporter.cpp \
|
||||||
widgets/CutterSeekable.cpp
|
widgets/CutterSeekable.cpp \
|
||||||
|
common/RefreshDeferrer.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
Cutter.h \
|
Cutter.h \
|
||||||
@ -322,7 +323,8 @@ HEADERS += \
|
|||||||
widgets/ComboQuickFilterView.h \
|
widgets/ComboQuickFilterView.h \
|
||||||
dialogs/HexdumpRangeDialog.h \
|
dialogs/HexdumpRangeDialog.h \
|
||||||
common/QtResImporter.h \
|
common/QtResImporter.h \
|
||||||
widgets/CutterSeekable.h
|
widgets/CutterSeekable.h \
|
||||||
|
common/RefreshDeferrer.h
|
||||||
|
|
||||||
FORMS += \
|
FORMS += \
|
||||||
dialogs/AboutDialog.ui \
|
dialogs/AboutDialog.ui \
|
||||||
|
37
src/common/RefreshDeferrer.cpp
Normal file
37
src/common/RefreshDeferrer.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
#include "RefreshDeferrer.h"
|
||||||
|
#include "widgets/CutterDockWidget.h"
|
||||||
|
|
||||||
|
RefreshDeferrer::RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent) : QObject(parent),
|
||||||
|
acc(acc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshDeferrer::~RefreshDeferrer()
|
||||||
|
{
|
||||||
|
delete acc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RefreshDeferrer::attemptRefresh(RefreshDeferrerParams params)
|
||||||
|
{
|
||||||
|
if (dockWidget->isVisibleToUser()) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
dirty = true;
|
||||||
|
acc->accumulate(params);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RefreshDeferrer::registerFor(CutterDockWidget *dockWidget)
|
||||||
|
{
|
||||||
|
this->dockWidget = dockWidget;
|
||||||
|
connect(dockWidget, &CutterDockWidget::becameVisibleToUser, this, [this]() {
|
||||||
|
if(dirty) {
|
||||||
|
emit refreshNow(acc->result());
|
||||||
|
acc->clear();
|
||||||
|
dirty = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
83
src/common/RefreshDeferrer.h
Normal file
83
src/common/RefreshDeferrer.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
|
||||||
|
#ifndef REFRESHDEFERRER_H
|
||||||
|
#define REFRESHDEFERRER_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
class CutterDockWidget;
|
||||||
|
class RefreshDeferrer;
|
||||||
|
|
||||||
|
using RefreshDeferrerParams = void *;
|
||||||
|
using RefreshDeferrerParamsResult = void *;
|
||||||
|
|
||||||
|
class RefreshDeferrerAccumulator
|
||||||
|
{
|
||||||
|
friend class RefreshDeferrer;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~RefreshDeferrerAccumulator() = default;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void accumulate(RefreshDeferrerParams params) =0;
|
||||||
|
virtual void ignoreParams(RefreshDeferrerParams params) =0;
|
||||||
|
virtual void clear() =0;
|
||||||
|
virtual RefreshDeferrerParamsResult result() =0;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
class ReplacingRefreshDeferrerAccumulator: public RefreshDeferrerAccumulator
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T *value = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
~ReplacingRefreshDeferrerAccumulator() override
|
||||||
|
{
|
||||||
|
delete value;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void accumulate(RefreshDeferrerParams params) override
|
||||||
|
{
|
||||||
|
delete value;
|
||||||
|
value = static_cast<T *>(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ignoreParams(RefreshDeferrerParams params) override
|
||||||
|
{
|
||||||
|
delete static_cast<T *>(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear() override
|
||||||
|
{
|
||||||
|
delete value;
|
||||||
|
value = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual RefreshDeferrerParamsResult result() override
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class RefreshDeferrer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
private:
|
||||||
|
CutterDockWidget *dockWidget = nullptr;
|
||||||
|
RefreshDeferrerAccumulator *acc;
|
||||||
|
bool dirty = false;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent = nullptr);
|
||||||
|
virtual ~RefreshDeferrer();
|
||||||
|
|
||||||
|
bool attemptRefresh(RefreshDeferrerParams params);
|
||||||
|
void registerFor(CutterDockWidget *dockWidget);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void refreshNow(RefreshDeferrerParamsResult paramsResult);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //REFRESHDEFERRER_H
|
@ -12,10 +12,9 @@ CutterDockWidget::CutterDockWidget(MainWindow *main, QAction *action) :
|
|||||||
connect(action, &QAction::triggered, this, &CutterDockWidget::toggleDockWidget);
|
connect(action, &QAction::triggered, this, &CutterDockWidget::toggleDockWidget);
|
||||||
}
|
}
|
||||||
|
|
||||||
isVisibleToUserCurrent = false;
|
|
||||||
|
|
||||||
// Install event filter to catch redraw widgets when needed
|
// Install event filter to catch redraw widgets when needed
|
||||||
installEventFilter(this);
|
installEventFilter(this);
|
||||||
|
updateIsVisibleToUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
CutterDockWidget::~CutterDockWidget() {}
|
CutterDockWidget::~CutterDockWidget() {}
|
||||||
|
@ -13,6 +13,7 @@ public:
|
|||||||
explicit CutterDockWidget(MainWindow *main, QAction *action = nullptr);
|
explicit CutterDockWidget(MainWindow *main, QAction *action = nullptr);
|
||||||
~CutterDockWidget() override;
|
~CutterDockWidget() override;
|
||||||
bool eventFilter(QObject *object, QEvent *event) override;
|
bool eventFilter(QObject *object, QEvent *event) override;
|
||||||
|
bool isVisibleToUser() { return isVisibleToUserCurrent; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void toggleDockWidget(bool show);
|
void toggleDockWidget(bool show);
|
||||||
@ -28,7 +29,6 @@ private:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
bool isVisibleToUser() { return isVisibleToUserCurrent; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CUTTERWIDGET_H
|
#endif // CUTTERWIDGET_H
|
||||||
|
@ -42,6 +42,7 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
|||||||
, mDisasScrollArea(new DisassemblyScrollArea(this))
|
, mDisasScrollArea(new DisassemblyScrollArea(this))
|
||||||
, mDisasTextEdit(new DisassemblyTextEdit(this))
|
, mDisasTextEdit(new DisassemblyTextEdit(this))
|
||||||
, seekable(new CutterSeekable(this))
|
, seekable(new CutterSeekable(this))
|
||||||
|
, disasmRefresh(new ReplacingRefreshDeferrerAccumulator<RVA>)
|
||||||
{
|
{
|
||||||
topOffset = bottomOffset = RVA_INVALID;
|
topOffset = bottomOffset = RVA_INVALID;
|
||||||
cursorLineOffset = 0;
|
cursorLineOffset = 0;
|
||||||
@ -63,6 +64,13 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
|||||||
setupFonts();
|
setupFonts();
|
||||||
setupColors();
|
setupColors();
|
||||||
|
|
||||||
|
disasmRefresh.registerFor(this);
|
||||||
|
connect(&disasmRefresh, &RefreshDeferrer::refreshNow, this, [this](RefreshDeferrerParamsResult paramsResult) {
|
||||||
|
printf("got refresh now!\n");
|
||||||
|
RVA *offset = static_cast<RVA *>(paramsResult);
|
||||||
|
refreshDisasm(*offset);
|
||||||
|
});
|
||||||
|
|
||||||
maxLines = 0;
|
maxLines = 0;
|
||||||
updateMaxLines();
|
updateMaxLines();
|
||||||
|
|
||||||
@ -175,13 +183,6 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
|||||||
ADD_SHORTCUT(QKeySequence(Qt::CTRL + Qt::Key_Plus), &DisassemblyWidget::zoomIn)
|
ADD_SHORTCUT(QKeySequence(Qt::CTRL + Qt::Key_Plus), &DisassemblyWidget::zoomIn)
|
||||||
ADD_SHORTCUT(QKeySequence(Qt::CTRL + Qt::Key_Minus), &DisassemblyWidget::zoomOut)
|
ADD_SHORTCUT(QKeySequence(Qt::CTRL + Qt::Key_Minus), &DisassemblyWidget::zoomOut)
|
||||||
#undef ADD_SHORTCUT
|
#undef ADD_SHORTCUT
|
||||||
|
|
||||||
connect(this, &CutterDockWidget::becameVisibleToUser, this, [this]() {
|
|
||||||
printf("ooh! we became visible!\n");
|
|
||||||
if (disasmDirty) {
|
|
||||||
refreshDisasm(disasmDirtyOffset);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisassemblyWidget::toggleSync()
|
void DisassemblyWidget::toggleSync()
|
||||||
@ -202,15 +203,11 @@ QWidget *DisassemblyWidget::getTextWidget()
|
|||||||
|
|
||||||
void DisassemblyWidget::refreshDisasm(RVA offset)
|
void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||||
{
|
{
|
||||||
if (!isVisibleToUser()) {
|
if(!disasmRefresh.attemptRefresh(new RVA(offset))) {
|
||||||
printf("setting dirty\n");
|
printf("we tried to refresh, but shouldn't yet.\n");
|
||||||
disasmDirty = true;
|
|
||||||
disasmDirtyOffset = offset;
|
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
printf("now refreshing\n");
|
|
||||||
disasmDirty = false;
|
|
||||||
}
|
}
|
||||||
|
printf("ok, actually refreshing now!\n");
|
||||||
|
|
||||||
if (offset != RVA_INVALID) {
|
if (offset != RVA_INVALID) {
|
||||||
topOffset = offset;
|
topOffset = offset;
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
#include "Cutter.h"
|
#include "Cutter.h"
|
||||||
#include "CutterDockWidget.h"
|
#include "CutterDockWidget.h"
|
||||||
#include "CutterSeekable.h"
|
#include "CutterSeekable.h"
|
||||||
|
#include "common/RefreshDeferrer.h"
|
||||||
|
|
||||||
#include <QTextEdit>
|
#include <QTextEdit>
|
||||||
#include <QPlainTextEdit>
|
#include <QPlainTextEdit>
|
||||||
#include <QShortcut>
|
#include <QShortcut>
|
||||||
@ -57,8 +59,7 @@ private:
|
|||||||
int cursorLineOffset;
|
int cursorLineOffset;
|
||||||
bool seekFromCursor;
|
bool seekFromCursor;
|
||||||
|
|
||||||
bool disasmDirty = false;
|
RefreshDeferrer disasmRefresh;
|
||||||
RVA disasmDirtyOffset = RVA_INVALID;
|
|
||||||
|
|
||||||
RVA readCurrentDisassemblyOffset();
|
RVA readCurrentDisassemblyOffset();
|
||||||
RVA readDisassemblyOffset(QTextCursor tc);
|
RVA readDisassemblyOffset(QTextCursor tc);
|
||||||
|
Loading…
Reference in New Issue
Block a user