GithubHelp home page GithubHelp logo

Expose QPromise to QML about qtpromise HOT 10 OPEN

simonbrunel avatar simonbrunel commented on May 12, 2024
Expose QPromise to QML

from qtpromise.

Comments (10)

simonbrunel avatar simonbrunel commented on May 12, 2024 1

QPromise<T> is not a Q_OBJECT (or Q_GADGET) and its methods are not compatible with JavaScript (e.g. QPromise<T>::then() doesn't work with a JS function, ie. QJSValue). Exception handling is also different between JavaScript and C++ and I really want to keep the C++ implementation not aware of QML. That's why we need a Q_GADGET wrapper (QJSPromise) around QPromise to translate from and to JavaScript values.

Then, we need to figure out how to convert from/to QJSPromise (I was thinking of adding a QPromise<T>.as<U>() method?). Once everything implemented and if that works as expected, your snippet would look like:

class CustomObjectWithPromise : public QObject
{
  Q_OBJECT

public:
  Q_INVOKABLE QtPromise::QJSPromise getIntAsync();
  {
     // readIntValueAsync returning QPromise<int>
     return readIntValueAsync().as<QJSValue>();
  }
};

Note: QPromise has been designed to avoid dealing with pointers, you shouldn't return a QPromise<T>* but instead a QPromise<T>.

from qtpromise.

pwuertz avatar pwuertz commented on May 12, 2024 1

So since creating QJSValue from C++ is a pain due to the burden of acquiring a QJSEngine, couldn't the Promise be shipped via QVariant instead? With QJSPromise being a registered type, Qt should be converting from/to QVariant transparently..

from qtpromise.

simonbrunel avatar simonbrunel commented on May 12, 2024

@Adphi Thank you :)

What do you mean exactly by "... support QPromise exposition to QML"?

I started writing a QML wrapper allowing to use the same functionalities in JavaScript:

var promise = new Promise(function(resolve) {
  //...
  resolve(42);
});

promise
  .then(function(res) { /*...*/ })
  .fail(function(err) { /*...*/ })
  .finally(function() { /*...*/ })
  // ...

Internally, it relies on a QPromise<QJSValue>. You can find that early implementation in the qtqmlpromise branch but it's definitely not ready for production, not tested and the public API may change. Also, it doesn't allow exchanging promises between both worlds (e.g. returning a QPromise<int> to QML), I still need to figure out what would be the best approach.

from qtpromise.

Adphi avatar Adphi commented on May 12, 2024

What do you mean exactly by "... support QPromise exposition to QML"?

I mean: exchanging promises between C++ and QML.
I was hopping to be able to return a Promise to QML from C++.
For example:

class CustomObjectWithPromise : public QObject
{
    Q_OBJECT
public:
    explicit CustomObjectWithPromise(QObject *parent = nullptr);
    Q_INVOKABLE QtPromise::QPromise<int>* getIntAsync();

signals:

public slots:

private:
    QNetworkAccessManager *mManager;
};

from qtpromise.

Adphi avatar Adphi commented on May 12, 2024

Thank you.
I'll keep an eye on this.

from qtpromise.

pwuertz avatar pwuertz commented on May 12, 2024

@simonbrunel What is the biggest issue to solve for getting QML Promise in a technology preview state? As in knowing full well that the API may change, but being confident that then/fail/finally do what you would expect? I've seen there are some automated tests in the wip branch covering the behavior within QML already. Wouldn't it be save to use within QML then?

Do you like the idea of having a generic QPromise<T>.as<U>() function? If not, one could also think of a template constructor QJSPromise(QPromise<T>&&) specifically taking care of JSValue conversion, right?

from qtpromise.

simonbrunel avatar simonbrunel commented on May 12, 2024

The major issue is accessing the current QJSEngine to convert the QPromise<T> value into a QJSValue. That's fine when the promise comes from QML but exposing a Q_SLOT or Q_INVOKABLE returning a QJSPromise is quite wonky. In some cases we could use the deprecated QJSValue::engine() accessor, but it's not enough, for example to reject a promise with a JS exception where there is no associated QJSValue.

Currently, it should be relatively easy to release a QML only implementation where the QJSPromise would be private and always bound to a QJSEngine. It would not initially allow to exchange promises between QML and C++ but at least it would offer a nice QML promise implementation.

I already implemented QPromise<T>.as<U>() in addition to implicit cast, I still need to write tests but I terribly lack of time. Though, that will not be enough to convert QPromise<T> -> QJSPromise because we will not have access to the QJSEngine.

from qtpromise.

simonbrunel avatar simonbrunel commented on May 12, 2024

WIP on the Qt side for a native JavaScript promise: https://codereview.qt-project.org/#/c/122066/

from qtpromise.

pwuertz avatar pwuertz commented on May 12, 2024

Interesting, sounds like they are almost at the point of merging ES6 Promises into their JS engine. Crazy thought: Could this be an opportunity to use that momentum and convince Lars Knoll to include your library to follow up on this development on the C++ side? As TP of some sort? The point being that if both worlds had a reference Promise implementation, the QML engine might as well just implement automatic conversion from/to those types instead of being forced to shoehorn everything through QObject/Gadget/QJSValue. Like they did with supporting QByteArray <-> ArrayBuffer at some point.

from qtpromise.

simonbrunel avatar simonbrunel commented on May 12, 2024

@pwuertz FYI, a C++ promise like API is under investigation for Qt 6 (QTBUG-80908).

from qtpromise.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.