mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 08:37: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;
|
||||
} else {
|
||||
dirty = true;
|
||||
acc->accumulate(params);
|
||||
if (acc) {
|
||||
acc->accumulate(params);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -28,8 +30,10 @@ void RefreshDeferrer::registerFor(CutterDockWidget *dockWidget)
|
||||
this->dockWidget = dockWidget;
|
||||
connect(dockWidget, &CutterDockWidget::becameVisibleToUser, this, [this]() {
|
||||
if(dirty) {
|
||||
emit refreshNow(acc->result());
|
||||
acc->clear();
|
||||
emit refreshNow(acc ? acc->result() : nullptr);
|
||||
if (acc) {
|
||||
acc->clear();
|
||||
}
|
||||
dirty = false;
|
||||
}
|
||||
});
|
||||
|
@ -10,6 +10,9 @@ class RefreshDeferrer;
|
||||
using RefreshDeferrerParams = void *;
|
||||
using RefreshDeferrerParamsResult = void *;
|
||||
|
||||
/*!
|
||||
* \brief Abstract class for accumulating params in RefreshDeferrer
|
||||
*/
|
||||
class RefreshDeferrerAccumulator
|
||||
{
|
||||
friend class RefreshDeferrer;
|
||||
@ -18,12 +21,34 @@ public:
|
||||
virtual ~RefreshDeferrerAccumulator() = default;
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* \brief Add a new param to the accumulator
|
||||
*/
|
||||
virtual void accumulate(RefreshDeferrerParams params) =0;
|
||||
|
||||
/*!
|
||||
* \brief Ignore the incoming params. Useful for freeing if necessary.
|
||||
*/
|
||||
virtual void ignoreParams(RefreshDeferrerParams params) =0;
|
||||
|
||||
/*!
|
||||
* \brief Clear the current accumulator
|
||||
*/
|
||||
virtual void clear() =0;
|
||||
|
||||
/*!
|
||||
* \brief Return the final result of the accumulation
|
||||
*/
|
||||
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>
|
||||
class ReplacingRefreshDeferrerAccumulator: public RefreshDeferrerAccumulator
|
||||
{
|
||||
@ -32,6 +57,9 @@ private:
|
||||
bool replaceIfNull;
|
||||
|
||||
public:
|
||||
/*!
|
||||
* \param Determines whether, if nullptr is passed, the current value should be replaced or kept.
|
||||
*/
|
||||
explicit ReplacingRefreshDeferrerAccumulator(bool replaceIfNull = true)
|
||||
: 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
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -77,8 +138,11 @@ private:
|
||||
bool dirty = false;
|
||||
|
||||
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);
|
||||
void registerFor(CutterDockWidget *dockWidget);
|
||||
|
@ -32,6 +32,26 @@ private:
|
||||
protected:
|
||||
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>
|
||||
RefreshDeferrer *createReplacingRefreshDeferrer(bool replaceIfNull, Func refreshNowFunc)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user