From: Michal H. <ms...@gm...> - 2008-04-15 13:52:26
|
New field active was added to the IObserver class. This is used by Observer handler to check if observer wants to be triggered by it. setActive can be then used to actively control when the observer is triggered and when not which might be useful in some situations (e.g. when we can't - for some reason - unregister in time but we need to be sure that observer is not notified). * IObserver - active, setActive, isActive added * ObserverHandler - checks isActive before it calls notify * testsutils.cc - test cases for active Index: src/tests/kernel/testutils.cc =================================================================== --- src/tests/kernel/testutils.cc.orig 2008-04-04 19:49:44.000000000 +0200 +++ src/tests/kernel/testutils.cc 2008-04-05 16:15:52.000000000 +0200 @@ -318,7 +318,19 @@ public: { // ok } + OUTPUT << "TC5:\tdeactivating observer5 will skipp it" << endl; + observer5->setActive(false); + Observer<int>::counter=0; + observerHandler.notifyObservers(newValue, context); + CPPUNIT_ASSERT(Observer<int>::counter==34678); + OUTPUT << "TC6:\tactivating observer5 will trigger it" << endl; + observer5->setActive(true); + Observer<int>::counter=0; + observerHandler.notifyObservers(newValue, context); + CPPUNIT_ASSERT(Observer<int>::counter==345678); + OUTPUT << "TC7:\tobserver is always created as activated" << endl; + CPPUNIT_ASSERT(shared_ptr<Observer<int> >(new Observer<int>(8))->isActive()); return true; } Index: src/utils/observer.h =================================================================== --- src/utils/observer.h.orig 2008-04-05 14:35:09.000000000 +0200 +++ src/utils/observer.h 2008-04-05 16:15:52.000000000 +0200 @@ -237,7 +237,7 @@ public: * This should be used in following way: * <ul> * <li>value keeper which wants to enable observers has to implement - * IObserverHandler interface which enables to register and unregister + * ObserverHandler interface which enables to register and unregister * observers. It guaranties it calls notify on each registered observer after * change was registered. * <li>implementator of class is responsible for notify method implementation @@ -256,21 +256,32 @@ public: * Each observer implementation has its priority which is used be value keeper * to determine order in which to notify obsevers, if there is more then one. * <br> + * Observer can be in active/inactive state depending on the active flag value. + * See setActive, isActive methods. + * <br> * Exception NOTE: * No method throws an exception. */ template<typename T> class IObserver { + /** Active flag. + * Observer is ignored by observer handler if it is false. + */ + bool active; public: /** Type for priority. */ typedef int priority_t; + + /** Default constructor. + */ + IObserver():active(true) {} /** Notify method. * @param newValue New value of changed value or its part. * @param context Value change context. * - * Each time value keeper, which implements IObserverHandler, changes + * Each time value keeper, which implements ObserverHandler, changes * value (or its part), all registered observers are notified about that * by this method calling. * <br> @@ -299,6 +310,25 @@ public: */ virtual priority_t getPriority()const throw() =0; + /** Sets active flag value. + * @param active Flag value to be set. + * @return previous value of the flag. + */ + bool setActive(bool active) + { + bool oldValue = this->active; + this->active = active; + return oldValue; + } + + /** Returns current value of the active flag. + * @return true if observer can be notified, false otherwise. + */ + bool isActive()const + { + return active; + } + /** * Virtual destructor. */ @@ -434,7 +464,7 @@ public: #endif /** Wrapper for observer registration. - * @param obj Observer handler (IObserverHandler wrapped by shared_ptr). + * @param obj Observer handler (ObserverHandler wrapped by shared_ptr). * @param observer Observer to be registered (IObserver wrapped by shared_ptr). * * Note that this way of observer registration is preffered because @@ -450,7 +480,7 @@ public: }while(0) /** Wrapper for observer unregistration. - * @param obj Observer handler (IObserverHandler wrapped by shared_ptr). + * @param obj Observer handler (ObserverHandler wrapped by shared_ptr). * @param observer Observer to be registered (IObserver wrapped by shared_ptr). * * Note that this way of observer unregistration is preffered because @@ -466,7 +496,7 @@ public: }while(0) /** Wrapper for observer registration. - * @param obj Observer handler (simple pointer to IObserverHandler). + * @param obj Observer handler (simple pointer to ObserverHandler). * @param observer Observer to be registered (simple pointer to IObserver). * * Note that this way of observer registration is preffered because @@ -482,7 +512,7 @@ public: }while(0) /** Wrapper for observer unregistration. - * @param obj Observer handler (simple pointer to IObserverHandler). + * @param obj Observer handler (simple pointer to ObserverHandler). * @param observer Observer to be unregistered (simple pointer to IObserver). * * Note that this way of observer unregistration is preffered because @@ -604,11 +634,12 @@ public: } /** - * Notify all observers about a change. + * Notify all active observers about a change. * * Observers are notified in according their priorities. Higher priority * (smaller priority value) sooner it is called. Observers with same - * priorities are called in unspecified order. + * priorities are called in unspecified order. All inactive observers + * are ignored. * * @param newValue Object with new value. * @param context Context in which the change has been made. @@ -618,7 +649,11 @@ public: // obsrvers list is ordered by priorities, so iteration works correctly typename ObserverList::const_iterator it = observers.begin (); for (; it != observers.end(); ++it) - (*it)->notify (newValue, context); + { + Observer o = (*it); + if(o->isActive()) + o->notify (newValue, context); + } } }; -- Michal Hocko |