00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef GRINLIZ_PUBLISHER_INCLUDED
00027 #define GRINLIZ_PUBLISHER_INCLUDED
00028
00029 #ifdef _MSC_VER
00030 #pragma warning( disable : 4786 )
00031 #endif
00032
00033 #include <set>
00034
00035 namespace grinliz {
00036
00052 template< class LISTENER_CLASS >
00053 class Publisher
00054 {
00055 public:
00056
00057 typedef typename std::set<LISTENER_CLASS*>::iterator iterator;
00059 typedef typename std::set<LISTENER_CLASS*>::const_iterator const_iterator;
00060
00061 Publisher() : copyValid( false ) {}
00062
00063 ~Publisher()
00064 {
00065 for( iterator listenerIterator = listeners.begin();
00066 listenerIterator != listeners.end();
00067 ++listenerIterator )
00068 {
00069 (*listenerIterator)->publishers.erase( this );
00070 }
00071 }
00072
00074 void AddListener( LISTENER_CLASS* add )
00075 {
00076 copyValid = false;
00077 listeners.insert( add );
00078 add->publishers.insert( this );
00079 }
00080
00083 void RemoveListener( LISTENER_CLASS* remove )
00084 {
00085 copyValid = false;
00086 remove->publishers.erase( this );
00087 listeners.erase( remove );
00088 }
00089
00101 const_iterator begin() { if ( !copyValid )
00102 {
00103 listenersCopy.clear();
00104 listenersCopy = listeners;
00105 copyValid = true;
00106 }
00107 return listenersCopy.begin();
00108 }
00109
00111 const_iterator end() { return listenersCopy.end(); }
00112
00113 bool empty() { return listeners.empty(); }
00114
00115 private:
00116 std::set<LISTENER_CLASS*> listeners;
00117
00118
00119
00120
00121
00122 bool copyValid;
00123 std::set<LISTENER_CLASS*> listenersCopy;
00124 };
00125
00126
00149 template <class LISTENER_CLASS>
00150 class Listener
00151 {
00152 friend class Publisher< LISTENER_CLASS >;
00153
00154 private:
00155 std::set< Publisher<LISTENER_CLASS>* > publishers;
00156 typedef typename std::set< Publisher<LISTENER_CLASS>* >::iterator iterator;
00157
00158 public:
00159 virtual ~Listener()
00160 {
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170 while ( true )
00171 {
00172 iterator it = publishers.begin();
00173 if ( it == publishers.end() ) break;
00174 (*it)->RemoveListener( static_cast< LISTENER_CLASS* >( this ) );
00175 }
00176 }
00177 };
00178
00179 };
00180 #endif