Skip to content

Instantly share code, notes, and snippets.

@eeiaao
Last active July 20, 2019 06:11
Show Gist options
  • Save eeiaao/7204df5692fe3ecd0b6b2ebcc8044532 to your computer and use it in GitHub Desktop.
Save eeiaao/7204df5692fe3ecd0b6b2ebcc8044532 to your computer and use it in GitHub Desktop.
#ifndef PROMISE_FACTORY_H
#define PROMISE_FACTORY_H
#include <QQmlComponent>
#include <QQmlEngine>
#include <QJSValue>
// ### TODO: gs
static QHash<QObject *, QQmlEngine *> hash;
static void resolveArgumentsCountAndCall(QJSValue &callable, const QJSValue &instance,
const QVariantList &args)
{
Q_ASSERT(callable.isCallable());
Q_ASSERT(instance.isObject());
auto engine = hash.take(instance.toQObject());
Q_ASSERT(engine);
QJSValueList arguments;
if (args.size() > 1) {
QJSValue argsArray = engine->newArray(uint(args.size()));
for (int i = 0; i < args.size(); ++i)
argsArray.setProperty(quint32(i), engine->toScriptValue(args.at(i)));
arguments << argsArray;
} else if (args.size() == 1) {
arguments << engine->toScriptValue(args.at(0));
}
callable.callWithInstance(instance, arguments);
}
class PromiseFactory
{
public:
static QJSValue create(QQmlEngine *engine)
{
const char *promise_qml {
"import QtQuick 2.12\n"
"QtObject {\n"
" function create() {\n"
" class Deferred {\n"
" constructor() {\n"
" this.promise = new Promise((resolve, reject) => {\n"
" this.resolve_ = resolve;\n"
" this.reject_ = reject;\n"
" });\n"
" }\n"
" then(func) {\n"
" this.promise.then(func);\n"
" return this;\n"
" }\n"
" catch(func) {\n"
" this.promise.catch(func)\n"
" return this;\n"
" }\n"
" resolve(v) {\n"
" this.resolve_(v);\n"
" }\n"
" reject(v) {\n"
" this.reject_(v);\n"
" }\n"
" }\n"
" let deferred = new Deferred();\n"
" return deferred;\n"
" }\n"
"}\n"
};
QQmlComponent promiseComponent(engine);
promiseComponent.setData(promise_qml, QUrl());
auto container = promiseComponent.create();
QJSValue promise = engine->newQObject(container).property("create").call();
hash.insert(promise.toQObject(), engine);
return promise;
}
static void resolve(const QJSValue &promise, const QVariantList &args = {})
{
auto resolve = promise.property("resolve");
resolveArgumentsCountAndCall(resolve, promise, args);
}
static void reject(const QJSValue &promise, const QVariantList &args = {})
{
auto reject = promise.property("reject");
resolveArgumentsCountAndCall(reject, promise, args);
}
};
#endif // PROMISE_FACTORY_H
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment