A CYIFuture object is a container for a value that will be assigned at a future time, typically from a different thread. The templated type of this class is the type of value that can be stored in this object.
Functions are provided to allow a user to get the result of the content of the CYIFuture. If no value has been assigned yet, the user's thread will block until a value is assigned, or until a user-specified timeout is reached. Once a value has been assigned, the getter functions return immediately.
A value can only be assigned to a CYIFuture once. Further attempts to assign a value will return failure and will have no effect. Getters can be used to obtain a reference to the stored value, and Take() can be used to get move the assigned value out of the CYIFuture.
Signals can optionally be connected so that users are notified when a value is assigned to the CYIFuture or when the future has been cancelled. The future itself is passed as argument to the signal to support move-only types. The signal slot, however, can take the underlying type as parameter when the type is copyable.
Signals in CYIFuture objects differ slightly from regular CYISignal signals. The CYIFuture guarantee emitting where race conditions are possible. For example, if a connection is established to the Completed signal but the associated task had already completed (and thus the Completed signal had already been emitted), then the Completed signal will be emitted immediately for the newly-established connection.
Futures also support continuations, added by a call to Then(). Continuations are similar to signals, but can be run on a new thread or on the default thread pool. By default, continuations run on the UI thread.
A CYIFuture object can optionally be associated with a CYITask object. This association is done through the CYITask itself. Only one task can be associated with a CYIFuture object, and that link cannot be broken once it has been made. When used with an associated task, cancelling a future will result in the associated task being cancelled as well (unless it has already started executing). Unlike with std::future, deleting a CYIFuture object will never block and the associated task will continue running.
Copies of futures share the same task association. When a value is assigned to a future, copies of that future have access to the same value through a shared state. Signals and continuations are also shared between futures and their copies.
All public functions, with the exception of the destructor, are thread-safe.
Examples:
ResultType | the type of object that can be assigned to this CYIFuture object. |
#include <thread/YiFuture.h>
Public Member Functions | |
CYIFuture () | |
CYIFuture (ResultType(*pDefaultFactory)()) | |
CYIFuture (const CYIFuture &other) | |
CYIFuture (CYIFuture &&other) noexcept | |
CYIFuture & | operator= (const CYIFuture &other) |
CYIFuture & | operator= (CYIFuture &&other) noexcept |
void | Reset () |
const ResultType & | Get (bool *pValueAssigned=nullptr) const |
ResultType | Get (uint64_t timeoutMs, bool *pValueAssigned=nullptr) const |
bool | Set (ResultType rValue) |
ResultType | Take (bool *pValueAssigned=nullptr) |
ResultType | Take (uint64_t timeoutMs, bool *pValueAssigned=nullptr) |
operator const ResultType & () const | |
template<typename Callable > | |
auto | Then (Callable callable, CYIThreadPools::RunAsyncMode asyncMode=CYIThreadPools::RunAsyncMode::OnUIThread) -> CYIFuture< decltype(ReturnTypeOf< Callable >())> |
![]() | |
virtual | ~CYIAbstractFuture () |
bool | IsCancelled () const |
bool | IsCompleted () const |
bool | Cancel () |
bool | CancelOrWait () |
bool | Wait () const |
bool | Wait (uint64_t timeoutMs) const |
Public Attributes | |
CYISignal< CYIFuture< ResultType > > * | pCompleted |
A signal triggered when a value is assigned to this object. The future value is wrapped in a CYIFuture object to support move-only types. More... | |
![]() | |
CYISignal * | pCancelled |
A signal triggered when this object is cancelled. More... | |
Protected Member Functions | |
CYIFuture (CYIFutureSharedState< ResultType > &sharedState) | |
CYIFutureSharedState< ResultType > * | GetCastSharedState () |
A convenience function for getting the cast shared state pointer. More... | |
const CYIFutureSharedState< ResultType > * | GetCastSharedState () const |
A convenience function for getting the cast shared state pointer. More... | |
![]() | |
CYIAbstractFuture (std::shared_ptr< CYIFutureSharedStateBase > pSharedState) | |
Friends | |
class | CYIFutureSharedState< ResultType > |
Additional Inherited Members | |
![]() | |
std::shared_ptr< CYIFutureSharedStateBase > | m_pSharedState |
Creates an empty future object.
Creates an empty future object, with pDefaultFactory to be used to create default values. The factory is used only when a CYIFuture object is cancelled.
Sample usage:
CYIFuture< ResultType >::CYIFuture | ( | const CYIFuture< ResultType > & | other | ) |
|
noexcept |
|
protected |
const ResultType& CYIFuture< ResultType >::Get | ( | bool * | pValueAssigned = nullptr | ) | const |
Waits until a value has been assigned to this object, or until this object has been cancelled. If a value has been assigned, a reference to the value is returned. If the future is cancelled, a reference to a value constructed by the default constructor of ResultType is returned.
If pValueAssigned is non-null, true is assigned to the pointed-to bool if a value has been assigned to this future, and false otherwise.
ResultType CYIFuture< ResultType >::Get | ( | uint64_t | timeoutMs, |
bool * | pValueAssigned = nullptr |
||
) | const |
Waits until a value has been assigned to this object, until this object has been cancelled, or until the specified timeout is reached. If a value has been assigned, a reference to it is returned. If the future is cancelled or if the timeout value is reached, a reference to a value constructed by the default constructor of ResultType is returned.
If pValueAssigned is non-null, true is assigned to the pointed-to bool if a value has been assigned to this future, and false otherwise.
|
inlineprotected |
A convenience function for getting the cast shared state pointer.
|
inlineprotected |
A convenience function for getting the cast shared state pointer.
CYIFuture< ResultType >::operator const ResultType & | ( | ) | const |
CYIFuture& CYIFuture< ResultType >::operator= | ( | const CYIFuture< ResultType > & | other | ) |
|
noexcept |
void CYIFuture< ResultType >::Reset | ( | ) |
Resets this object to a blank slate, as if newly-initialized.
bool CYIFuture< ResultType >::Set | ( | ResultType | rValue | ) |
Assigns a value to this object.
A value can only be assigned once, and cannot be done if the future has been cancelled. A successful assignment will result in the Completed signal being triggered as well as threads blocked on calls to Wait and Get to wake up.
ResultType CYIFuture< ResultType >::Take | ( | bool * | pValueAssigned = nullptr | ) |
Waits until a value has been assigned to this object, or until this object has been cancelled. If a value has been assigned, the value is moved out of this future and returned. If the future is cancelled, a default-constructed instance of ResultType is moved and returned.
If pValueAssigned is non-null, true is assigned to the pointed-to bool if a value has been assigned to this future, and false otherwise.
ResultType CYIFuture< ResultType >::Take | ( | uint64_t | timeoutMs, |
bool * | pValueAssigned = nullptr |
||
) |
Waits until a value has been assigned to this object, until this object has been cancelled, or until the specified timeout is reached. If a value has been assigned, the value is moved out of this future and returned. If the future is cancelled or if the timeout value is reached, a default-constructed instance of ResultType is moved and returned.
If pValueAssigned is non-null, true is assigned to the pointed-to bool if a value has been assigned to this future, and false otherwise.
auto CYIFuture< ResultType >::Then | ( | Callable | callable, |
CYIThreadPools::RunAsyncMode | asyncMode = CYIThreadPools::RunAsyncMode::OnUIThread |
||
) | -> CYIFuture< decltype(ReturnTypeOf< Callable >())> |
Adds a continuation to this future. The continuation is executed once a value has been assigned to the future.
A copy of this CYIFuture can optionally be passed to the continuation so that the value assigned to this CYIFuture can be used in the continuation.
The callable can optionally take a CYITaskBase pointer as input. This allows the Callable to detect and respond to cancellation requests. If the callable takes both a future and a task as input, the task parameter must be first.
By default, continuations run on the UI thread. This can be changed by passing a value to asyncMode.
Multiple continuations can be added to the same future object. They will be executed in the order in which they were added.
Example:
|
friend |
CYISignal<CYIFuture<ResultType> >* CYIFuture< ResultType >::pCompleted |
A signal triggered when a value is assigned to this object. The future value is wrapped in a CYIFuture object to support move-only types.