Scroom  0.14
Scroom::Utils::Observable< T > Class Template Reference

#include <observable.hh>

Inheritance diagram for Scroom::Utils::Observable< T >:
Inheritance graph
Collaboration diagram for Scroom::Utils::Observable< T >:
Collaboration graph

Public Types

using Observer = boost::shared_ptr< T >
 
using Ptr = boost::shared_ptr< Observable< T > >
 

Public Member Functions

 Observable ()
 
 ~Observable () override
 
 Observable (const Observable &)=delete
 
 Observable (Observable &&)=delete
 
Observable operator= (const Observable &)=delete
 
Observable operator= (Observable &&)=delete
 
Scroom::Bookkeeping::Token registerStrongObserver (Observer const &observer)
 
Scroom::Bookkeeping::Token registerObserver (ObserverWeak const &observer)
 

Protected Member Functions

std::list< ObservergetObservers ()
 
virtual void observerAdded (Observer const &observer, Scroom::Bookkeeping::Token const &token)
 

Private Types

using ObserverWeak = boost::weak_ptr< T >
 
using Registration = Detail::Registration< T >
 

Private Member Functions

void unregisterObserver (ObserverWeak const &observer)
 

Private Attributes

Scroom::Bookkeeping::Map< ObserverWeak, typename Registration::Ptr >::Ptr registrationMap
 

Friends

class Detail::Registration< T >
 

Detailed Description

template<typename T>
class Scroom::Utils::Observable< T >

Base class for something that accepts observers.

Upon registering, observers are given a Registration. If the same Observer registers twice (using the same method), he'll still receive events only once. When the Observer destroys his Registration, he'll be unregistered.

There are two ways of registering: One can register a shared_ptr, or a weak_ptr, depending on whether you want the Observable to keep the Observer from being destructed.

Note
When you register one Observer with both a shared_ptr and a weak_ptr, unpredictable things will happen.

Member Typedef Documentation

◆ Observer

template<typename T >
using Scroom::Utils::Observable< T >::Observer = boost::shared_ptr<T>

◆ ObserverWeak

template<typename T >
using Scroom::Utils::Observable< T >::ObserverWeak = boost::weak_ptr<T>
private

◆ Ptr

template<typename T >
using Scroom::Utils::Observable< T >::Ptr = boost::shared_ptr<Observable<T> >

◆ Registration

template<typename T >
using Scroom::Utils::Observable< T >::Registration = Detail::Registration<T>
private

Constructor & Destructor Documentation

◆ Observable() [1/3]

◆ ~Observable()

template<typename T >
Scroom::Utils::Observable< T >::~Observable
override
179  {
180  // Destroy strong references to any observers
181  //
182  // The one holding the token of the registration is in control
183  // of the lifetime of the registration objects. Hence, as long
184  // as the Token is valid, a reference to the Registration will
185  // exist, which may, in turn, contain a (strong) reference to an
186  // Observer. This is not desirable. As soon as the observable is
187  // deleted (which is now), it should no longer hold any
188  // references to any Observers. Hence, we should manually reset
189  // references to observers here.
190  for(const typename Registration::Ptr& registration: registrationMap->values())
191  {
192  registration->o.reset();
193  }
194  }

◆ Observable() [2/3]

template<typename T >
Scroom::Utils::Observable< T >::Observable ( const Observable< T > &  )
delete

◆ Observable() [3/3]

template<typename T >
Scroom::Utils::Observable< T >::Observable ( Observable< T > &&  )
delete

Member Function Documentation

◆ getObservers()

template<typename T >
std::list< typename Observable< T >::Observer > Scroom::Utils::Observable< T >::getObservers
protected

Retrieve a list of current observers.

Always, a list of shared_ptr objects is returned, regardless of whether the Observer registered a shared_ptr or a weak_ptr.

198  {
199  std::list<typename Observable<T>::Observer> result;
200  for(const typename Registration::Ptr& registration: registrationMap->values())
201  {
202  Observer const o = registration->observer.lock();
203  if(o)
204  {
205  result.push_back(o);
206  }
207  }
208 
209  return result;
210  }

Referenced by PresentationBase::close(), TestObservable::getObservers(), and PresentationBase::open().

Here is the caller graph for this function:

◆ observerAdded()

template<typename T >
void Scroom::Utils::Observable< T >::observerAdded ( Observer const &  observer,
Scroom::Bookkeeping::Token const &  token 
)
protectedvirtual

Override this function if you want to be notified of new observers registering.

Reimplemented in CompressedTile, CompressedTile, and TestRecursiveObservable.

260  {
261  // Do nothing
262  }

◆ operator=() [1/2]

template<typename T >
Observable Scroom::Utils::Observable< T >::operator= ( const Observable< T > &  )
delete

◆ operator=() [2/2]

template<typename T >
Observable Scroom::Utils::Observable< T >::operator= ( Observable< T > &&  )
delete

◆ registerObserver()

template<typename T >
Scroom::Bookkeeping::Token Scroom::Utils::Observable< T >::registerObserver ( ObserverWeak const &  observer)
234  {
236  typename Detail::Registration<T>::Ptr r = registrationMap->get(observer);
237  if(r)
238  {
239  r->set(observer);
240  }
241  else
242  {
243  r = Detail::Registration<T>::create(shared_from_this<Observable<T>>(), observer);
244  registrationMap->set(observer, r);
245  }
246 
247  observerAdded(typename Observable<T>::Observer(observer), t);
248 
249  return t;
250  }

Referenced by CompressedTile::registerObserver().

Here is the caller graph for this function:

◆ registerStrongObserver()

template<typename T >
Scroom::Bookkeeping::Token Scroom::Utils::Observable< T >::registerStrongObserver ( Observer const &  observer)
214  {
216  typename Detail::Registration<T>::Ptr r = registrationMap->get(observer);
217  if(r)
218  {
219  r->set(observer);
220  }
221  else
222  {
223  r = Detail::Registration<T>::create(shared_from_this<Observable<T>>(), observer);
224  registrationMap->set(observer, r);
225  }
226 
227  observerAdded(observer, t);
228 
229  return t;
230  }

Referenced by CompressedTile::registerStrongObserver().

Here is the caller graph for this function:

◆ unregisterObserver()

template<typename T >
void Scroom::Utils::Observable< T >::unregisterObserver ( ObserverWeak const &  observer)
private
254  {
255  registrationMap->remove(observer);
256  }

Friends And Related Function Documentation

◆ Detail::Registration< T >

template<typename T >
friend class Detail::Registration< T >
friend

Member Data Documentation

◆ registrationMap

template<typename T >
Scroom::Bookkeeping::Map<ObserverWeak, typename Registration::Ptr>::Ptr Scroom::Utils::Observable< T >::registrationMap
private

Map all registrations to their registration data


The documentation for this class was generated from the following file:
Scroom::Bookkeeping::MapBase::set
void set(const K &k, const V &v)
Definition: bookkeepingimpl.hh:313
Scroom::Bookkeeping::MapBase::remove
void remove(const K &k)
Definition: bookkeepingimpl.hh:283
Scroom::Utils::Detail::Registration::Ptr
boost::shared_ptr< Registration< T > > Ptr
Definition: observable.hh:41
Scroom::Bookkeeping::MapBase::reReserve
Token reReserve(const K &k)
Definition: bookkeepingimpl.hh:228
Scroom::Utils::Observable::Observer
boost::shared_ptr< T > Observer
Definition: observable.hh:74
Scroom::Utils::Observable::registrationMap
Scroom::Bookkeeping::Map< ObserverWeak, typename Registration::Ptr >::Ptr registrationMap
Definition: observable.hh:83
Scroom::Bookkeeping::MapBase::values
std::list< V > values() const
Definition: bookkeepingimpl.hh:362
Scroom::Bookkeeping::MapBase::get
V get(const K &k)
Definition: bookkeepingimpl.hh:332
Scroom::Utils::Observable::observerAdded
virtual void observerAdded(Observer const &observer, Scroom::Bookkeeping::Token const &token)
Definition: observable.hh:259
Scroom::Bookkeeping::Token
Definition: bookkeeping.hh:37
Scroom::Bookkeeping::Map::create
static Ptr create()
Definition: bookkeepingimpl.hh:424
Scroom::Utils::Detail::Registration::create
static Ptr create(boost::weak_ptr< Observable< T >> observable, boost::shared_ptr< T > observer)
Definition: observable.hh:156