QCoro ライブラリは、Qt で C++20 コルーチンを利用するためのツールのセットを提供します。
コルーチンがどれほど素晴らしいかを理解するには、以下の例を見てください。
QNetworkAccessManager networkAccessManager;// co_await 応答 - QNetworkReply が完了するまでコルーチンは一時停止されます。// コルーチンが一時停止されている間、*Qt イベント ループは通常どおり実行されます*.const QNetworkReply *reply = co_await networkAccessManager.get(url); // 返信が完了すると、何も驚くべきことがなかったかのようにコードがここから再開されます;-)const auto data = Reply->readAll();
これには、コルーチン TS をサポートするコンパイラーが必要です。サポートされるコンパイラーとバージョンのリストについては、ドキュメントを参照してください。
ドキュメント
QCoro は、Qt で C++20 コルーチンを簡単に使用するために必要なツールを提供します。ライブラリの基礎となるのはQCoro::Task<T>
です。これは実行されたコルーチンを表し、呼び出し元がコルーチンの結果を非同期的に待機できるようにします。さらに、QCoro は、非同期操作を直接co_await
できるようにするQTimer
、 QNetworkReply
、 QDBusPendingCall
、 QFuture
などの一般的な Qt タイプのラッパーのセットを提供します。
さらに、多くのネイティブ Qt 関数と型をラップしてコルーチンに適したものにすることができる魔法のqCoro()
関数があります。
サポートされているすべての機能と Qt タイプの完全なリストについては、ドキュメントを確認してください。
QDBusPendingCall
QCoro は、非同期 D-Bus 呼び出しが完了するまで待つことができます。 QCoro でQDBusPendingCallWatcher
を使用する必要はありません。代わりに結果co_await
だけです。 co_await の間、Qt イベント ループは通常どおり実行されます。
QDBusInterfaceremoteServiceInterface{サービス名, オブジェクトパス, インターフェース};const QDBusReply<bool> isReady = co_await RemoteServiceInterface.asyncCall(QStringLiteral("isReady"));
完全なドキュメントはこちらから。
QFuture
QFuture は非同期タスクの結果を表します。通常、将来の準備ができたときに通知を受け取るには、 QFutureWatcher
使用する必要があります。 QCoro を使用すると、ただco_await
だけで済みます。
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;
完全なドキュメントはこちらから。
QNetworkReply
Qt を使用してネットワーク リクエストを実行するのは面倒な場合があります。シグナル/スロットのアプローチではコードのフローが中断されます。リクエストの連鎖とエラー処理はすぐに混乱し、コードは多数の関数に分割されます。しかし、QCoro ではそうではなく、単にQNetworkReply
が完了するのをco_await
ことができます。
QNetworkAccessManager qnam; QNetworkReply *reply = qnam.get(QStringLiteral("https://github.com/qcoro/qcoro"));const auto content = co_await Reply; Reply->deleteLater();if (reply->error() != QNetworkReply::NoError) {co_return handleError(reply); }const 自動リンク = findLinkInReturnedHtmlCode(contents); Reply = qnam.get(link);const auto data = co_await Reply; Reply->deleteLater();if (reply->error() != QNetworkReply::NoError) {co_return handleError(reply); } ...
完全なドキュメントはこちらから。
QTimer
コードの実行を 1 秒間遅らせたい場合もあれば、一定の間隔でコードを実行したい場合もあります。これはco_await
使用すると非常に簡単になります。
QTimer タイマー; timer.setInterval(1s); timer.start();for (int i = 1; i <= 100; ++i) {co_await timer;qDebug() << "" << i << " 秒間待機しています..."; }qDebug() << "完了!";
完全なドキュメントはこちらから。
QIODevice
QIODevice
、データの非同期書き込みと読み取りを可能にする Qt の多くのクラスの基本クラスです。読み取る準備ができているデータがあることをどのようにして確認しますか? QIODevice::readyRead()
単体に接続することも、QCoro を使用してオブジェクトco_await
こともできます。
socket->write("PING");// "pong" を待機中 const auto data = co_awaitソケット;co_return CalculateLatency(data);
完全なドキュメントはこちらから。
詳細については、完全なドキュメントを確認してください。
co_await
使用してコルーチンの結果を処理できない場合があります。通常は、コルーチンをサポートしていないサードパーティのコードとやり取りする場合です。これらのシナリオでは、コルーチンの終了時に非同期で呼び出される継続コールバックをコルーチンにチェーンすることができます。
void RegularFunction() {someCoroutineReturningInt().then([](int result) {// handle result}); }
継続コールバックはコルーチンにすることもでき、式全体の結果は Task になります。ここで、T は継続の戻り値の型です。そのおかげで、チェーン全体co_await
、複数の.then()
継続をチェーンしたりすることが可能になります。
完全なドキュメントはこちらから。
ジェネレーターは、複数の値を遅延生成するコルーチンです。 Qt 固有のものは何もありませんが、QCoro はユーザーが Qt アプリケーションでカスタム ジェネレーターを作成するために必要なツールを提供します。
QCoro は、同期ジェネレーター ( QCoro::Generator<T>
) と非同期ジェネレーター ( QCoro::AsyncGenerator<T>
) の両方に API を提供します。どちらのジェネレーターも、コンテナーのような API、つまりイテレーターのようなオブジェクトを返すメンバー関数begin()
およびend()
を提供します。これはよく知られ確立された API であり、ジェネレーターを既存のアルゴリズムと互換性を持たせます。
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; } }
完全なドキュメントはここにあります。
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.