00001 00030 #ifndef EVENTS_H 00031 #define EVENTS_H 00032 00033 #include <itpp/base/itassert.h> 00034 #include <queue> 00035 #include <deque> 00036 00037 00038 namespace itpp 00039 { 00040 00042 00043 00044 // typedef long double Ttype; //!< 128-bit floating point time 00045 typedef double Ttype; 00046 // typedef long unsigned int Ttype; //!< 64-bit unsigned integer time 00047 00048 class Event_Queue; 00049 class Base_Event; 00050 class Base_Signal; 00051 00059 class Base_Event 00060 { 00061 public: 00062 friend class Base_Signal; 00063 00064 friend class Event_Queue; 00065 00066 friend struct Compare_Base_Event_Times; 00067 00069 Base_Event(const Ttype delta_time) { // The event will occur in 'delta_time' time units from now! 00070 it_assert(delta_time >= 0, "Only causal simulations are possible"); 00071 active = true; 00072 delta_t = delta_time; 00073 expire_t = 0; // Will be set correctly upon calling Event_Queue::add(). 00074 id = global_id++; 00075 } 00076 00078 virtual ~Base_Event() {} 00079 00081 void cancel() { active = false; } 00082 00083 protected: 00085 virtual void exec(void) = 0; 00087 Ttype delta_t; 00089 Ttype expire_t; 00091 bool active; 00093 unsigned long long int id; 00095 static unsigned long long int global_id; 00096 }; 00097 00099 struct Compare_Base_Event_Times { 00101 bool operator()(Base_Event *event1, Base_Event *event2) { 00102 if (event1->expire_t == event2->expire_t) // Equal expire times. 00103 return (event1->id > event2->id); // Base comparison on the event id. 00104 else 00105 return (event1->expire_t > event2->expire_t); // Different expire times. Regular comparison. 00106 } 00107 }; 00108 00117 class Event_Queue 00118 { 00119 public: 00120 friend class Base_Signal; 00121 00123 Event_Queue() {} 00125 ~Event_Queue() {} 00126 00128 static void add(Base_Event *e); 00130 static Ttype now() {return t;} 00132 static void start(); 00134 static void stop(); 00136 static void clear(); 00137 protected: 00138 //static void cancel_all(Base_Signal *s); 00139 private: 00140 typedef std::deque<Base_Event*, std::allocator< Base_Event* > >::iterator Base_Event_Iterator; 00141 static void _run(); 00142 static bool keep_running; 00143 static Ttype t; // Current time. 00144 static std::priority_queue < Base_Event*, 00145 std::deque<Base_Event*, std::allocator<Base_Event*> >, 00146 Compare_Base_Event_Times > event_queue; // Queue for the Events. 00147 }; 00148 00154 template <class ObjectType> 00155 class Event : public Base_Event 00156 { 00157 public: 00159 Event(ObjectType *object_pointer, void (ObjectType::*object_function_pointer)(), const Ttype delta_time) : Base_Event(delta_time) { 00160 po = object_pointer; 00161 pm = object_function_pointer; 00162 } 00163 00165 virtual ~Event() {} 00166 00168 virtual void exec(void) {(*po.*pm)(); } 00169 00170 private: 00171 void (ObjectType::*pm)(); // Pointer to class member function to be executed on event expire. 00172 ObjectType *po; // Pointer to object who's member function is to be executed on event expire. 00173 }; 00174 00180 template <class ObjectType, class DataType> class Data_Event : public Base_Event 00181 { 00182 public: 00184 Data_Event(ObjectType *object_pointer, 00185 void (ObjectType::*object_function_pointer)(DataType data), 00186 DataType data, const Ttype delta_time) : Base_Event(delta_time) { 00187 po = object_pointer; 00188 pm = object_function_pointer; 00189 u = data; 00190 } 00191 00193 virtual ~Data_Event() {} 00194 00196 virtual void exec(void) { 00197 (*po.*pm)(u); 00198 } 00199 00200 private: 00201 void (ObjectType::*pm)(DataType data); // Pointer to class member function to be executed on event expire. 00202 ObjectType* po; // Pointer to object who's member function is to be executed on event expire. 00203 DataType u; // User data. 00204 }; 00205 00207 00208 } // namespace itpp 00209 00210 #endif // #ifndef EVENTS_H
Generated on Fri Aug 14 15:28:24 2009 for IT++ by Doxygen 1.5.9