#include "precompile.h" #include #include #include "coroutine.h" #include "comgr.h" #include "app.h" void Awaiter::Await(std::shared_ptr notifyer) { notifyers_.push_back(notifyer); DoAwait(); } std::shared_ptr Awaiter::Sleep(int time) { return std::make_shared(time); } void Promise::DoAwait() { } Coroutine::Coroutine(std::function cb) { INIT_LIST_HEAD(&co_entry_); INIT_LIST_HEAD(&exec_entry_); list_add_tail(&co_entry_, &CoMgr::Instance()->co_list_); Attach(); cb_ = cb; source_ = std::make_shared::pull_type> ( [this] (boost::coroutines2::coroutine::push_type& sink) { CallEnter(sink); cb_(this); CallExit(sink); for (auto notifyer : notifyers_) { if (!notifyer.expired()) { notifyer.lock()->DoResume(); } } }); } Coroutine::~Coroutine() { #ifdef DEBUG a8::XPrintf("Coroutine::~Coroutine()\n", {}); #endif Deatch(); list_del_init(&co_entry_); } bool Coroutine::Exec() { if (*source_) { (*source_)(); return true; } else { return false; } } void Coroutine::CoSuspend() { Deatch(); } void Coroutine::CoResume() { Attach(); } void Coroutine::CoYield() { (*sink_)(); } std::shared_ptr Coroutine::CoAwait(std::shared_ptr awaiter) { CoSuspend(); awaiter->Await(shared_from_this()); while (!awaiter->Done()) { CoYield(); } //CoResume(); return awaiter->GetResult(); } void Coroutine::Attach() { list_add_tail(&exec_entry_, &CoMgr::Instance()->exec_list_); } void Coroutine::Deatch() { if (!list_empty(&exec_entry_)) { list_del_init(&exec_entry_); } } void Coroutine::CallEnter(boost::coroutines2::coroutine::push_type& sink) { sink_ = &sink; } void Coroutine::CallExit(boost::coroutines2::coroutine::push_type& sink) { sink_ = nullptr; } void Coroutine::DoAwait() { } void Coroutine::DoResume() { CoResume(); } void TimerPromise::DoAwait() { f8::Timer::Instance()->SetTimeout ( time_, [this, self = shared_from_this()] (int event, const a8::Args* args) mutable { if (event == a8::TIMER_EXEC_EVENT) { done_ = true; for (auto notifyer : notifyers_) { if (!notifyer.expired()) { notifyer.lock()->DoResume(); } } } }); }