Oatpp Coroutines

In oatpp, Coroutine is the class extended from oatpp::async::Coroutine or from oatpp::async::CoroutineWithResult.
Coroutines are processed in the oatpp::async::Processor. Root Coroutine should always be oatpp::async::Coroutine.

Example

class MyCoroutine : public oatpp::async::Coroutine<MyCoroutine> {
public:

  /*
   *  act() - entrypoint of Coroutine
   *  returns Action - what to do next
   */
  Action act() override {
    OATPP_LOGD("MyCoroutine", "act()");
    return yieldTo(&MyCoroutine::step2);
  }

  Action step2() {
    OATPP_LOGD("MyCoroutine", "step2");
    return yieldTo(&MyCoroutine::step3);
  }

  Action step3() {
    OATPP_LOGD("MyCoroutine", "step3");
    return finish();
  }

};

oatpp::async::Processor processor;
processor.addCoroutine(new MyCoroutine());
while (processor.iterate(1)) {
}

Output:

MyCoroutine:act()
MyCoroutine:step2
MyCoroutine:step3

Call Coroutine from Coroutine

class OtherCoroutine : public oatpp::async::Coroutine<OtherCoroutine> {
public:
  Action act() override {
    OATPP_LOGD("OtherCoroutine", "act()");
    return finish();
  }
};

class MyCoroutine : public oatpp::async::Coroutine<MyCoroutine> {
public:

  Action act() override {
    OATPP_LOGD("MyCoroutine", "act()");
    return OtherCoroutine::start().next(finish()); /* Action to do after OtherCoroutine finished */);
  }

};

oatpp::async::Processor processor;
processor.addCoroutine(new MyCoroutine());
while (processor.iterate(1)) {
}

Output:

MyCoroutine:act()
OtherCoroutine:act()

Call Coroutine and return Result

class CoroutineWithResult : public oatpp::async::CoroutineWithResult<CoroutineWithResult, const char* /* result type */> {
public:
  Action act() override {
    OATPP_LOGD("CoroutineWithResult", "act()");
    return _return("<result>");
  }
};

class MyCoroutine : public oatpp::async::Coroutine<MyCoroutine> {
public:

  Action act() override {
    OATPP_LOGD("MyCoroutine", "act()");
    return CoroutineWithResult::startForResult().callbackTo(&MyCoroutine::onResult);
  }

  Action onResult(const char* result) {
    OATPP_LOGD("MyCoroutine", "result='%s'", result);
    return finish();
  }

};

oatpp::async::Processor processor;
processor.addCoroutine(new MyCoroutine);
while (processor.iterate(1)) {
}

Output:

MyCoroutine:act()
CoroutineWithResult:act()
MyCoroutine:result='<result>'

Counter

class MyCoroutineCounter : public oatpp::async::Coroutine<MyCoroutineCounter> {
private:
  const char* m_name;
  v_int32 m_counter = 0;
public:

  MyCoroutineCounter(const char* name) : m_name(name) {}

  Action act() override {
    OATPP_LOGD(m_name, "counter=%d", m_counter);
    if(m_counter < 10) {
      m_counter ++;
      return repeat();
    }
    return finish();
  }

};

oatpp::async::Processor processor;
processor.addCoroutine(new MyCoroutineCounter("A"));
processor.addCoroutine(new MyCoroutineCounter("B"));
processor.addCoroutine(new MyCoroutineCounter("C"));
while (processor.iterate(1)) {
}

Output:

A:counter=0
B:counter=0
C:counter=0
A:counter=1
B:counter=1
C:counter=1
A:counter=2
B:counter=2
C:counter=2
A:counter=3
B:counter=3
C:counter=3
A:counter=4
B:counter=4
C:counter=4
A:counter=5
B:counter=5
C:counter=5
A:counter=6
B:counter=6
C:counter=6
A:counter=7
B:counter=7
C:counter=7
A:counter=8
B:counter=8
C:counter=8
A:counter=9
B:counter=9
C:counter=9
A:counter=10
B:counter=10
C:counter=10