/// Waits for the given number of records to be reached, before the given timeout. qi::FutureSync<bool> waitUntil(unsigned int nofRecords, const qi::Duration& timeout) const { qi::Promise<bool> waiting; async([this, waiting, nofRecords, timeout]() mutable { if(nofRecords <= _records.size()) { waiting.setValue(true); return; } qi::SignalLink recordedSubscription; // track timeout auto timingOut = asyncDelay([this, waiting, &recordedSubscription]() mutable { waiting.setValue(false); recorded.disconnect(recordedSubscription); }, timeout); // be called after signal emissions are recorded recordedSubscription = recorded.connect(stranded( [this, waiting, &recordedSubscription, timingOut, nofRecords]() mutable { if (nofRecords <= _records.size()) { waiting.setValue(true); timingOut.cancel(); recorded.disconnect(recordedSubscription); } // no need for scheduling in the strand because it is a direct connection })).setCallType(qi::MetaCallType_Direct); }); return waiting.future(); }
void ex_countdown_s() { // 5 second countdown const int n = 5; // startAsync() packages an asynchronous coroutine as a Task. Tasks are a generic, composable // representation of asynchronous operations. They serve as building blocks that may be awaited // from within other asynchronous coroutines. ut::Task<void> task = ut::stackful::startAsync([n]() { for (int i = n; i > 0; i--) { printf("%d...\n", i); // Suspend for 1 second. ut::stackful::await_(asyncDelay(1000)); } printf("liftoff!\n"); }); // In order to do meaningful work CppAsync requires some kind of run loop (Qt / GTK / // MFC / Boost.Asio / ...). Events should be dispatched to the run loop, enabling // coordination of concurrent tasks from this single thread. // // Here a custom Looper runs until there are no more scheduled operations. sLooper.run(); assert(task.isReady()); }
void ex_abortableCountdown_s() { // 5 second countdown const int n = 5; ut::Task<void> task = ut::stackful::startAsync([n]() { auto readLineTask = asyncReadLine(); for (int i = n; i > 0; i--) { printf("%d\n", i); // Suspend for up to 1 second, or until key press. auto *doneTask = ut::stackful::awaitAny_( readLineTask, asyncDelay(1000)); if (doneTask == &readLineTask) { printf("aborted!\n"); sLooper.cancelAll(); return; } } printf("liftoff!\n"); // Stop pinging when done. sLooper.cancelAll(); }); // Print every 100ms to show the even loop is not blocked. ping(); // Loop until there are no more scheduled operations. sLooper.run(); assert(task.isReady()); }