All Projects → danvratil → qcoro

danvratil / qcoro

Licence: MIT license
C++ Coroutines for Qt

Programming Languages

C++
36643 projects - #6 most used programming language
CMake
9771 projects
c
50402 projects - #5 most used programming language

Projects that are alternatives of or similar to qcoro

programming-with-cpp20
Companion source code for "Programming with C++20 - Concepts, Coroutines, Ranges, and more"
Stars: ✭ 142 (-5.33%)
Mutual labels:  coroutines, cpp20
LibreMines
A Free/Libre and Open Source Software Qt based Minesweeper game available for GNU/Linux, FreeBSD and Windows systems.
Stars: ✭ 55 (-63.33%)
Mutual labels:  qt5, qt6
NotepadNext
A cross-platform, reimplementation of Notepad++
Stars: ✭ 5,715 (+3710%)
Mutual labels:  qt5, qt6
banana
🍌 Modern C++ Telegram Bot API library
Stars: ✭ 30 (-80%)
Mutual labels:  coroutines, cpp20
agrpc
Async GRPC with C++20 coroutine support
Stars: ✭ 53 (-64.67%)
Mutual labels:  coroutines, cpp20
zab
C++20 liburing backed coroutine executor and event loop framework.
Stars: ✭ 54 (-64%)
Mutual labels:  coroutines, cpp20
qt-downloader
CLI to download Qt on headless systems
Stars: ✭ 39 (-74%)
Mutual labels:  qt5, qt6
sycl
SYCL for Vitis: Experimental fusion of triSYCL with Intel SYCL oneAPI DPC++ up-streaming effort into Clang/LLVM
Stars: ✭ 80 (-46.67%)
Mutual labels:  cpp20
cxbqn
BQN virtual machine
Stars: ✭ 20 (-86.67%)
Mutual labels:  cpp20
kotlin-kafka-and-kafka-streams-examples
Kafka with KafkaReactor and Kafka Streams Examples in Kotlin
Stars: ✭ 33 (-78%)
Mutual labels:  coroutines
doctest
The fastest feature-rich C++11/14/17/20 single-header testing framework
Stars: ✭ 4,434 (+2856%)
Mutual labels:  cpp20
QtOSG
A proof-of-concept widget for integrating Qt and OpenSceneGraph in a thread-safe manner
Stars: ✭ 103 (-31.33%)
Mutual labels:  qt5
pastelyst
A Web Paste Tool built with Cutelyst and KDE Frameworks
Stars: ✭ 19 (-87.33%)
Mutual labels:  qt5
floppy
🧩 Handling and maintain your UI view component easily
Stars: ✭ 55 (-63.33%)
Mutual labels:  coroutines
HitagiEngine
DirectX12 game engine
Stars: ✭ 51 (-66%)
Mutual labels:  cpp20
QtPyConvert
An automatic Python Qt binding transpiler to the Qt.py abstraction layer.
Stars: ✭ 66 (-56%)
Mutual labels:  qt5
Android-Assignment
This assignment gives you basically a post list and its detail with comments.🚀
Stars: ✭ 32 (-78.67%)
Mutual labels:  coroutines
ResDelivery-Hilt-Coroutines-Mvvm-Single-Activity
This is a Sample Single Activity App (Multi Fragments) that uses Dagger-Hilt, Coroutines Flows, Paging 3 & Mvvm Clean Architecture
Stars: ✭ 28 (-81.33%)
Mutual labels:  coroutines
engine
A personal game engine project, with development focus towards 2D/2.5D games.
Stars: ✭ 32 (-78.67%)
Mutual labels:  cpp20
slashdiablo-launcher
A lightweight cross platform Slashdiablo game launcher for Diablo II, written in Go & QML.
Stars: ✭ 29 (-80.67%)
Mutual labels:  qt5

Linux CI Windows CI MacOS CI Docs build Latest release License: MIT C++20 Supported Compilers

QCoro - Coroutines for Qt5 and Qt6

The QCoro library provides set of tools to make use of C++20 coroutines with Qt.

Take a look at the example below to see what an amazing thing coroutines are:

QNetworkAccessManager networkAccessManager;
// co_await the reply - the coroutine is suspended until the QNetworkReply is finished.
// While the coroutine is suspended, *the Qt event loop runs as usual*.
const QNetworkReply *reply = co_await networkAccessManager.get(url);
// Once the reply is finished, your code resumes here as if nothing amazing has just happened ;-)
const auto data = reply->readAll();

It requires a compiler with support for the couroutines TS.

Documentation

👉 📘 Documentation

Supported Qt Types

QCoro provides QCoro::Task<T> which can be used as a coroutine return type and allows the coroutine to be awaited by its caller. Additionally, it provides qCoro() wrapper function, which wraps an object of a supported Qt type to a thin, coroutine-friendly wrapper that allows co_awaiting asynchronous operations on this type. Finally, it allows to directly co_await default asynchronous operations on certain Qt types. Below is a list of a few supported types, you can find the full list in the documentation.

QDBusPendingCall

QCoro can wait for an asynchronous D-Bus call to finish. There's no need to use QDBusPendingCallWatcher with QCoro - just co_await the result instead. While co_awaiting, the Qt event loop runs as usual.

QDBusInterface remoteServiceInterface{serviceName, objectPath, interface};
const QDBusReply<bool> isReady = co_await remoteServiceInterface.asyncCall(QStringLiteral("isReady"));

📘 Full documentation here.

QFuture

QFuture represents a result of an asynchronous task. Normally you have to use QFutureWatcher to get notified when the future is ready. With QCoro, you can just co_await it!

const QFuture<int> task1 = QtConcurrent::run(....);
const QFuture<int> task2 = QtConcurrent::run(....);

const int a = co_await task1;
const int b = co_await task2;

co_return a + b;

📘 Full documentation here.

QNetworkReply

Doing network requests with Qt can be tedious - the signal/slot approach breaks the flow of your code. Chaining requests and error handling quickly become mess and your code is broken into numerous functions. But not with QCoro, where you can simply co_await the QNetworkReply to finish:

QNetworkReply qnam;
QNetworkReply *reply = qnam.get(QStringLiteral("https://github.com/danvratil/qcoro"));
const auto contents = co_await reply;
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError) {
    co_return handleError(reply);
}

const auto link = findLinkInReturnedHtmlCode(contents);
reply = qnam.get(link);
const auto data = co_await reply;
reply->deleteLater();
if (reply->error() != QNetworkReply::NoError) {
    co_return handleError(reply);
}
 ...

📘 Full documentation here.

QTimer

Maybe you want to delay executing your code for a second, maybe you want to execute some code in repeated interval. This becomes super-trivial with co_await:

QTimer timer;
timer.setInterval(1s);
timer.start();

for (int i = 1; i <= 100; ++i) {
    co_await timer;
    qDebug() << "Waiting for " << i << " seconds...";
}

qDebug() << "Done!";

📘 Full documentation here.

QIODevice

QIODevice is a base-class for many classes in Qt that allow data to be asynchronously written and read. How do you find out that there are data ready to be read? You could connect to QIODevice::readyRead() singal, or you could use QCoro and co_await the object:

socket->write("PING");
// Waiting for "pong"
const auto data = co_await socket;
co_return calculateLatency(data);

📘 Full documentation here.

...and more!

Go check the full documentation to learn more.

.then() continuations

Sometimes it's not possible to use co_await to handle result of a coroutine - usually when interfacing with a 3rd party code that does not support coroutines. In those scenarios it's possible to chain a continuation callback to the coroutine which will get invoked asynchronously when the coroutine finishes.

void regularFunction() {
    someCoroutineReturningInt().then([](int result) {
        // handle result
    });
}

The continuation callback can also be a coroutine and the result of the entire expression is Task where T is the return type of the continuation. Thanks to that it's possible to co_await the entire chain, or chain multiple .then() continuations.

📘 Full documentation here.

Generators

Generator is a coroutine that lazily produces multiple values. While there's nothing Qt-specific, QCoro provides the necessary tools for users to create custom generators in their Qt applications.

QCoro provides API for both synchronous generators (QCoro::Generator<T>) and asynchronous generators (QCoro::AsyncGenerator<T>). Both generators provide container-like API: begin() and end() member functions that return iterator-like objects, which is well-known and established API and makes generators compatible with existing algorithms.

QCoro::Generator<int> fibonacci() {
    quint64 a = 0, b = 0;
    Q_FOREVER {
        co_yield b;
        const auto tmp = b;
        a = b;
        b += tmp;
    }
}

void printFib(quint64 max) {
    for (auto fib : fibonacci()) {
        if (fib > max) {
            break;
        }
        std::cout << fib << std::endl;
    }
}

📘 Full documentation here.

License

MIT License

Copyright (c) 2022 Daniel Vrátil <[email protected]>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].