Example #1
0
  /// 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();
  }
Example #2
0
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());
}