An abstract observable type, maintaining a list of observers, who can be notified in case of Events.
More...
#include <observable.hpp>
|
| virtual | ~Observable ()=default |
| | Observable ()=default |
| | Observable (Observable const &) |
| | Copies do NOT inherit the watcher list: observers subscribed to the source object, not to the copy.
|
| Observable & | operator= (Observable const &) |
| | Copy-assignment: leaves the target's own watcher list untouched (see the copy ctor note).
|
| void | AddObserver (AnyObserver &new_observer) const |
| | Add an observer (non-owning) to observe this observable.
|
| void | AddObserver (std::shared_ptr< AnyObserver > const &new_observer) const |
| | Add an observer whose lifetime is co-owned by this observable.
|
| void | RemoveObserver (AnyObserver &observer) const |
| | Remove an observer from this observable.
|
| virtual bool | ObservableIsA (std::type_index t) const |
| | Whether this observable may be observed as the given type.
|
|
| void | NotifyObservers (AnyEvent const &e) const |
| | Sends an event to observers that subscribed to its exact dynamic type, then to all catch-all (untyped) observers.
|
| void | NotifyObservers (AnyEvent &e) const |
| | Notify all observers of a (mutable) event.
|
| bool | HasObservers () const |
| | Whether anyone is currently observing (conservative).
|
An abstract observable type, maintaining a list of observers, who can be notified in case of Events.
Some known observable types are Tracker and Endgame.
◆ ~Observable()
| virtual bertini::Observable::~Observable |
( |
| ) |
|
|
virtualdefault |
◆ Observable() [1/2]
| bertini::Observable::Observable |
( |
| ) |
|
|
default |
◆ Observable() [2/2]
| bertini::Observable::Observable |
( |
Observable const & | | ) |
|
|
inline |
Copies do NOT inherit the watcher list: observers subscribed to the source object, not to the copy.
This makes copies safe to use on other threads — a fresh copy notifies nobody until observers are explicitly added to it. Copy-assignment likewise leaves the target's own watchers untouched.
◆ AddObserver() [1/2]
| void bertini::Observable::AddObserver |
( |
AnyObserver & | new_observer | ) |
const |
|
inline |
Add an observer (non-owning) to observe this observable.
Stores only a raw reference: the caller is responsible for keeping the observer alive while it is attached. This is the right overload for stack-allocated C++ observers added and removed within a scope. For an observer whose lifetime you would rather have tracked, see the shared_ptr overload.
Observers that override SubscribedEventTypes() with a non-empty list are registered in a type-indexed map so NotifyObservers only calls them for events they declared interest in. Observers returning an empty list (the default) are placed in a catch-all list and receive every event.
Safe to call from inside an observer's Observe() (i.e. during a notification): the add is deferred and applied once the current notification loop finishes. This is what lets a "meta-observer" attach new observers in response to events.
- Exceptions
-
◆ AddObserver() [2/2]
| void bertini::Observable::AddObserver |
( |
std::shared_ptr< AnyObserver > const & | new_observer | ) |
const |
|
inline |
Add an observer whose lifetime is co-owned by this observable.
The observable keeps a shared_ptr, so the observer stays alive (and keeps receiving events) for as long as it is attached, even after the caller drops their own reference — "attach it and forget it", with no dangling. It is released when RemoveObserver is called or this observable is destroyed. (Stack-allocated C++ observers can't be shared_ptr-owned; use the reference overload for those.)
- Exceptions
-
◆ HasObservers()
| bool bertini::Observable::HasObservers |
( |
| ) |
const |
|
inlineprotected |
Whether anyone is currently observing (conservative).
Lets an emitter skip constructing an event – and any work needed to build its payload, such as a numeric-type conversion – when there is no observer to receive it. Conservative: returns true if any watcher list is non-empty (even if a stale, emptied typed bucket lingers), so it never wrongly suppresses a real observer.
◆ NotifyObservers() [1/2]
| void bertini::Observable::NotifyObservers |
( |
AnyEvent & | e | ) |
const |
|
inlineprotected |
Notify all observers of a (mutable) event.
◆ NotifyObservers() [2/2]
| void bertini::Observable::NotifyObservers |
( |
AnyEvent const & | e | ) |
const |
|
inlineprotected |
Sends an event to observers that subscribed to its exact dynamic type, then to all catch-all (untyped) observers.
Mutations of the observer lists are deferred for the duration of a notification (see AddObserver/RemoveObserver), so iterating the live lists here is safe even when an observer subscribes/unsubscribes mid-dispatch. An observer that returns ObserveResult::Unsubscribe is dropped once the (possibly nested) notification completes. The depth counter keeps this correct under re-entrant emission.
◆ ObservableIsA()
| virtual bool bertini::Observable::ObservableIsA |
( |
std::type_index | t | ) |
const |
|
inlinevirtual |
◆ operator=()
Copy-assignment: leaves the target's own watcher list untouched (see the copy ctor note).
◆ RemoveObserver()
| void bertini::Observable::RemoveObserver |
( |
AnyObserver & | observer | ) |
const |
|
inline |
Remove an observer from this observable.
Like AddObserver, this is safe to call during a notification: the removal is deferred until the current notification loop finishes.