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 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 public: 00060 friend class Base_Signal; 00061 00062 friend class Event_Queue; 00063 00064 friend struct Compare_Base_Event_Times; 00065 00067 Base_Event(const Ttype delta_time) { // The event will occur in 'delta_time' time units from now! 00068 it_assert(delta_time>=0, "Only causal simulations are possible"); 00069 active = true; 00070 delta_t = delta_time; 00071 expire_t = 0; // Will be set correctly upon calling Event_Queue::add(). 00072 id = global_id++; 00073 } 00074 00076 virtual ~Base_Event(){} 00077 00079 void cancel(){ active = false; } 00080 00081 protected: 00083 virtual void exec(void) = 0; 00085 Ttype delta_t; 00087 Ttype expire_t; 00089 bool active; 00091 unsigned long long int id; 00093 static unsigned long long int global_id; 00094 }; 00095 00097 struct Compare_Base_Event_Times { 00099 bool operator()(Base_Event *event1, Base_Event *event2) { 00100 if(event1->expire_t == event2->expire_t) // Equal expire times. 00101 return (event1->id > event2->id); // Base comparison on the event id. 00102 else 00103 return (event1->expire_t > event2->expire_t); // Different expire times. Regular comparison. 00104 } 00105 }; 00106 00115 class Event_Queue { 00116 public: 00117 friend class Base_Signal; 00118 00120 Event_Queue(){} 00122 ~Event_Queue(){} 00123 00125 static void add(Base_Event *e); 00127 static Ttype now(){return t;} 00129 static void start(); 00131 static void stop(); 00133 static void clear(); 00134 protected: 00135 //static void cancel_all(Base_Signal *s); 00136 private: 00137 typedef std::deque<Base_Event*, std::allocator< Base_Event* > >::iterator Base_Event_Iterator; 00138 static void _run(); 00139 static bool keep_running; 00140 static Ttype t; // Current time. 00141 static std::priority_queue<Base_Event*, 00142 std::deque<Base_Event*, std::allocator<Base_Event*> >, 00143 Compare_Base_Event_Times> event_queue; // Queue for the Events. 00144 }; 00145 00151 template <class ObjectType> 00152 class Event : public Base_Event { 00153 public: 00155 Event(ObjectType *object_pointer, void (ObjectType::*object_function_pointer)(), const Ttype delta_time) : Base_Event(delta_time) { 00156 po = object_pointer; 00157 pm = object_function_pointer; 00158 } 00159 00161 virtual ~Event(){} 00162 00164 virtual void exec(void) { (*po.*pm)(); } 00165 00166 private: 00167 void (ObjectType::*pm)(); // Pointer to class member function to be executed on event expire. 00168 ObjectType *po; // Pointer to object who's member function is to be executed on event expire. 00169 }; 00170 00176 template <class ObjectType, class DataType> class Data_Event : public Base_Event { 00177 public: 00179 Data_Event(ObjectType *object_pointer, 00180 void (ObjectType::*object_function_pointer)(DataType data), 00181 DataType data, const Ttype delta_time) : Base_Event(delta_time) { 00182 po = object_pointer; 00183 pm = object_function_pointer; 00184 u = data; 00185 } 00186 00188 virtual ~Data_Event(){} 00189 00191 virtual void exec(void) { 00192 (*po.*pm)(u); 00193 } 00194 00195 private: 00196 void (ObjectType::*pm)(DataType data); // Pointer to class member function to be executed on event expire. 00197 ObjectType* po; // Pointer to object who's member function is to be executed on event expire. 00198 DataType u; // User data. 00199 }; 00200 00202 00203 } // namespace itpp 00204 00205 #endif // #ifndef EVENTS_H
Generated on Sat Apr 19 11:01:27 2008 for IT++ by Doxygen 1.5.5