mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 16:47:26 +00:00
Document RefreshDeferrer
This commit is contained in:
parent
9ef971263f
commit
bbd5ad6b38
@ -18,7 +18,9 @@ bool RefreshDeferrer::attemptRefresh(RefreshDeferrerParams params)
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
dirty = true;
|
dirty = true;
|
||||||
acc->accumulate(params);
|
if (acc) {
|
||||||
|
acc->accumulate(params);
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,8 +30,10 @@ void RefreshDeferrer::registerFor(CutterDockWidget *dockWidget)
|
|||||||
this->dockWidget = dockWidget;
|
this->dockWidget = dockWidget;
|
||||||
connect(dockWidget, &CutterDockWidget::becameVisibleToUser, this, [this]() {
|
connect(dockWidget, &CutterDockWidget::becameVisibleToUser, this, [this]() {
|
||||||
if(dirty) {
|
if(dirty) {
|
||||||
emit refreshNow(acc->result());
|
emit refreshNow(acc ? acc->result() : nullptr);
|
||||||
acc->clear();
|
if (acc) {
|
||||||
|
acc->clear();
|
||||||
|
}
|
||||||
dirty = false;
|
dirty = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,9 @@ class RefreshDeferrer;
|
|||||||
using RefreshDeferrerParams = void *;
|
using RefreshDeferrerParams = void *;
|
||||||
using RefreshDeferrerParamsResult = void *;
|
using RefreshDeferrerParamsResult = void *;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Abstract class for accumulating params in RefreshDeferrer
|
||||||
|
*/
|
||||||
class RefreshDeferrerAccumulator
|
class RefreshDeferrerAccumulator
|
||||||
{
|
{
|
||||||
friend class RefreshDeferrer;
|
friend class RefreshDeferrer;
|
||||||
@ -18,12 +21,34 @@ public:
|
|||||||
virtual ~RefreshDeferrerAccumulator() = default;
|
virtual ~RefreshDeferrerAccumulator() = default;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/*!
|
||||||
|
* \brief Add a new param to the accumulator
|
||||||
|
*/
|
||||||
virtual void accumulate(RefreshDeferrerParams params) =0;
|
virtual void accumulate(RefreshDeferrerParams params) =0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Ignore the incoming params. Useful for freeing if necessary.
|
||||||
|
*/
|
||||||
virtual void ignoreParams(RefreshDeferrerParams params) =0;
|
virtual void ignoreParams(RefreshDeferrerParams params) =0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Clear the current accumulator
|
||||||
|
*/
|
||||||
virtual void clear() =0;
|
virtual void clear() =0;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Return the final result of the accumulation
|
||||||
|
*/
|
||||||
virtual RefreshDeferrerParamsResult result() =0;
|
virtual RefreshDeferrerParamsResult result() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Accumulator which simply replaces the current value by an incoming new one
|
||||||
|
* \tparam T The type of the param to store
|
||||||
|
*
|
||||||
|
* This accumulator takes the ownership of all params passed to it and deletes them automatically if not needed anymore!
|
||||||
|
*/
|
||||||
template<class T>
|
template<class T>
|
||||||
class ReplacingRefreshDeferrerAccumulator: public RefreshDeferrerAccumulator
|
class ReplacingRefreshDeferrerAccumulator: public RefreshDeferrerAccumulator
|
||||||
{
|
{
|
||||||
@ -32,6 +57,9 @@ private:
|
|||||||
bool replaceIfNull;
|
bool replaceIfNull;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/*!
|
||||||
|
* \param Determines whether, if nullptr is passed, the current value should be replaced or kept.
|
||||||
|
*/
|
||||||
explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true)
|
explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true)
|
||||||
: replaceIfNull(replaceIfNull) {}
|
: replaceIfNull(replaceIfNull) {}
|
||||||
|
|
||||||
@ -67,6 +95,39 @@ protected:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Helper class for deferred refreshing in Widgets
|
||||||
|
*
|
||||||
|
* This class can handle the logic necessary to defer the refreshing of widgets when they are not visible.
|
||||||
|
* It contains an optional RefreshDeferrerAccumulator, which can be used to accumulate incoming events while
|
||||||
|
* refreshing is deferred.
|
||||||
|
*
|
||||||
|
* Example (don't write it like this in practice, use the convenience methods in CutterDockWidget):
|
||||||
|
* ```
|
||||||
|
* // in the constructor of a widget
|
||||||
|
* this->refreshDeferrer = new RefreshDeferrer(new ReplacingRefreshDeferrerAccumulator(false), this);
|
||||||
|
* this->refreshDeferrer->registerFor(this);
|
||||||
|
* connect(this->refreshDeferrer, &RefreshDeferrer::refreshNow, this, [this](MyParam *param) {
|
||||||
|
* // We attempted a refresh some time before, but it got deferred.
|
||||||
|
* // Now the RefreshDeferrer tells us to do the refresh and gives us the accumulated param.
|
||||||
|
* this->doRefresh(*param);
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* // ...
|
||||||
|
*
|
||||||
|
* void MyWidget::doRefresh(MyParam param)
|
||||||
|
* {
|
||||||
|
* if (!this->refreshDeferrer->attemptRefresh(new MyParam(param))) {
|
||||||
|
* // We shouldn't refresh right now.
|
||||||
|
* // The RefreshDeferrer takes over the param we passed it in attemptRefresh()
|
||||||
|
* // and gives it to the ReplacingRefreshDeferrerAccumulator.
|
||||||
|
* return;
|
||||||
|
* }
|
||||||
|
* // do the actual refresh depending on param
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
*/
|
||||||
class RefreshDeferrer : public QObject
|
class RefreshDeferrer : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -77,8 +138,11 @@ private:
|
|||||||
bool dirty = false;
|
bool dirty = false;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent = nullptr);
|
/*!
|
||||||
virtual ~RefreshDeferrer();
|
* \param acc The accumulator (can be nullptr). The RefreshDeferrer takes the ownership!
|
||||||
|
*/
|
||||||
|
explicit RefreshDeferrer(RefreshDeferrerAccumulator *acc, QObject *parent = nullptr);
|
||||||
|
~RefreshDeferrer() override;
|
||||||
|
|
||||||
bool attemptRefresh(RefreshDeferrerParams params);
|
bool attemptRefresh(RefreshDeferrerParams params);
|
||||||
void registerFor(CutterDockWidget *dockWidget);
|
void registerFor(CutterDockWidget *dockWidget);
|
||||||
|
@ -32,6 +32,26 @@ private:
|
|||||||
protected:
|
protected:
|
||||||
void closeEvent(QCloseEvent *event) override;
|
void closeEvent(QCloseEvent *event) override;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Convenience method for creating and registering a RefreshDeferrer without any parameters
|
||||||
|
* \param refreshNowFunc lambda taking no parameters, called when a refresh should occur
|
||||||
|
*/
|
||||||
|
template<typename Func>
|
||||||
|
RefreshDeferrer *createRefreshDeferrer(Func refreshNowFunc)
|
||||||
|
{
|
||||||
|
auto *deferrer = new RefreshDeferrer(nullptr, this);
|
||||||
|
deferrer->registerFor(this);
|
||||||
|
connect(deferrer, &RefreshDeferrer::refreshNow, this, [refreshNowFunc](const RefreshDeferrerParamsResult) {
|
||||||
|
refreshNowFunc();
|
||||||
|
});
|
||||||
|
return deferrer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Convenience method for creating and registering a RefreshDeferrer with a replacing Accumulator
|
||||||
|
* \param replaceIfNull passed to the ReplacingRefreshDeferrerAccumulator
|
||||||
|
* \param refreshNowFunc lambda taking a single parameter of type ParamResult, called when a refresh should occur
|
||||||
|
*/
|
||||||
template<class ParamResult, typename Func>
|
template<class ParamResult, typename Func>
|
||||||
RefreshDeferrer *createReplacingRefreshDeferrer(bool replaceIfNull, Func refreshNowFunc)
|
RefreshDeferrer *createReplacingRefreshDeferrer(bool replaceIfNull, Func refreshNowFunc)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user