// $Id: Subject.hh 6096 2007-02-19 10:06:26Z m9710797 $ #ifndef SUBJECT_HH #define SUBJECT_HH #include "Observer.hh" #include #include #include namespace openmsx { /** * Generic Gang-of-Four Subject class of the Observer pattern, templatized * edition. */ template class Subject { public: void attach(Observer& observer); void detach(Observer& observer); protected: Subject(); ~Subject(); void notify() const; private: typedef std::vector*> Observers; Observers observers; #ifndef NDEBUG mutable bool notifyInProgress; #endif }; template Subject::Subject() #ifndef NDEBUG : notifyInProgress(false) #endif { } template Subject::~Subject() { assert(!notifyInProgress); assert(observers.empty()); } template void Subject::attach(Observer& observer) { assert(!notifyInProgress); observers.push_back(&observer); } template void Subject::detach(Observer& observer) { assert(!notifyInProgress); typename Observers::iterator it = find(observers.begin(), observers.end(), &observer); assert(it != observers.end()); observers.erase(it); } template void Subject::notify() const { #ifndef NDEBUG assert(!notifyInProgress); notifyInProgress = true; #endif for (typename Observers::const_iterator it = observers.begin(); it != observers.end(); ++it) { (*it)->update(*static_cast(this)); } #ifndef NDEBUG notifyInProgress = false; #endif } } #endif