SMTK
@SMTK_VERSION@
Simulation Modeling Tool Kit
|
An Observer is a functor that is called when certain actions are performed. More...
#include <Observers.h>
Classes | |
class | Key |
Public Types | |
typedef int | Priority |
A value to indicate the relative order in which an observer should be called. More... | |
typedef std::function< void(Observer &)> | Initializer |
A functor to optionally initialize Observers as they are inserted into the Observers instance. | |
Public Member Functions | |
Observers (Initializer &&initializer) | |
template<class... Types> | |
auto | operator() (Types &&... args) -> decltype(std::declval< Observer >()(args...)) |
The call operator calls each of its Observer functors in sequence if there is no override functor defined. More... | |
template<class... Types> | |
auto | callObserversDirectly (Types &&... args) -> typename std::enable_if< std::is_integral< decltype(std::declval< Observer >()(args...))>::value, decltype(std::declval< Observer >()(args...))>::type |
For Observer functors that return an integral value, call all Observer functors and aggregate their output using a bitwise OR operator. | |
template<class... Types> | |
auto | callObserversDirectly (Types &&... args) -> typename std::enable_if< !std::is_integral< decltype(std::declval< Observer >()(args...))>::value, decltype(std::declval< Observer >()(args...))>::type |
For Observer functors that do not return an integral value, simply call all Observer functors. | |
Key | insert (Observer fn, Priority priority, bool initialize, std::string description="") |
Ask to receive notification (and possibly a chance to respond to) events. More... | |
Key | insert (Observer fn, std::string description="") |
std::size_t | erase (Key &handle) |
Indicate that an observer should no longer be called. More... | |
Observer | find (const Key &handle) const |
Return the observer for the given key if one exists or nullptr otherwise. | |
std::size_t | size () const |
Return the number of Observer functors in this instance. | |
void | overrideWith (Observer fn) |
Replace the default implementation (calling each Observer functor in sequence) with a new behavior. | |
void | removeOverride () |
Remove the overriding behavior, restoring the default behavior (calling each Observer functor when Observers is called). | |
const Initializer & | initializer () const |
void | setInitializer (Initializer fn) |
std::string | description (Key handle) const |
Static Public Member Functions | |
static constexpr Priority | defaultPriority () |
static constexpr Priority | lowestPriority () |
A convenience that returns the lowest priority representable for observers. | |
Static Public Attributes | |
static constexpr Priority | Default = DefaultPriority |
The default priority for observers inserted without an explicit priority. | |
Protected Attributes | |
std::map< InternalKey, Observer > | m_observers |
std::map< InternalKey, std::string > | m_descriptions |
Observer | m_override |
Initializer | m_initializer |
Friends | |
class | Key |
An Observer is a functor that is called when certain actions are performed.
This pattern allows for the injection of algorithms in response to a group of actions (e.g. Resource added/removed, Operation about to run/has run). Observers added to the Observers instance can also be initialized (allowing for a retroactive response to items currently under observation).
Observer functions can be assigned an integral priority when they are added. Observer functions with a higher priority value will be executed before those with a lower priority. Observer functions with the same priority value are called in the order in which they were inserted.
In addition to adding and removing Observer functors to an Observers instance, the execution logic of Observers can be overridden at runtime by inserting an override functor into the Observers instance. This allows for a run-time configurable type of polymorphism where consuming code can change the behavior of the Observers class, allowing consuming code to redefine the context in which Observer functors are executed. By default, the Observers call operator iterates over and calls each Observer functor.
Variants exist for Observer functors with no return value, where the Observer functors are simply called in sequence, and for Observer functions with a binary return value, where the observer results are aggregated via a bitwise OR operator.
When an Observer functor is added to an instance of Observers, a non-copyable Key is returned. The key can be used to remove the Observer functor, and the Observer functor is also scoped by the Key (when the Key goes out of scope, the Observer functor is removed from the Observers instance) by default. To decouple the Key's lifetime from that of the Observer functor, use the Key's release() method.
typedef int smtk::common::Observers< Observer, DebugObservers, DefaultPriority >::Priority |
A value to indicate the relative order in which an observer should be called.
Larger is higher priority.
|
inline |
Indicate that an observer should no longer be called.
Returns the number of remaining observers.
|
inline |
Ask to receive notification (and possibly a chance to respond to) events.
An integral priority value determines the relative order in which the observer is called with respect to other observer functions. Observer functions with a higher priority are called before those with a lower priority. If the Observers instance has an initializer and initialization is requested, the Observer functor is initialized (this is commonly a means to run the Observer functor retroactively on things already under observation). The return value is a handle that can be used to unregister the observer.
|
inline |
The call operator calls each of its Observer functors in sequence if there is no override functor defined.
Otherwise, it calls the override functor.