Page MenuHomePhorge

matrix-promise.cpp
No OneTemporary

Size
2 KB
Referenced Files
None
Subscribers
None

matrix-promise.cpp

/*
* This file is part of kazv.
* SPDX-FileCopyrightText: 2020-2023 tusooa <tusooa@kazv.moe>
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
#include <libkazv-config.hpp>
#include <immer/config.hpp> // https://github.com/arximboldi/immer/issues/168
#include <QTimer>
#include "qt-json.hpp"
#include "matrix-promise.hpp"
using namespace Kazv;
// We cannot emit signals to MatrixPromise directly because by the time
// the Promise has resolved, the MatrixPromise might be under deletion.
// If it is deleted after we test for nullity on the QPointer but before we call
// MatrixPromise::resolved(), we will be calling a function on a zero pointer.
// Therefore we create another long-lived object called the Passer.
// It passes the signal to the MatrixPromise through a signal connection.
// The calling of the actual resolved/* functions is performed in the
// thread of the MatrixPromise (the QML thread) so it cannot be deleted halfway.
class MatrixPromisePrivPasser : public QObject
{
Q_OBJECT
public:
MatrixPromisePrivPasser(MatrixPromise *p);
Q_SIGNALS:
void resolved(bool success, const QJsonValue &data);
};
struct MatrixPromise::Private
{
using Passer = MatrixPromisePrivPasser;
std::shared_ptr<Passer> passer;
Private(MatrixPromise *q)
: passer(new Passer(q))
{
}
};
MatrixPromisePrivPasser::MatrixPromisePrivPasser(MatrixPromise *p)
: QObject(0)
{
connect(this, &MatrixPromisePrivPasser::resolved,
static_cast<QObject *>(p), [p](bool success, const QJsonValue &data) { // will only be called if p still lives
Q_EMIT p->resolved(success, data);
if (success) {
Q_EMIT p->succeeded(data);
} else {
Q_EMIT p->failed(data);
}
});
}
MatrixPromise::MatrixPromise(QObject *parent)
: QObject(parent)
, m_d()
{
}
MatrixPromise::MatrixPromise(SingleTypePromise<EffectStatus> promise, QObject *parent)
: QObject(parent)
, m_d(new Private(this))
{
promise.then([passer=m_d->passer](const auto &result) {
Q_EMIT passer->resolved(result.success(), result.data().get());
});
}
MatrixPromise::~MatrixPromise() = default;
MatrixPromise *MatrixPromise::createResolved(bool isSuccess, const QJsonValue &data, QObject *parent)
{
auto matrixPromise = new MatrixPromise(parent);
QTimer::singleShot(0, matrixPromise, [p=matrixPromise, success=isSuccess, data]() {
Q_EMIT p->resolved(success, data);
if (success) {
Q_EMIT p->succeeded(data);
} else {
Q_EMIT p->failed(data);
}
});
return matrixPromise;
}
#include "matrix-promise.moc"

File Metadata

Mime Type
text/x-c++
Expires
Sun, Dec 1, 8:46 AM (1 d, 19 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41642
Default Alt Text
matrix-promise.cpp (2 KB)

Event Timeline