SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
Classes | Public Types | Public Member Functions | Protected Attributes | Friends | List of all members
smtk::common::Observers< Observer, DebugObservers > Class Template Reference

An Observer is a functor that is called when certain actions are performed. More...

#include <Observers.h>

Collaboration diagram for smtk::common::Observers< Observer, DebugObservers >:
[legend]

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 Initializerinitializer () const
 
void setInitializer (Initializer fn)
 
std::string description (Key handle) const
 

Protected Attributes

std::map< InternalKey, Observer > m_observers
 
std::map< InternalKey, std::string > m_descriptions
 
Observer m_override
 
Initializer m_initializer
 

Friends

class Key
 

Detailed Description

template<typename Observer, bool DebugObservers = false>
class smtk::common::Observers< Observer, DebugObservers >

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.

Member Typedef Documentation

◆ Priority

template<typename Observer , bool DebugObservers = false>
typedef int smtk::common::Observers< Observer, DebugObservers >::Priority

A value to indicate the relative order in which an observer should be called.

Larger is higher priority.

Member Function Documentation

◆ erase()

template<typename Observer , bool DebugObservers = false>
std::size_t smtk::common::Observers< Observer, DebugObservers >::erase ( Key handle)
inline

Indicate that an observer should no longer be called.

Returns the number of remaining observers.

◆ insert()

template<typename Observer , bool DebugObservers = false>
Key smtk::common::Observers< Observer, DebugObservers >::insert ( Observer  fn,
Priority  priority,
bool  initialize,
std::string  description = "" 
)
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.

◆ operator()()

template<typename Observer , bool DebugObservers = false>
template<class... Types>
auto smtk::common::Observers< Observer, DebugObservers >::operator() ( Types &&...  args) -> decltype(std::declval<Observer>()(args...))
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.


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