56 template<
typename RTy02>
friend class CoRoutine;
59 areWeStoppedBool.store(
true);
63 return areWeStoppedBool.load();
66 void return_value(
const RTy& at) {
70 void return_value(RTy&& at) {
75 return CoRoutine<RTy>{ std::coroutine_handle<CoRoutine<RTy>::promise_type>::from_promise(*
this) };
78 std::suspend_never initial_suspend() {
82 std::suspend_always final_suspend()
noexcept {
84 areWeDone->store(
true);
89 void unhandled_exception() {
90 if (exceptionBuffer) {
91 exceptionBuffer->send(std::current_exception());
97 std::atomic_bool* areWeDone{};
98 std::atomic_bool areWeStoppedBool{};
103 if (
this != &other) {
104 coroutineHandle = other.coroutineHandle;
105 other.coroutineHandle =
nullptr;
106 coroutineHandle.promise().exceptionBuffer = &exceptionBuffer;
107 coroutineHandle.promise().areWeDone = &areWeDone;
108 currentStatus.store(other.currentStatus.load());
115 *
this = std::move(other);
123 coroutineHandle = coroutineHandleNew;
124 coroutineHandle.promise().exceptionBuffer = &exceptionBuffer;
125 coroutineHandle.promise().areWeDone = &areWeDone;
130 *
this = coroutineHandleNew;
134 if (coroutineHandle) {
135 coroutineHandle.promise().exceptionBuffer =
nullptr;
136 coroutineHandle.promise().areWeDone =
nullptr;
137 if (coroutineHandle.done()) {
138 coroutineHandle.destroy();
146 if (!coroutineHandle) {
148 }
else if (coroutineHandle && !coroutineHandle.done()) {
150 }
else if (coroutineHandle && coroutineHandle.done()) {
153 return currentStatus.load();
159 if (coroutineHandle) {
160 while (!areWeDone.load()) {
161 std::this_thread::sleep_for(1ms);
164 std::exception_ptr exceptionPtr{};
165 while (exceptionBuffer.tryReceive(exceptionPtr)) {
166 std::rethrow_exception(exceptionPtr);
167 std::this_thread::sleep_for(1ms);
169 result = std::move(coroutineHandle.promise().result);
172 throw CoRoutineError(
"CoRoutine::get(), You called get() on a CoRoutine that is "
173 "not in a valid state.");
181 if (coroutineHandle) {
182 if (!coroutineHandle.done()) {
183 coroutineHandle.promise().requestStop();
184 while (!areWeDone.load()) {
185 std::this_thread::sleep_for(1ms);
188 std::exception_ptr exceptionPtr{};
190 while (exceptionBuffer.tryReceive(exceptionPtr)) {
191 std::rethrow_exception(exceptionPtr);
192 std::this_thread::sleep_for(1ms);
194 result = std::move(coroutineHandle.promise().result);
201 std::coroutine_handle<CoRoutine<RTy>::promise_type> coroutineHandle{};
203 UnboundedMessageBlock<std::exception_ptr> exceptionBuffer{};
204 std::atomic_bool areWeDone{};
214 template<
typename RTy>
friend class CoRoutine;
217 areWeStoppedBool.store(
true);
220 bool areWeStopped() {
221 return areWeStoppedBool.load();
228 return CoRoutine<void>{ std::coroutine_handle<CoRoutine<void>::promise_type>::from_promise(*
this) };
231 std::suspend_never initial_suspend() {
235 std::suspend_always final_suspend()
noexcept {
237 areWeDone->store(
true);
242 void unhandled_exception() {
243 if (exceptionBuffer) {
244 exceptionBuffer->send(std::current_exception());
250 std::atomic_bool areWeStoppedBool{};
251 std::atomic_bool* areWeDone{};
255 if (
this != &other) {
256 coroutineHandle = other.coroutineHandle;
257 other.coroutineHandle =
nullptr;
258 coroutineHandle.promise().exceptionBuffer = &exceptionBuffer;
259 coroutineHandle.promise().areWeDone = &areWeDone;
260 currentStatus.store(other.currentStatus.load());
267 *
this = std::move(other);
275 coroutineHandle = coroutineHandleNew;
276 coroutineHandle.promise().exceptionBuffer = &exceptionBuffer;
277 coroutineHandle.promise().areWeDone = &areWeDone;
282 *
this = coroutineHandleNew;
286 if (coroutineHandle) {
287 coroutineHandle.promise().exceptionBuffer =
nullptr;
288 coroutineHandle.promise().areWeDone =
nullptr;
289 if (coroutineHandle.done()) {
290 coroutineHandle.destroy();
298 if (!coroutineHandle) {
300 }
else if (coroutineHandle && !coroutineHandle.done()) {
302 }
else if (coroutineHandle && coroutineHandle.done()) {
305 return currentStatus.load();
310 if (coroutineHandle) {
311 while (!areWeDone.load()) {
312 std::this_thread::sleep_for(1ms);
315 std::exception_ptr exceptionPtr{};
316 while (exceptionBuffer.tryReceive(exceptionPtr)) {
317 std::rethrow_exception(exceptionPtr);
318 std::this_thread::sleep_for(1ms);
321 throw CoRoutineError(
"CoRoutine::get(), You called get() on a CoRoutine that is "
322 "not in a valid state.");
328 if (coroutineHandle) {
329 if (!coroutineHandle.done()) {
330 coroutineHandle.promise().requestStop();
331 while (!areWeDone.load()) {
332 std::this_thread::sleep_for(1ms);
336 std::exception_ptr exceptionPtr{};
337 while (exceptionBuffer.tryReceive(exceptionPtr)) {
338 std::rethrow_exception(exceptionPtr);
339 std::this_thread::sleep_for(1ms);
345 std::coroutine_handle<CoRoutine<void>::promise_type> coroutineHandle{};
347 UnboundedMessageBlock<std::exception_ptr> exceptionBuffer{};
348 std::atomic_bool areWeDone{};
351 class DiscordCoreAPI_Dll NewThreadAwaiterBase {
353 static DiscordCoreInternal::CoRoutineThreadPool threadPool;
360 bool await_ready()
const noexcept {
365 NewThreadAwaiterBase::threadPool.submitTask(coroHandleNew);
366 coroHandle = coroHandleNew;
369 auto await_resume()
noexcept {
374 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.