54 class DiscordCoreAPI_Dll promise_type {
56 template<
typename RTy02>
friend class CoRoutine;
59 this->areWeStoppedBool.store(
true);
63 return this->areWeStoppedBool.load();
66 void return_value(RTy&& at) {
67 this->result = std::move(at);
71 return CoRoutine<RTy>{ std::coroutine_handle<CoRoutine<RTy>::promise_type>::from_promise(*
this) };
74 std::suspend_never initial_suspend() {
78 std::suspend_always final_suspend()
noexcept {
79 if (this->areWeDone) {
80 this->areWeDone->store(
true);
85 void unhandled_exception() {
86 if (this->exceptionBuffer) {
87 this->exceptionBuffer->send(std::current_exception());
93 std::atomic_bool areWeStoppedBool{};
94 std::atomic_bool* areWeDone{
nullptr };
100 this->coroutineHandle = other.coroutineHandle;
101 other.coroutineHandle =
nullptr;
102 this->coroutineHandle.promise().exceptionBuffer = &this->exceptionBuffer;
103 this->coroutineHandle.promise().areWeDone = &this->areWeDone;
104 this->currentStatus.store(other.currentStatus.load());
111 *
this = std::move(other);
119 this->coroutineHandle = coroutineHandleNew;
120 this->coroutineHandle.promise().exceptionBuffer = &this->exceptionBuffer;
121 this->coroutineHandle.promise().areWeDone = &this->areWeDone;
126 *
this = coroutineHandleNew;
130 if (
this && this->coroutineHandle) {
131 this->coroutineHandle.promise().exceptionBuffer =
nullptr;
132 this->coroutineHandle.promise().areWeDone =
nullptr;
133 if (this->coroutineHandle.done()) {
134 this->coroutineHandle.destroy();
142 if (!this->coroutineHandle) {
144 }
else if (this->coroutineHandle && !this->coroutineHandle.done()) {
146 }
else if (this->coroutineHandle && this->coroutineHandle.done()) {
149 return this->currentStatus.load();
155 if (
this && this->coroutineHandle) {
156 while (!this->areWeDone.load()) {
157 std::this_thread::sleep_for(1ms);
160 std::exception_ptr exceptionPtr{};
161 while (this->exceptionBuffer.
tryReceive(exceptionPtr)) {
162 std::rethrow_exception(exceptionPtr);
163 std::this_thread::sleep_for(1ms);
165 this->result = std::move(this->coroutineHandle.promise().result);
168 throw CoRoutineError(
"CoRoutine::get(), You called get() on a CoRoutine that is "
169 "not in a valid state.");
177 if (
this && this->coroutineHandle) {
178 if (!this->coroutineHandle.done()) {
179 this->coroutineHandle.promise().requestStop();
180 while (!this->areWeDone.load()) {
181 std::this_thread::sleep_for(1ms);
184 std::exception_ptr exceptionPtr{};
186 while (this->exceptionBuffer.
tryReceive(exceptionPtr)) {
187 std::rethrow_exception(exceptionPtr);
188 std::this_thread::sleep_for(1ms);
190 this->result = std::move(this->coroutineHandle.promise().result);
197 std::coroutine_handle<CoRoutine<RTy>::promise_type> coroutineHandle{
nullptr };
199 UnboundedMessageBlock<std::exception_ptr> exceptionBuffer{};
200 std::atomic_bool areWeDone{};
208 class DiscordCoreAPI_Dll promise_type {
210 template<
typename RTy>
friend class CoRoutine;
213 this->areWeStoppedBool.store(
true);
216 bool areWeStopped() {
217 return this->areWeStoppedBool.load();
224 return CoRoutine<void>{ std::coroutine_handle<CoRoutine<void>::promise_type>::from_promise(*
this) };
227 std::suspend_never initial_suspend() {
231 std::suspend_always final_suspend()
noexcept {
232 if (this->areWeDone) {
233 this->areWeDone->store(
true);
238 void unhandled_exception() {
239 if (this->exceptionBuffer) {
240 this->exceptionBuffer->send(std::current_exception());
246 std::atomic_bool areWeStoppedBool{};
247 std::atomic_bool* areWeDone{
nullptr };
251 if (
this != &other) {
252 this->coroutineHandle = other.coroutineHandle;
253 other.coroutineHandle =
nullptr;
254 this->coroutineHandle.promise().exceptionBuffer = &this->exceptionBuffer;
255 this->coroutineHandle.promise().areWeDone = &this->areWeDone;
256 this->currentStatus.store(other.currentStatus.load());
263 *
this = std::move(other);
271 this->coroutineHandle = coroutineHandleNew;
272 this->coroutineHandle.promise().exceptionBuffer = &this->exceptionBuffer;
273 this->coroutineHandle.promise().areWeDone = &this->areWeDone;
278 *
this = coroutineHandleNew;
282 if (
this && this->coroutineHandle) {
283 this->coroutineHandle.promise().exceptionBuffer =
nullptr;
284 this->coroutineHandle.promise().areWeDone =
nullptr;
285 if (this->coroutineHandle.done()) {
286 this->coroutineHandle.destroy();
294 if (!this->coroutineHandle) {
296 }
else if (this->coroutineHandle && !this->coroutineHandle.done()) {
298 }
else if (this->coroutineHandle && this->coroutineHandle.done()) {
301 return this->currentStatus.load();
306 if (
this && this->coroutineHandle) {
307 while (!this->areWeDone.load()) {
308 std::this_thread::sleep_for(1ms);
311 std::exception_ptr exceptionPtr{};
312 while (this->exceptionBuffer.
tryReceive(exceptionPtr)) {
313 std::rethrow_exception(exceptionPtr);
314 std::this_thread::sleep_for(1ms);
317 throw CoRoutineError(
"CoRoutine::get(), You called get() on a CoRoutine that is "
318 "not in a valid state.");
324 if (
this && this->coroutineHandle) {
325 if (!this->coroutineHandle.done()) {
326 this->coroutineHandle.promise().requestStop();
327 while (!this->areWeDone.load()) {
328 std::this_thread::sleep_for(1ms);
332 std::exception_ptr exceptionPtr{};
333 while (this->exceptionBuffer.
tryReceive(exceptionPtr)) {
334 std::rethrow_exception(exceptionPtr);
335 std::this_thread::sleep_for(1ms);
341 std::coroutine_handle<CoRoutine<void>::promise_type> coroutineHandle{
nullptr };
343 UnboundedMessageBlock<std::exception_ptr> exceptionBuffer{};
344 std::atomic_bool areWeDone{};
347 class DiscordCoreAPI_Dll NewThreadAwaiterBase {
349 static DiscordCoreInternal::CoRoutineThreadPool threadPool;
356 bool await_ready()
const noexcept {
361 NewThreadAwaiterBase::threadPool.submitTask(coroHandleNew);
362 this->coroHandle = coroHandleNew;
365 auto await_resume()
noexcept {
366 return this->coroHandle;
370 std::coroutine_handle<typename CoRoutine<RTy>::promise_type> coroHandle{};
CoRoutineStatus
The current status of the associated CoRoutine.
The main namespace for this library.
An error type for CoRoutines.
A CoRoutine - representing a potentially asynchronous operation/function.
CoRoutineStatus getStatus()
Collects the status of the CoRoutine.
RTy get()
Gets the resulting value of the CoRoutine.
RTy cancel()
Cancels the currently executing CoRoutine and returns the current result.
void cancel()
Cancels the currently executing CoRoutine and returns the current result.
CoRoutineStatus getStatus()
Collects the status of the CoRoutine.
void get()
Gets the resulting value of the CoRoutine.
An awaitable that can be used to launch the CoRoutine onto a new thread - as well as return the handl...
A thread-safe messaging block for data-structures.
bool tryReceive(OTy &object)
Tries to receive an object of type OTy to be placed into a reference.