00001 00029 #ifndef EVENTS_H 00030 #define EVENTS_H 00031 00032 #include <itpp/base/itassert.h> 00033 #include <queue> 00034 #include <deque> 00035 00036 00037 namespace itpp 00038 { 00039 00041 00042 00043 // typedef long double Ttype; //!< 128-bit floating point time 00044 typedef double Ttype; 00045 // typedef long unsigned int Ttype; //!< 64-bit unsigned integer time 00046 00047 class Event_Queue; 00048 class Base_Event; 00049 class Base_Signal; 00050 00058 class Base_Event 00059 { 00060 public: 00061 friend class Base_Signal; 00062 00063 friend class Event_Queue; 00064 00065 friend struct Compare_Base_Event_Times; 00066 00068 Base_Event(const Ttype delta_time) { // The event will occur in 'delta_time' time units from now! 00069 it_assert(delta_time >= 0, "Only causal simulations are possible"); 00070 active = true; 00071 delta_t = delta_time; 00072 expire_t = 0; // Will be set correctly upon calling Event_Queue::add(). 00073 id = global_id++; 00074 } 00075 00077 virtual ~Base_Event() {} 00078 00080 void cancel() { active = false; } 00081 00082 protected: 00084 virtual void exec(void) = 0; 00086 Ttype delta_t; 00088 Ttype expire_t; 00090 bool active; 00092 unsigned long long int id; 00094 static unsigned long long int global_id; 00095 }; 00096 00098 struct Compare_Base_Event_Times { 00100 bool operator()(Base_Event *event1, Base_Event *event2) { 00101 if (event1->expire_t == event2->expire_t) // Equal expire times. 00102 return (event1->id > event2->id); // Base comparison on the event id. 00103 else 00104 return (event1->expire_t > event2->expire_t); // Different expire times. Regular comparison. 00105 } 00106 }; 00107 00116 class Event_Queue 00117 { 00118 public: 00119 friend class Base_Signal; 00120 00122 Event_Queue() {} 00124 ~Event_Queue() {} 00125 00127 static void add(Base_Event *e); 00129 static Ttype now() {return t;} 00131 static void start(); 00133 static void stop(); 00135 static void clear(); 00136 protected: 00137 //static void cancel_all(Base_Signal *s); 00138 private: 00139 typedef std::deque<Base_Event*, std::allocator< Base_Event* > >::iterator Base_Event_Iterator; 00140 static void _run(); 00141 static bool keep_running; 00142 static Ttype t; // Current time. 00143 static std::priority_queue < Base_Event*, 00144 std::deque<Base_Event*, std::allocator<Base_Event*> >, 00145 Compare_Base_Event_Times > event_queue; // Queue for the Events. 00146 }; 00147 00153 template <class ObjectType> 00154 class Event : public Base_Event 00155 { 00156 public: 00158 Event(ObjectType *object_pointer, void (ObjectType::*object_function_pointer)(), const Ttype delta_time) : Base_Event(delta_time) { 00159 po = object_pointer; 00160 pm = object_function_pointer; 00161 } 00162 00164 virtual ~Event() {} 00165 00167 virtual void exec(void) {(*po.*pm)(); } 00168 00169 private: 00170 void (ObjectType::*pm)(); // Pointer to class member function to be executed on event expire. 00171 ObjectType *po; // Pointer to object who's member function is to be executed on event expire. 00172 }; 00173 00179 template <class ObjectType, class DataType> class Data_Event : public Base_Event 00180 { 00181 public: 00183 Data_Event(ObjectType *object_pointer, 00184 void (ObjectType::*object_function_pointer)(DataType data), 00185 DataType data, const Ttype delta_time) : Base_Event(delta_time) { 00186 po = object_pointer; 00187 pm = object_function_pointer; 00188 u = data; 00189 } 00190 00192 virtual ~Data_Event() {} 00193 00195 virtual void exec(void) { 00196 (*po.*pm)(u); 00197 } 00198 00199 private: 00200 void (ObjectType::*pm)(DataType data); // Pointer to class member function to be executed on event expire. 00201 ObjectType* po; // Pointer to object who's member function is to be executed on event expire. 00202 DataType u; // User data. 00203 }; 00204 00206 00207 } // namespace itpp 00208 00209 #endif // #ifndef EVENTS_H
Generated on Wed Jul 27 2011 16:27:05 for IT++ by Doxygen 1.7.4