Comments (4)
Hi,
thanks for the report. Indeed we allow constructing an empty invalid QCoro::Task
, so awaiting it shouldn't crash (not sure what it should do, though). I'll try to fix it, and probably deprecate the default constructor as it serves no real purpose. An empty QCoro::Task
makes little sense.
As a side note, you ran into the problem because you are using QCoro wrong (at least from what I can see from the minimal sample). Just returning a QmlTask
doesn't magically make your slowOperation()
function non-blocking. Your implementation will still block the main thread for 1s.
You need to have your "slow operation" implemented as a proper real coroutine, then you just wrap the returned QCoro::Task
(which represents the running coroutine) into QCoro::QmlTask
which makes it work in QML.
class TestQmlType : public QObject
{
Q_OBJECT
QML_ELEMENT
public:
explicit TestQmlType(QObject *parent = nullptr);
Q_INVOKABLE QCoro::QmlTask slowOperation();
private:
// A real coroutine with QCoro::Task<> return type
QCoro::Task<QVariant> doSlowOperation();
};
QCoro::QmlTask TestQmlType::slowOperation()
{
return QCoro::QmlTask(doSlowOperation());
}
QCoro::Task<QVariant> TestQmlType::doSlowOperation()
{
qInfo() << "Slow operation start";
co_await QCoro::sleepFor(1s);
qInfo() << "Slow operation end";
co_return 42;
}
from qcoro.
Ahh, thanks! I was a bit confused by the docs then. Is there a way to move this into a single function?
return QCoro::QmlTask([]() -> QCoro::Task<QVariant> {
qInfo() << "Slow operation end";
co_return 42;
});
gives me:
C:\Users\Ryzen-7950X\Documents\CoroTest\TestQmlType.cpp(8): error C2440: '<function-style-cast>': cannot convert from 'TestQmlType::slowOperation::<lambda_1>' to 'QCoro::QmlTask'
C:\Users\Ryzen-7950X\Documents\CoroTest\TestQmlType.cpp(8): note: 'QCoro::QmlTask::QmlTask': no overloaded function could convert all the argument types
C:\Users\Ryzen-7950X\Documents\CoroTest\ThirdParty\qcoro\QCoro\qml\qcoroqmltask.h(37): note: could be 'QCoro::QmlTask::QmlTask(QCoro::Task<QVariant> &&)'
C:\Users\Ryzen-7950X\Documents\CoroTest\TestQmlType.cpp(8): note: 'QCoro::QmlTask::QmlTask(QCoro::Task<QVariant> &&)': cannot convert argument 1 from 'TestQmlType::slowOperation::<lambda_1>' to 'QCoro::Task<QVariant> &&'
C:\Users\Ryzen-7950X\Documents\CoroTest\TestQmlType.cpp(11): note: Reason: cannot convert from 'TestQmlType::slowOperation::<lambda_1>' to 'QCoro::Task<QVariant>'
C:\Users\Ryzen-7950X\Documents\CoroTest\TestQmlType.cpp(11): note: No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
C:\Users\Ryzen-7950X\Documents\CoroTest\ThirdParty\qcoro\QCoro\qml\qcoroqmltask.h(68): note: or 'QCoro::QmlTask::QmlTask(QCoro::Task<void> &&)'
C:\Users\Ryzen-7950X\Documents\CoroTest\ThirdParty\qcoro\QCoro\qml\qcoroqmltask.h(59): note: or 'QCoro::QmlTask::QmlTask(T &&)'
C:\Users\Ryzen-7950X\Documents\CoroTest\ThirdParty\qcoro\QCoro\qml\qcoroqmltask.h(44): note: or 'QCoro::QmlTask::QmlTask(QCoro::Task<T> &&)'
C:\Users\Ryzen-7950X\Documents\CoroTest\TestQmlType.cpp(8): note: while trying to match the argument list '(TestQmlType::slowOperation::<lambda_1>)'
Also looks like the FetchContent_Populate I use is not fully correct, because I cannot include #include "QCoro/core/qcorotimer.h"
C:\Users\Ryzen-7950X\Documents\CoroTest\ThirdParty\qcoro\qcoro\core\qcorotimer.h:8: error: C1083: Cannot open include file: 'qcorocore_export.h': No such file or directory
from qcoro.
Well, the documentation is far from perfect :-) I'll try to update it later...
You are on the right track, but you have to call the lambda so that you obtain the QCoro::Task<>
that can be passed into QmlTask
. In your case, the coroutine is synchronous (there's no co_await
) so when called it will run, finish, store its result into a QCoro::Task
and return that to you. You pass it to QmlTask
and QmlTask
will extract the result and provide it into QML (by invoking your .then() callback in JS).
If your lambda was a coroutine that suspends, then you would call it, the coroutine would run as a regular function until it would reach co_await
- at that point it would suspend and return the QCoro::Task
holding a reference to the suspended coroutine, which you then pass to QmlTask
again. Once the thing being awaiting is finished, the coroutine would be resumed and run to its completion, storing the result to the QCoro::Task
object you already have and that in turn would once again trigger the JS callback in your QML code.
Also looks like the FetchContent_Populate I use is not fully correct, because I cannot include #include "QCoro/core/qcorotimer.h"
Are you linking against the QCoro::Core target in your CMakeLists? That should pull in all the correct include paths.
from qcoro.
Are you linking against the QCoro::Core target in your CMakeLists? That should pull in all the correct include paths.
Yes, this is from the attached test project: https://github.com/danvratil/qcoro/files/13634187/CoroTest.zip
EDIT: Ok looks like I was wrong. Normally I would expect the QCoro6::Qml to have an public dependency to QCoro6::Core :)
include(FetchContent)
FetchContent_Populate(
QCoro
GIT_REPOSITORY https://github.com/danvratil/qcoro.git
GIT_TAG 12c052e8e29b9f976ea1c02af7c845573bd8efa3
# Workaround because: 1. QtCreator cannot handle QML_ELEMENT stuff when it is in bin folder
# https://bugreports.qt.io/browse/QTCREATORBUG-27083
SOURCE_DIR ThirdParty/qcoro)
add_subdirectory(ThirdParty/qcoro)
# Does not work, needs to set(CMAKE_CXX_STANDARD 23)
qcoro_enable_coroutines()
qt_add_qml_module(appCoroTest
URI CoroTest
VERSION 1.0
QML_FILES Main.qml
SOURCES TestQmlType.h TestQmlType.cpp
)
target_link_libraries(appCoroTest
PRIVATE Qt6::Quick QCoro6::Qml
)
from qcoro.
Related Issues (20)
- `CheckAtomic.cmake` Fails on Windows with LLVM Clang
- Build Failure with Clang `15.x`< on Windows in Debug
- QCoroSignal crashes
- QCoro::waitFor does not rethrow exceptions
- Add latest Qt6 to CI
- Bind coroutine to a QObject lifetime HOT 6
- Make not co_awaiting a coroutine trigger -Wunused-result HOT 1
- Add this library to vcpkg HOT 1
- Apple Clang ICEs in Release build of QCoro HOT 1
- Update QCoro in ConanCenter
- Add support to work with database HOT 2
- Next release HOT 3
- like winrt HOT 2
- support mqtt HOT 2
- Qt Design Studio : Mocking QCoro::QmlTask in Javascript or QML HOT 3
- Clang 14.x ornery about std::experimental::coroutine_traits HOT 3
- Illogical result of the `write` function.
- Bug: application crashes when signal from another thread timeouts HOT 1
- Support for move only types in QFuture via takeResult
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from qcoro.