You.i Engine
CYIFuture< ResultType > Class Template Reference

Detailed Description

template<typename ResultType>
class CYIFuture< ResultType >

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:

\
CYIFuture<CYIString> future = AnAsyncFunction();
CYIString value = future.Get(); // blocks until the value is available
future.pCompleted->Connect([](CYIString value) {
// Do something with the value
});
future.Then([](CYIString value){
// Do something with the value
Template Parameters
ResultTypethe type of object that can be assigned to this CYIFuture object.
See also
CYITask<ResultType>
CYIAbstractFuture

#include <thread/YiFuture.h>

Inheritance diagram for CYIFuture< ResultType >:

Public Member Functions

 CYIFuture ()
 
 CYIFuture (ResultType(*pDefaultFactory)())
 
 CYIFuture (const CYIFuture &other)
 
 CYIFuture (CYIFuture &&other) noexcept
 
CYIFutureoperator= (const CYIFuture &other)
 
CYIFutureoperator= (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 >())>
 
- Public Member Functions inherited from CYIAbstractFuture
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...
 
- Public Attributes inherited from CYIAbstractFuture
CYISignalpCancelled
 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...
 
- Protected Member Functions inherited from CYIAbstractFuture
 CYIAbstractFuture (std::shared_ptr< CYIFutureSharedStateBase > pSharedState)
 

Friends

class CYIFutureSharedState< ResultType >
 

Additional Inherited Members

- Protected Attributes inherited from CYIAbstractFuture
std::shared_ptr< CYIFutureSharedStateBase > m_pSharedState
 

Constructor & Destructor Documentation

◆ CYIFuture() [1/5]

template<typename ResultType>
CYIFuture< ResultType >::CYIFuture ( )

Creates an empty future object.

◆ CYIFuture() [2/5]

template<typename ResultType>
CYIFuture< ResultType >::CYIFuture ( ResultType(*)()  pDefaultFactory)

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:

// std::runtime_error does not have a default constructor.
return std::runtime_error("Task cancelled.");
});

◆ CYIFuture() [3/5]

template<typename ResultType>
CYIFuture< ResultType >::CYIFuture ( const CYIFuture< ResultType > &  other)

◆ CYIFuture() [4/5]

template<typename ResultType>
CYIFuture< ResultType >::CYIFuture ( CYIFuture< ResultType > &&  other)
noexcept

◆ CYIFuture() [5/5]

template<typename ResultType>
CYIFuture< ResultType >::CYIFuture ( CYIFutureSharedState< ResultType > &  sharedState)
protected

Member Function Documentation

◆ Get() [1/2]

template<typename ResultType>
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.

Note
Returns immediately if this object has been assigned a value or has been cancelled.
Warning
If no value gets assigned to this object, this function will wait forever.
Returns
Returns a reference to the value if a value was assigned to this object, and returns a reference to a value constructed by the default constructor of ResultType if the future has been cancelled.

◆ Get() [2/2]

template<typename ResultType>
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.

Note
Returns immediately if this object has been assigned a value or has been cancelled.
In some circumstances, this function may return before the timeout is reached, even if this object hasn't been cancelled and hasn't had a value assigned to it (e.g. in case of a 'spurious wakeup').
In order to avoid race conditions, this function returns a copy of ResultType rather than a reference. If ResultType is expensive to copy, using CYIAbstractFuture::Wait(uint64_t) const along with CYIFuture::Get(bool*) const may be preferable.
This function is not available for ResultType types that are not copy-constructible (such as std::unique_ptr).
Returns
Returns a reference to the value if a value was assigned to this object, and returns a reference to avalue constructed by the default constructor of ResultType if the future has been cancelled or if the timeout value was reached.

◆ GetCastSharedState() [1/2]

template<typename ResultType>
CYIFutureSharedState<ResultType>* CYIFuture< ResultType >::GetCastSharedState ( )
inlineprotected

A convenience function for getting the cast shared state pointer.

◆ GetCastSharedState() [2/2]

template<typename ResultType>
const CYIFutureSharedState<ResultType>* CYIFuture< ResultType >::GetCastSharedState ( ) const
inlineprotected

A convenience function for getting the cast shared state pointer.

◆ operator const ResultType &()

template<typename ResultType>
CYIFuture< ResultType >::operator const ResultType & ( ) const

Implicitely converts this CYIFuture object to its underlying type. The conversion blocks until a value has been assigned to this CYIFuture (or until the CYIFuture has been cancelled.)

See also
Get

◆ operator=() [1/2]

template<typename ResultType>
CYIFuture& CYIFuture< ResultType >::operator= ( const CYIFuture< ResultType > &  other)

◆ operator=() [2/2]

template<typename ResultType>
CYIFuture& CYIFuture< ResultType >::operator= ( CYIFuture< ResultType > &&  other)
noexcept

◆ Reset()

template<typename ResultType>
void CYIFuture< ResultType >::Reset ( )

Resets this object to a blank slate, as if newly-initialized.

Note
Calling this function does not cancel an associated task. However, the task's completion will no longer result in a value being assigned to this object. Calling this function has no effect on copies of this future.

◆ Set()

template<typename ResultType>
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.

Returns
Returns true if the assignement succeeded.

◆ Take() [1/2]

template<typename ResultType>
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.

Note
Returns immediately if this object has been assigned a value or has been cancelled.
Warning
If no value gets assigned to this object, this function will wait forever.
The Take() functions can only called once. Calling a Take() function multiple times on the same Future object is undefined behaviour. Calling the Take() function invalidates the value returned by previous calls to Get(). Calling the Take() function also invalidates the values from copies of this future.
Returns
Moves and returns the value if a value was assigned to this object, and moves and returns a value constructed by the default constructor of ResultType if the future has been cancelled.

◆ Take() [2/2]

template<typename ResultType>
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.

Note
Returns immediately if this object has been assigned a value or has been cancelled.
In some circumstances, this function may return before the timeout is reached, even if this object hasn't been cancelled and hasn't had a value assigned to it (e.g. in case of a 'spurious wakeup').
Warning
The Take() functions can only called once. Calling a Take() function multiple times on the same Future object is undefined behaviour. Calling the Take() function invalidates the value returned by previous calls to Get(). Calling the Take() function also invalidates the values from copies of this future.
Returns
Moves and returns the value if a value was assigned to this object, and moves and returns a value constructed by the default constructor of ResultType if the future has been cancelled or if the timeout value was reached.

◆ Then()

template<typename ResultType>
template<typename Callable >
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.

Note
If a value has already been assigned when this function is called, the continuation is immediately executed.
The continuation is not executed if the future is cancelled. Continuations are executed even if the CYIFuture that they're created on is deleted.
Returns
A CYIFuture that holds the result of the continuation's execution.

Example:

future.Then([](CYIFuture<std::vector<CYIString>> input)
{
// Continuation code
future.Then([](CYITaskBase *pTask, std::vector<CYIString> input)
{
// Continuation code
future.Then([]()
{
// Continuation code
future.Then([](CYITaskBase *pTask)
{
// Continuation code
});

Friends And Related Function Documentation

◆ CYIFutureSharedState< ResultType >

template<typename ResultType>
friend class CYIFutureSharedState< ResultType >
friend

Member Data Documentation

◆ pCompleted

template<typename ResultType>
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.


The documentation for this class was generated from the following file: