00001 00024 #include <typeinfo> 00025 #include <iostream> 00026 #include <assert.h> 00027 using std::cin; 00028 using std::cout; 00029 using std::cerr; 00030 using std::endl; 00031 00032 #include "TimeStampedEvent.hh" 00033 #include "PolymorphEvent.hh" 00034 #include "Listener.hh" 00035 #include "EventSender.hh" 00036 00037 class TicEvent: public TimeStampedEvent<> 00038 { 00039 public: 00040 TicEvent(int bin): _bin(bin) {} 00041 const int _bin; 00042 }; 00043 00044 class TacEvent: public TimeStampedEvent<>, public PolymorphEvent 00045 { 00046 public: 00047 TacEvent(int bin): _bin(bin) {} 00048 virtual void send() const { sendTypedEvent(*this); } 00049 // following will be flagged by compiler only if TacEvent instantiated 00050 //virtual void send() const { EventSender<TacEvent>::send(*this); } 00051 const int _bin; 00052 }; 00053 00054 class TicTacListener; 00055 // global listener to affect reaction of TicTacListener to tic events 00056 TicTacListener* ticTacListener2p = NULL; 00057 00058 class TicTacListener: public Listener<TicEvent>, public Listener<TacEvent> 00059 { 00060 private: 00061 size_t countTicsHeard; 00062 size_t countTacsHeard; 00063 size_t countAllHeard; 00064 00065 public: 00066 TicTacListener(): countTicsHeard(0), countTacsHeard(0), countAllHeard(0) {} 00067 00068 private: 00069 virtual void processEvent(const TicEvent& event); 00070 virtual void processEvent(const TacEvent& event) 00071 { 00072 countTacsHeard ++; 00073 countAllHeard ++; 00074 assert(event.getTimeStamp() == (countAllHeard+1)); 00075 cout << countTacsHeard << ": Heard TacEvent bin " 00076 << event._bin << endl; 00077 assert(EventSender<TicEvent>::isSending()); 00078 } 00079 }; 00080 00081 void TicTacListener::processEvent(const TicEvent& event) 00082 { 00083 countTicsHeard ++; 00084 countAllHeard ++; 00085 if (countTicsHeard==1) 00086 assert(event.getTimeStamp() == countAllHeard); 00087 else 00088 assert(event.getTimeStamp() == (countAllHeard+1)); 00089 00090 cout << countTicsHeard << ": Heard TicEvent bin " 00091 << event._bin << endl; 00092 assert(EventSender<TicEvent>::isSending()); 00093 00094 switch (countTicsHeard) 00095 { 00096 case 1: 00097 EventSender<TicEvent>::send(TicEvent(2)); 00098 break; 00099 case 2: 00100 Listener<TicEvent>::ignoreThisEvent(); 00101 Listener<TicEvent>::ignoreThisEvent(); 00102 Listener<TicEvent>::ignoreThisEvent(); 00103 break; 00104 case 3: { 00105 const size_t before = EventSender<TacEvent>::getMinNumIgnored(); 00106 Listener<TacEvent>::ignoreThisEvent(); // do nothing 00107 assert(before == EventSender<TacEvent>::getMinNumIgnored()); 00108 } 00109 break; 00110 case 4: 00111 Listener<TicEvent>::listenForEvents(); // do nothing 00112 Listener<TicEvent>::ignoreEvents(); // removal queue 00113 Listener<TicEvent>::ignoreEvents(); // do nothing 00114 Listener<TicEvent>::listenForEvents(); // elim from removal 00115 Listener<TicEvent>::listenForEvents(); // do nothing 00116 Listener<TicEvent>::ignoreEvents(); // removal queue 00117 Listener<TicEvent>::ignoreEvents(); // do nothing 00118 break; 00119 case 5: 00120 if (this != ticTacListener2p) 00121 { 00122 assert(ticTacListener2p); 00123 // nada: 00124 ticTacListener2p->Listener<TicEvent>::ignoreEvents(); 00125 ticTacListener2p->Listener<TicEvent>::listenForEvents(); 00126 // nada: 00127 ticTacListener2p->Listener<TicEvent>::listenForEvents(); 00128 // ignore: 00129 ticTacListener2p->Listener<TicEvent>::ignoreEvents(); 00130 ticTacListener2p->Listener<TicEvent>::listenForEvents(); 00131 // nada: 00132 ticTacListener2p->Listener<TicEvent>::listenForEvents(); 00133 } 00134 break; 00135 default: break; 00136 } 00137 } 00138 00139 int main() 00140 { 00141 TicTacListener ticTacListener; 00142 00143 cout << "\n*** Test immediate registration/deregistration ***" << endl; 00144 cout << "--> Deregister unregistered listener: " << endl; 00145 assert(EventSender<TicEvent>::getNumListeners() == 0); 00146 EventSender<TicEvent>::remove(ticTacListener); 00147 assert(EventSender<TicEvent>::getNumListeners() == 0); 00148 cout << "--> Register listener: " << endl; 00149 EventSender<TicEvent>::add(ticTacListener); 00150 assert(EventSender<TicEvent>::getNumListeners() == 1); 00151 00152 /* NOTE: listener is setup so that first event received (ie 00153 first call to send()) causes another TicEvent to be 00154 generated, thereby leading to a recursive flush exception. 00155 This is caught here. 00156 */ 00157 cout << "\n*** Test recursive event generation ***" << endl; 00158 try { 00159 EventSender<TicEvent>::send(TicEvent(1)); 00160 } 00161 //following line leads to compiler crash: 00162 catch (const EventSender<TicEvent>::IllegalSendError& rse) 00163 //catch (const std::logic_error& rse) 00164 { 00165 cout << "RecursiveSend Exception properly thrown, message is:" << endl; 00166 cout << rse.what() << endl; 00167 } 00168 assert(! EventSender<TicEvent>::isSending()); 00169 assert(EventSender<TicEvent>::getMinNumIgnored() == 0); 00170 00171 // NOTE: no other event sent should cause 00172 // exception so no need to catch 00173 00174 cout << "\n*** Test ignoring events ***" << endl; 00175 EventSender<TicEvent>::send( TicEvent(2) ); 00176 assert(EventSender<TicEvent>::getMinNumIgnored() == 1); 00177 EventSender<TicEvent>::send( TicEvent(3) ); 00178 assert(EventSender<TicEvent>::getMinNumIgnored() == 0); 00179 00180 cout << "\n*** Test add/remove during send ***" << endl; 00181 EventSender<TicEvent>::send( TicEvent(4) ); 00182 assert(EventSender<TicEvent>::getNumListeners() == 0); 00183 EventSender<TicEvent>::add(ticTacListener); 00184 00185 TicTacListener ticTacListener2; 00186 ticTacListener2p = &ticTacListener2; 00187 EventSender<TicEvent>::send( TicEvent(5) ); 00188 assert(EventSender<TicEvent>::getNumListeners() == 2); 00189 00190 cout << "\n*** Done ***" << endl; 00191 } 00192