Allow Task<TaskVoid> when using coroutines to not require co_returning a value

This commit is contained in:
camila314 2025-01-30 01:22:14 -06:00
parent c1cae85672
commit 2bfff1afe4

View file

@ -10,7 +10,7 @@
namespace geode {
namespace geode_internal {
template <class T, class P>
struct TaskPromise;
struct TaskPromiseBase;
template <class T, class P>
struct TaskAwaiter;
@ -162,7 +162,7 @@ namespace geode {
friend class Task;
template <class, class>
friend struct geode_internal::TaskPromise;
friend struct geode_internal::TaskPromiseBase;
template <class, class>
friend struct geode_internal::TaskAwaiter;
@ -323,7 +323,7 @@ namespace geode {
friend class Task;
template <class, class>
friend struct geode_internal::TaskPromise;
friend struct geode_internal::TaskPromiseBase;
template <class, class>
friend struct geode_internal::TaskAwaiter;
@ -951,20 +951,22 @@ namespace geode {
// ```
namespace geode {
struct TaskVoid {};
namespace geode_internal {
template <class T, class P>
struct TaskPromise {
struct TaskPromiseBase {
using MyTask = Task<T, P>;
std::weak_ptr<typename MyTask::Handle> m_handle;
~TaskPromise() {
~TaskPromiseBase() {
// does nothing if its not pending
MyTask::cancel(m_handle.lock());
}
std::suspend_always initial_suspend() noexcept {
queueInMainThread([this] {
std::coroutine_handle<TaskPromise>::from_promise(*this).resume();
std::coroutine_handle<TaskPromiseBase>::from_promise(*this).resume();
});
return {};
}
@ -978,15 +980,15 @@ namespace geode {
return handle;
}
void return_value(T x) {
MyTask::finish(m_handle.lock(), std::move(x));
}
std::suspend_never yield_value(P value) {
MyTask::progress(m_handle.lock(), std::move(value));
return {};
}
void return_base(T value) {
MyTask::finish(m_handle.lock(), std::move(value));
}
bool isCancelled() {
if (auto p = m_handle.lock()) {
return p->is(MyTask::Status::Cancelled);
@ -995,6 +997,19 @@ namespace geode {
}
};
template <class T, class P>
struct TaskPromise : public TaskPromiseBase<T, P> {
void return_value(T value) {
this->return_base(value);
}
};
template <class P>
struct TaskPromise<TaskVoid, P> : public TaskPromiseBase<TaskVoid, P> {
void return_void() {
this->return_base({});
}
};
template <class T, class P>
struct TaskAwaiter {
Task<T, P> task;