carb::delegate::Delegate< void(Args…)>

Defined in carb/delegate/Delegate.h

template<class ...Args>
class carb::delegate::Delegate<void(Args...)>

Implements a thread-safe callback system that can have multiple subscribers.

A delegate is a weak-coupling callback system. Essentially, a system uses Delegate to have a callback that can be received by multiple subscribers.

Delegate has two ways to uniquely identify a bound callback: Bind() will output a Handle, or the caller can provide a key of any type with BindWithKey(). Either the Handle or the given key can be passed to Unbind() in order to remove a callback.

Delegate can call all bound callbacks with the Call() function. Recursive calling is allowed with caveats listed below.

Delegate is thread-safe for all operations. Call() can occur simultaneously in multiple threads. An Unbind() will wait if the bound callback is currently executing in another thread.

Delegate can be destroyed from a binding (during Call()) as the internal state is not disposed of until all active calls have been completed.

See

~Delegate().

Public Types

using Handle = ::carb::Strong<size_t, struct HandleSig>

A quasi-unique identifier outputted from Bind()

Handle is unique as long as it has not rolled over.

Public Functions

Delegate() = default

Constructs an empty delegate.

~Delegate()

Destructor.

The destructor unbinds all bindings and follows the waiting paradigm explained by UnbindAll(). As the internal state of the delegate is held until all active calls have completed, it is valid to destroy Delegate from a callback.

template<class Callable, class ...BindArgs>
Handle Bind(Handle *hOut, Callable &&func, BindArgs&&... args)

Binds a callable (with optional additional arguments) to the delegate.

Thread Safety

: Thread-safe with respect to other Delegate operations except for construction and destruction.

Note

This function can be done from within a callback. If done during a callback, the newly bound callable will not be available to be called until Call() returns, at which point the callback can be called by other threads or outer Call() calls (in the case of recursive calls to Call()).

Parameters
  • hOut – An optional pointer that receives a Handle representing the binding to Callable. This can be nullptr to ignore the Handle. The same Handle is also returned. In a multi-threaded environment, it is possible for func to be called before Bind() returns, but hOut will have already been assigned.

  • func – A callable object, such as lambda, functor or [member-]function. Return values are ignored. The callable must take as parameters args followed by the Args declared in the delegate template signature.

  • args – Additional optional arguments to bind with func. If func is a member function pointer the first argument must be the this pointer to call the member function with.

Returns

The Handle also passed to hOut.

template<class KeyType, class Callable, class ...BindArgs>
void BindWithKey(KeyType &&key, Callable &&func, BindArgs&&... args)

Binds a callable (with optional additional arguments) to the delegate with a user-defined key.

Thread Safety

: Thread-safe with respect to other Delegate operations except for construction and destruction.

Note

This function can be done from within a callback. If done during a callback, the newly bound callable will not be available to be called until Call() returns, at which point the callback can be called by other threads or outer Call() calls (in the case of recursive calls to Call()).

Parameters
  • key – A user-defined key of any type that supports equality (==) to identify this binding. Although multiple bindings can be referenced by the same key, Unbind() will only remove a single binding.

  • func – A callable object, such as lambda, functor or [member-]function. Return values are ignored. The callable must take as parameters args followed by the Args declared in the delegate template signature.

  • args – Additional optional arguments to bind with func. If func is a member function pointer the first argument must be the this pointer to call the member function with.

template<class KeyType>
bool Unbind(KeyType &&key)

Unbinds any single binding referenced by the given key.

This function can be done from within a callback. If the referenced binding is currently executing in another thread, Unbind() will not return until it has finished. Any binding can be safely unbound during a callback. If a binding un-binds itself, the captured arguments and callable object will not be destroyed until just before Call() returns.

Thread Safety

: Thread-safe with respect to other Delegate operations except for construction and destruction.

Note

It is guaranteed that when Unbind() returns, the callback is not running and will never run in any threads.

Parameters

key – A Handle or user-defined key previously passed to BindWithKey().

Returns

true if a binding was un-bound; false if no binding matching key was found.

bool UnbindCurrent()

Unbinds the currently executing callback without needing an identifying key.

Thread Safety

: Thread-safe with respect to other Delegate operations except for construction and destruction.

Note

If not done within the context of a callback, this function has no effect.

Returns

true if a binding was un-bound; false if there is no current binding.

void UnbindAll()

Unbinds all bound callbacks, possibly waiting for active calls to complete.

Unbinds all currently bound callbacks. This function will wait to return until bindings that it unbinds have completed all calls in other threads. It is safe to perform this operation from within a callback.

Thread Safety

: Thread-safe with respect to other Delegate operations except for construction and destruction.

size_t Count() const

Returns the number of active bound callbacks.

Thread Safety

: Thread-safe with respect to other Delegate operations except for construction and destruction.

Note

This function returns the count of active bound callbacks only. Pending callbacks (that were added with Bind() during Call()) are not counted.

Returns

the number of active bound callbacks.

template<class KeyType>
std::vector<std::decay_t<KeyType>> GetKeysByType() const

Given a type, returns a std::vector containing a copy of all keys used for bindings.

Thread Safety

: Thread-safe with respect to other Delegate operations except for construction and destruction.

Note

This function can be done from within a callback. Pending callbacks (that were added with Bind() during Call()) are included, even if they are pending in other threads. Note that in a multi-threaded environment, the actual keys in use by Delegate may change after this function returns; in such cases, an external mutex is recommended. KeyType must be Copyable in order for this function to compile.

Template Parameters

KeyTypeHandle or a type previously passed to BindWithKey()

Returns

a std::vector of copies of keys of the given type in use by this Delegate.

void Call(Args... args)

Calls all bound callbacks for this Delegate.

Thread Safety

: Thread-safe with respect to other Delegate operations except for construction and destruction.

Note

This function can be done concurrently in multiple threads simultaneously. Recursive calls to Call() are allowed but the caller must take care to avoid endless recursion. Callbacks are free to call Bind(), Unbind() or any other Delegate function. No internal locks are held while callbacks are called.

Parameters

args – The arguments to pass to the callbacks.

void operator()(Args... args)

Syntactic sugar for Call()

Public Static Attributes

static const Handle kInvalidHandle = {0}

A value representing an invalid Handle value.