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 \
|
||||
dialogs/HexdumpRangeDialog.cpp \
|
||||
common/QtResImporter.cpp \
|
||||
widgets/CutterSeekable.cpp
|
||||
widgets/CutterSeekable.cpp \
|
||||
common/RefreshDeferrer.cpp
|
||||
|
||||
HEADERS += \
|
||||
Cutter.h \
|
||||
@ -322,7 +323,8 @@ HEADERS += \
|
||||
widgets/ComboQuickFilterView.h \
|
||||
dialogs/HexdumpRangeDialog.h \
|
||||
common/QtResImporter.h \
|
||||
widgets/CutterSeekable.h
|
||||
widgets/CutterSeekable.h \
|
||||
common/RefreshDeferrer.h
|
||||
|
||||
FORMS += \
|
||||
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);
|
||||
}
|
||||
|
||||
isVisibleToUserCurrent = false;
|
||||
|
||||
// Install event filter to catch redraw widgets when needed
|
||||
installEventFilter(this);
|
||||
updateIsVisibleToUser();
|
||||
}
|
||||
|
||||
CutterDockWidget::~CutterDockWidget() {}
|
||||
|
@ -13,6 +13,7 @@ public:
|
||||
explicit CutterDockWidget(MainWindow *main, QAction *action = nullptr);
|
||||
~CutterDockWidget() override;
|
||||
bool eventFilter(QObject *object, QEvent *event) override;
|
||||
bool isVisibleToUser() { return isVisibleToUserCurrent; }
|
||||
|
||||
public slots:
|
||||
void toggleDockWidget(bool show);
|
||||
@ -28,7 +29,6 @@ private:
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
bool isVisibleToUser() { return isVisibleToUserCurrent; }
|
||||
};
|
||||
|
||||
#endif // CUTTERWIDGET_H
|
||||
|
@ -42,6 +42,7 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
, mDisasScrollArea(new DisassemblyScrollArea(this))
|
||||
, mDisasTextEdit(new DisassemblyTextEdit(this))
|
||||
, seekable(new CutterSeekable(this))
|
||||
, disasmRefresh(new ReplacingRefreshDeferrerAccumulator<RVA>)
|
||||
{
|
||||
topOffset = bottomOffset = RVA_INVALID;
|
||||
cursorLineOffset = 0;
|
||||
@ -63,6 +64,13 @@ DisassemblyWidget::DisassemblyWidget(MainWindow *main, QAction *action)
|
||||
setupFonts();
|
||||
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;
|
||||
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_Minus), &DisassemblyWidget::zoomOut)
|
||||
#undef ADD_SHORTCUT
|
||||
|
||||
connect(this, &CutterDockWidget::becameVisibleToUser, this, [this]() {
|
||||
printf("ooh! we became visible!\n");
|
||||
if (disasmDirty) {
|
||||
refreshDisasm(disasmDirtyOffset);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void DisassemblyWidget::toggleSync()
|
||||
@ -202,15 +203,11 @@ QWidget *DisassemblyWidget::getTextWidget()
|
||||
|
||||
void DisassemblyWidget::refreshDisasm(RVA offset)
|
||||
{
|
||||
if (!isVisibleToUser()) {
|
||||
printf("setting dirty\n");
|
||||
disasmDirty = true;
|
||||
disasmDirtyOffset = offset;
|
||||
if(!disasmRefresh.attemptRefresh(new RVA(offset))) {
|
||||
printf("we tried to refresh, but shouldn't yet.\n");
|
||||
return;
|
||||
} else {
|
||||
printf("now refreshing\n");
|
||||
disasmDirty = false;
|
||||
}
|
||||
printf("ok, actually refreshing now!\n");
|
||||
|
||||
if (offset != RVA_INVALID) {
|
||||
topOffset = offset;
|
||||
|
@ -4,6 +4,8 @@
|
||||
#include "Cutter.h"
|
||||
#include "CutterDockWidget.h"
|
||||
#include "CutterSeekable.h"
|
||||
#include "common/RefreshDeferrer.h"
|
||||
|
||||
#include <QTextEdit>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QShortcut>
|
||||
@ -57,8 +59,7 @@ private:
|
||||
int cursorLineOffset;
|
||||
bool seekFromCursor;
|
||||
|
||||
bool disasmDirty = false;
|
||||
RVA disasmDirtyOffset = RVA_INVALID;
|
||||
RefreshDeferrer disasmRefresh;
|
||||
|
||||
RVA readCurrentDisassemblyOffset();
|
||||
RVA readDisassemblyOffset(QTextCursor tc);
|
||||
|
Loading…
Reference in New Issue
Block a user