diff --git a/VistaCoreLibs/VistaAspects/VistaObserver.cpp b/VistaCoreLibs/VistaAspects/VistaObserver.cpp index 112ca3e97eec81b4bf3a401e4389324254b743fe..a8aa7c5ef5a535adf33e6f3d4a985145256a5990 100644 --- a/VistaCoreLibs/VistaAspects/VistaObserver.cpp +++ b/VistaCoreLibs/VistaAspects/VistaObserver.cpp @@ -34,28 +34,20 @@ /* CONSTRUCTORS / DESTRUCTOR */ /*============================================================================*/ - -IVistaObserver::IVistaObserver(IVistaObserver &) -{} - IVistaObserver::IVistaObserver() -: m_bObserverEnabled(true) -{} +: m_bObserverEnabled( true ) +{ } IVistaObserver::~IVistaObserver() { // copy vector of observables, because the original (member) version // is altered during the ReleaseObserveable call - std::vector<IVistaObserveable *> vecObs = m_vecObserveables; + const auto vecObs = m_vecObserveables; - std::vector<IVistaObserveable *>::iterator it; - for (it = vecObs.begin(); it != vecObs.end(); ++it) + for( IVistaObserveable* pObs : vecObs ) { - ReleaseObserveable(*it, IVistaObserveable::TICKET_NONE); + ReleaseObserveable( pObs, IVistaObserveable::TICKET_NONE ); } - - m_vecObserveables.clear(); - } /*============================================================================*/ @@ -67,81 +59,91 @@ bool IVistaObserver::GetIsObserverEnabled() const return m_bObserverEnabled; } -void IVistaObserver::SetIsObserverEnabled(bool bEnabled) +void IVistaObserver::SetIsObserverEnabled( bool bEnabled ) { m_bObserverEnabled = bEnabled; } -void IVistaObserver::UpdateRequest(IVistaObserveable *pObserveable, int msg, int nTicket) +void IVistaObserver::UpdateRequest( IVistaObserveable* pObserveable, + int msg, + int nTicket ) { - if(m_bObserverEnabled) - ObserverUpdate(pObserveable, msg, nTicket); + if( m_bObserverEnabled ) + { + ObserverUpdate( pObserveable, msg, nTicket ); + } } -bool IVistaObserver::ObserveableDeleteRequest( - IVistaObserveable* pObserveable, - int nTicket /*= IVistaObserveable::TICKET_NONE */ - ) +bool IVistaObserver::ObserveableDeleteRequest( IVistaObserveable* pObserveable, + int nTicket ) { return true; } -void IVistaObserver::ObserveableDelete( - IVistaObserveable* pObserveable, - int nTicket /*= IVistaObserveable::TICKET_NONE */ - ) +void IVistaObserver::ObserveableDelete( IVistaObserveable* pObserveable, int nTicket ) { - // just delete pObserveable from list - - std::vector<IVistaObserveable*>::iterator it = - std::find(m_vecObserveables.begin(), m_vecObserveables.end(), pObserveable); + const auto it = std::find( m_vecObserveables.begin(), + m_vecObserveables.end(), + pObserveable ); - if (it != m_vecObserveables.end()) + if( it != m_vecObserveables.end() ) { - m_vecObserveables.erase(it); + m_vecObserveables.erase( it ); } } -void IVistaObserver::ReleaseObserveable( - IVistaObserveable* pObserveable, - int nTicket /*= IVistaObserveable::TICKET_NONE */ - ) +void IVistaObserver::ReleaseObserveable( IVistaObserveable* pObserveable, int nTicket ) { - if (Observes(pObserveable)) + if( Observes( pObserveable ) ) { - pObserveable->DetachObserver(this); + pObserveable->DetachObserver( this ); - std::vector<IVistaObserveable*>::iterator it = - std::find(m_vecObserveables.begin(), m_vecObserveables.end(), pObserveable); + const auto it = std::find( m_vecObserveables.begin(), + m_vecObserveables.end(), + pObserveable ); - if (it != m_vecObserveables.end()) + if( it != m_vecObserveables.end() ) { - m_vecObserveables.erase(it); + m_vecObserveables.erase( it ); } } } -bool IVistaObserver::Observes(IVistaObserveable* pObserveable) +bool IVistaObserver::Observes( IVistaObserveable* pObserveable ) { - std::vector<IVistaObserveable *>::iterator it = - std::find(m_vecObserveables.begin(), m_vecObserveables.end(), pObserveable); + const auto it = std::find( m_vecObserveables.begin(), + m_vecObserveables.end(), + pObserveable ); - return (it != m_vecObserveables.end()); + return ( it != m_vecObserveables.end() ); } -void IVistaObserver::Observe( - IVistaObserveable* pObserveable, - int nTicket /*= IVistaObserveable::TICKET_NONE */ - ) +void IVistaObserver::Observe( IVistaObserveable* pObserveable, int nTicket ) { - if (!Observes(pObserveable)) + if( !Observes( pObserveable ) && pObserveable->AttachObserver( this, nTicket ) ) { - if (pObserveable->AttachObserver(this, nTicket)) - m_vecObserveables.push_back(pObserveable); + m_vecObserveables.push_back( pObserveable ); } } + /*============================================================================*/ -/* LOCAL VARS AND FUNCS */ +/* DEFAULT OBSERVER IMPLEMENTATION */ /*============================================================================*/ +VistaSimpleObserver::VistaSimpleObserver( + std::function< void( IVistaObserveable*, int, int ) > fnObserverUpdate ) +: m_fnObserverUpdate( std::move( fnObserverUpdate ) ) +{ } + +void VistaSimpleObserver::ObserverUpdate( IVistaObserveable* pObserveable, + int nMsg, + int nTicket ) +{ + m_fnObserverUpdate( pObserveable, nMsg, nTicket ); +} + + +/*============================================================================*/ +/* LOCAL VARS AND FUNCS */ +/*============================================================================*/ diff --git a/VistaCoreLibs/VistaAspects/VistaObserver.h b/VistaCoreLibs/VistaAspects/VistaObserver.h index cb1e14058312fb0c4d1b8eace2e957e3eab8bf5f..d81b088176099a1ed7200096b26f14c8d14b689a 100644 --- a/VistaCoreLibs/VistaAspects/VistaObserver.h +++ b/VistaCoreLibs/VistaAspects/VistaObserver.h @@ -34,6 +34,8 @@ #include "VistaNameable.h" #include "VistaObserveable.h" +#include <functional> + /*============================================================================*/ /* MACROS AND DEFINES */ @@ -59,9 +61,11 @@ class VISTAASPECTSAPI IVistaObserver { public: - virtual ~IVistaObserver(); - + IVistaObserver( const IVistaObserver& ) = delete; + IVistaObserver& operator=( const IVistaObserver& ) = delete; + virtual ~IVistaObserver(); + /** * An observeable is about to be deleted, this can be forbidden by returning * false here. @@ -76,8 +80,7 @@ public: * @return true iff pObserveable can be deleted */ virtual bool ObserveableDeleteRequest( IVistaObserveable* pObserveable, - int nTicket = IVistaObserveable::TICKET_NONE ); - + int nTicket = IVistaObserveable::TICKET_NONE ); /** * This is sent to the observer before the observeable is deleted. Note that this @@ -93,7 +96,7 @@ public: * @param pObserveable the observeable to be deleted */ virtual void ObserveableDelete( IVistaObserveable* pObserveable, - int nTicket = IVistaObserveable::TICKET_NONE ); + int nTicket = IVistaObserveable::TICKET_NONE ); /** * This message is sent when pObserveable shall be released and not be observed anymore. @@ -103,7 +106,7 @@ public: * @param pObserveable the observeable to be released. */ virtual void ReleaseObserveable( IVistaObserveable* pObserveable, - int nTicket = IVistaObserveable::TICKET_NONE ); + int nTicket = IVistaObserveable::TICKET_NONE ); /** @@ -115,8 +118,8 @@ public: * is observed. * @param pObserveable the observeable that changed its state. */ - virtual void ObserverUpdate(IVistaObserveable* pObserveable, - int nMsg, int nTicket) = 0; + virtual void ObserverUpdate( IVistaObserveable* pObserveable, + int nMsg, int nTicket ) = 0; /** * This method can be used to query whether pObserveable is observed by this observer or not. @@ -132,33 +135,46 @@ public: * IsObserved(pObserveable) must return true after a call to this * @param pObserveable the observeable to be observed */ - virtual void Observe( IVistaObserveable* pObserveable, - int nTicket = IVistaObserveable::TICKET_NONE ); + virtual void Observe( IVistaObserveable* pObserveable, + int nTicket = IVistaObserveable::TICKET_NONE ); void UpdateRequest( IVistaObserveable* pObserveable, int nMsg, int nTicket ); bool GetIsObserverEnabled() const; - virtual void SetIsObserverEnabled(bool bEnabled); + virtual void SetIsObserverEnabled( bool bEnabled ); + protected: IVistaObserver(); - // list of objects observed by this observer - // Note: this is implemented as a vector (even though we have to perform - // operations like deleting arbitrary elements), as this is nevertheless - // way faster than on an std::list. - std::vector<IVistaObserveable *> m_vecObserveables; + std::vector< IVistaObserveable* > m_vecObserveables; private: - /** - * Copy-constructor. We prevent copying. - */ - IVistaObserver(IVistaObserver &); - bool m_bObserverEnabled; +}; +/** + * This class facilitates the creation of a very simple observer, i.e., one in + * which only the ObserverUpdate function needs to be overridden. For this, + * instead of deriving a custom observer type, one can simply forgo this step + * and supply a std::function which is called by the update function. Note, that + * managing state usually becomes much harder using this implementation. + */ +class VISTAASPECTSAPI VistaSimpleObserver : public IVistaObserver +{ +public: + VistaSimpleObserver( + std::function< void( IVistaObserveable*, int, int ) > fnObserverUpdate ); + ~VistaSimpleObserver() override = default; + + void ObserverUpdate( + IVistaObserveable* pObserveable, int nMsg, int nTicket ) override; + +private: + std::function< void( IVistaObserveable*, int, int ) > m_fnObserverUpdate; }; + /*============================================================================*/ /* LOCAL VARS AND FUNCS */ /*============================================================================*/