00001 00033 #ifndef EVENTS_H 00034 #define EVENTS_H 00035 00036 #include <itpp/base/itassert.h> 00037 #include <queue> 00038 #include <deque> 00039 00040 00041 namespace itpp { 00042 //typedef long double Ttype; // 128-bit floating point time. 00043 typedef double Ttype; // 64-bit floating point time. 00044 //typedef long unsigned int Ttype; // 64-bit unsigned integer time. 00045 00046 class Event_Queue; 00047 class Base_Event; 00048 class Base_Signal; 00049 00057 class Base_Event { 00058 public: 00059 friend class Base_Signal; 00060 00061 friend class Event_Queue; 00062 00063 friend struct Compare_Base_Event_Times; 00064 00066 Base_Event(const Ttype delta_time) { // The event will occur in 'delta_time' time units from now! 00067 it_assert(delta_time>=0, "Only causal simulations are possible"); 00068 active = true; 00069 delta_t = delta_time; 00070 expire_t = 0; // Will be set correctly upon calling Event_Queue::add(). 00071 id = global_id++; 00072 } 00073 00075 virtual ~Base_Event(){} 00076 00078 void cancel(){ active = false; } 00079 00080 protected: 00081 virtual void exec(void) = 0; 00082 Ttype delta_t; 00083 Ttype expire_t; 00084 bool active; 00085 unsigned long long int id; 00086 static unsigned long long int global_id; 00087 }; 00088 00090 struct Compare_Base_Event_Times { 00092 bool operator()(Base_Event *event1, Base_Event *event2) { 00093 if(event1->expire_t == event2->expire_t) // Equal expire times. 00094 return (event1->id > event2->id); // Base comparison on the event id. 00095 else 00096 return (event1->expire_t > event2->expire_t); // Different expire times. Regular comparison. 00097 } 00098 }; 00099 00108 class Event_Queue { 00109 public: 00110 friend class Base_Signal; 00111 00113 Event_Queue(){} 00115 ~Event_Queue(){} 00116 00118 static void add(Base_Event *e); 00120 static Ttype now(){return t;} 00122 static void start(); 00124 static void stop(); 00126 static void clear(); 00127 protected: 00128 //static void cancel_all(Base_Signal *s); 00129 private: 00130 typedef std::deque<Base_Event*, std::allocator< Base_Event* > >::iterator Base_Event_Iterator; 00131 static void _run(); 00132 static bool keep_running; 00133 static Ttype t; // Current time. 00134 static std::priority_queue<Base_Event*, 00135 std::deque<Base_Event*, std::allocator<Base_Event*> >, 00136 Compare_Base_Event_Times> event_queue; // Queue for the Events. 00137 }; 00138 00144 template <class ObjectType> 00145 class Event : public Base_Event { 00146 public: 00148 Event(ObjectType *object_pointer, void (ObjectType::*object_function_pointer)(), const Ttype delta_time) : Base_Event(delta_time) { 00149 po = object_pointer; 00150 pm = object_function_pointer; 00151 } 00152 00154 virtual ~Event(){} 00155 00157 virtual void exec(void) { (*po.*pm)(); } 00158 00159 private: 00160 void (ObjectType::*pm)(); // Pointer to class member function to be executed on event expire. 00161 ObjectType *po; // Pointer to object who's member function is to be executed on event expire. 00162 }; 00163 00169 template <class ObjectType, class DataType> class Data_Event : public Base_Event { 00170 public: 00172 Data_Event(ObjectType *object_pointer, 00173 void (ObjectType::*object_function_pointer)(DataType data), 00174 DataType data, const Ttype delta_time) : Base_Event(delta_time) { 00175 po = object_pointer; 00176 pm = object_function_pointer; 00177 u = data; 00178 } 00179 00181 virtual ~Data_Event(){} 00182 00184 virtual void exec(void) { 00185 (*po.*pm)(u); 00186 } 00187 00188 private: 00189 void (ObjectType::*pm)(DataType data); // Pointer to class member function to be executed on event expire. 00190 ObjectType* po; // Pointer to object who's member function is to be executed on event expire. 00191 DataType u; // User data. 00192 }; 00193 00194 } // namespace itpp 00195 00196 #endif // #ifndef EVENTS_H
Generated on Fri Jun 8 02:08:56 2007 for IT++ by Doxygen 1.5.2