Squid::Tasks 1.0.0
C++14 coroutine-based task library for games
|
#include <Task.h>
Public Member Functions | |
Task () | |
Default constructor (constructs an invalid handle) | |
Task (nullptr_t) | |
Null-pointer constructor (constructs an invalid handle) | |
Task (const Task &in_otherTask) | |
Copy constructor (TaskHandle/WeakTaskHandle only) | |
Task (Task &&in_otherTask) noexcept | |
Move constructor. | |
Task & | operator= (nullptr_t) noexcept |
Null-pointer assignment operator (makes the handle invalid) | |
Task & | operator= (const Task &in_otherTask) |
Copy assignment operator (TaskHandle/WeakTaskHandle only) | |
Task & | operator= (Task &&in_otherTask) noexcept |
Move assignment operator. | |
~Task () | |
Destructor. | |
bool | IsValid () const |
Returns whether the underlying coroutine is valid. | |
operator bool () const | |
Conversion-to-bool that yields whether an underlying coroutine is set for the task. | |
bool | IsDone () const |
Returns whether the task has terminated. | |
bool | IsStopRequested () const |
Returns whether a stop request has been issued for the task. | |
void | RequestStop () |
Issues a request for the task to terminate gracefully as soon as possible. | |
void | Kill () |
Immediately terminates the task. | |
template<typename U = tRet, typename std::enable_if_t<!std::is_void< U >::value > * = nullptr> | |
std::optional< tRet > | TakeReturnValue () |
Attempts to take the task's return value (throws error if return value is either orphaned or was already taken) | |
eTaskStatus | Resume () |
Resumes the task (Task/WeakTask only) | |
std::string | GetDebugName (std::optional< TaskDebugStackFormatter > in_formatter={}) const |
Gets this task's debug name (use TASK_NAME to set the debug name) | |
std::string | GetDebugStack (std::optional< TaskDebugStackFormatter > in_formatter={}) const |
Gets this task's debug stack (use TASK_NAME to set a task's debug name) | |
auto | CancelIf (tTaskCancelFn in_cancelFn) && |
auto | CancelIfStopRequested () && |
auto | StopIf (tTaskCancelFn in_cancelFn) && |
Returns wrapper task that requests a stop on this task when the given function returns true, then waits for the task to terminate (without timeout). More... | |
auto | StopIf (tTaskCancelFn in_cancelFn, tTaskTime in_timeout) && |
Returns wrapper task that requests a stop on this task when the given function returns true, then waits for the task to terminate (with timeout in the global time-stream). More... | |
template<typename tTimeFn > | |
auto | StopIf (tTaskCancelFn in_cancelFn, tTaskTime in_timeout, tTimeFn in_timeFn) && |
Returns wrapper task that requests a stop on this task when the given function returns true, then waits for the task to terminate (with timeout in a given time-stream). More... | |
Task is a high-level task handle used to manage the lifetime and execution of an underlying coroutine
The Task class is actually a template class that implements 4 user-level handle types:
Handle Type | Return Type | Resumable? | Ref Strength |
---|---|---|---|
Task | <any type> | Yes | Strong |
WeakTask | void | Yes | Weak |
TaskHandle | <any type> | No | Strong |
WeakTaskHandle | void | No | Weak |
It is possible to convert between these 4 types, but not all conversions are permitted. The rules for conversion are:
In simpler terms, this means: a handle can always convert to a handle type with fewer capabilities, but not vice-versa.
Generally-speaking, it would be unsafe to convert in such a way that would add handle properties, hence the motivation for these conversion rules. Care has been taken, however, to provide clear human-readable compile-time error messages if and when an invalid conversion is attempted in code.
For a given coroutine instance, it is impossible to have more than a single resumable handle that references it at runtime. We refer to this as the "single-resumer rule". Because both Task and WeakTask are move-only types that cannot be copy-constructed or copy-assigned from other handles, this guarantees at compile-time that there will never be two handles that are able to resume the same underlying coroutine. This compile-time guarantee was implemented after many insidious bugs emerged in gameplay code written using early versions of the Squid::Tasks library.
When a task's single-resumer handle is destroyed, the task is immediately killed. If a coroutine were able to remain suspended without the possibility of ever being resumed again, then any task waiting for it to terminate would deadlock. For this reason, Squid::Tasks enforces that all coroutines must have a valid resumable handle at all times, otherwise they are immediately killed.
(If you are unfamiliar with what it meant by "move-only type", we recommend you research "C++ move semantics" to familiarize yourself.)
The default lifetime of a Task's underlying coroutine is determined by the handles the refer to it:
This lifetime management model is essentially the same as a strong-pointer/weak-pointer model, with the added constraint that tasks are killed as soon as they can no longer logically be resumed.
tRet | Return type of the underlying coroutine (can be void if the coroutine does not co_return a value) |
RefType | Whether this handle holds a strong or weak reference to the underlying coroutine |
Resumable | Whether this handle can be used to resume the underlying coroutine |
|
inline |
Returns wrapper task that kills this task when the given function returns true. Returns whether wrapped task was canceled. Task return value will be bool if wrapped task had void return type, otherwise std::optional<tRet>.
|
inline |
Returns wrapper task that kills this task when a stop request is issued on it. Returns whether wrapped task was canceled. Task return value will be bool if wrapped task had void return type, otherwise std::optional<tRet>.
|
inline |
Returns wrapper task that requests a stop on this task when the given function returns true, then waits for the task to terminate (without timeout).
Task returns whether wrapped task was canceled. Task return value will be bool if wrapped task had void return type, otherwise std::optional<tRet>. Returns wrapper task that requests a stop on this task when the given function returns true
|
inline |
Returns wrapper task that requests a stop on this task when the given function returns true, then waits for the task to terminate (with timeout in the global time-stream).
Task returns whether wrapped task was canceled. Task return value will be bool if wrapped task had void return type, otherwise std::optional<tRet>.
|
inline |
Returns wrapper task that requests a stop on this task when the given function returns true, then waits for the task to terminate (with timeout in a given time-stream).
Task returns whether wrapped task was canceled. Task return value will be bool if wrapped task had void return type, otherwise std::optional<tRet>.