carb::delegate::Delegate< void(Args…)>¶
Defined in carb/delegate/Delegate.h
-
template<class ...
Args
>
classcarb::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().
Delegate does not hold any internal locks while calling bound callbacks. It is strongly recommended to avoid holding locks when invoking Delegate’s Call() function.
These tenets make up the basis of Carbonite’s Basic Callback Hygiene as described in the Coding Style Guidelines .
Public Types
Public Functions
-
Delegate
() = default¶ Constructs an empty delegate.
-
Delegate
(Delegate &&other)¶ Move constructor.
- Parameters
other – The Delegate to move from. This Delegate will be left in a valid but empty state.
-
Delegate &
operator=
(Delegate &&other)¶ Move-assign operator.
- Parameters
other – The Delegate to move-assign from. Will be swapped with
*this
.- Returns
*this
-
~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
>
HandleBind
(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 benullptr
to ignore the Handle. The same Handle is also returned. In a multi-threaded environment, it is possible forfunc
to be called before Bind() returns, buthOut
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 theArgs
declared in the delegate template signature.args – Additional optional arguments to bind with
func
. Iffunc
is a member function pointer the first argument must be thethis
pointer to call the member function with.
- Returns
The Handle also passed to
hOut
.
-
template<class
KeyType
, classCallable
, class ...BindArgs
>
voidBindWithKey
(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 theArgs
declared in the delegate template signature.args – Additional optional arguments to bind with
func
. Iffunc
is a member function pointer the first argument must be thethis
pointer to call the member function with.
-
template<class
KeyType
>
boolUnbind
(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.
-
template<class
KeyType
>
boolHasKey
(KeyType &&key) const noexcept¶ Indicates if a binding exists in
*this
with the given key or Handle.- Thread Safety
: Thread-safe with respect to other Delegate operations except for construction and destruction. However, without external synchronization, it is possible for the result of this function to be incorrect by the time it is used.
- Parameters
key – A Handle or user-defined key previously passed to BindWithKey().
- Returns
true
if a binding exists with the givenkey
;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 noexcept¶ 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. Use HasPending() to determine if pending bindings exist.
- Returns
the number of active bound callbacks.
-
bool
HasPending
() const noexcept¶ Checks whether the Delegate has any pending bindings.
- Thread Safety
: Thread-safe with respect to other Delegate operations except for construction and destruction. The nature of this function is such that the result may be stale by the time it is read in the calling thread, unless the calling thread has at least one pending binding.
Note
This function returns
true
if any pending bound callbacks exist. This will only ever be non-zero if one or more threads are currently in the Call() function.- Returns
true
if any pending bindings exist;false
otherwise.
-
bool
IsEmpty
() const noexcept¶ Checks whether the Delegate contains no pending or active bound callbacks.
- Thread Safety
: Thread-safe with respect to other Delegate operations except for construction and destruction. However, without external synchronization, it is possible for the result of this function to be incorrect by the time it is used.
- Returns
true
if there are no active or pending callbacks present in*this
;false
otherwise.
-
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
KeyType – Handle 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.
-