Event.hh
00001 /* 00002 * Copyright 2011 Nate Koenig & Andrew Howard 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 * 00016 */ 00017 00018 #ifndef EVENT_HH 00019 #define EVENT_HH 00020 00021 #include <iostream> 00022 #include <vector> 00023 #include <boost/function.hpp> 00024 #include <boost/bind.hpp> 00025 #include <boost/shared_ptr.hpp> 00026 #include <boost/thread/mutex.hpp> 00027 00028 #include "common/Time.hh" 00029 #include "common/CommonTypes.hh" 00030 #include "gazebo_config.h" 00031 00032 namespace gazebo 00033 { 00036 namespace event 00037 { 00040 00042 class Event 00043 { 00044 public: virtual void Disconnect(ConnectionPtr c) = 0; 00045 public: virtual void Disconnect(int id) = 0; 00046 }; 00047 00049 class Connection 00050 { 00051 public: Connection() :event(NULL), id(-1), uniqueId(-1) {} 00052 public: Connection(Event *e, int i); 00053 public: ~Connection(); 00054 public: int GetId() const; 00055 public: int GetUniqueId() const; 00056 private: Event *event; 00057 private: int id; 00058 00059 private: static int counter; 00060 private: int uniqueId; 00061 00062 private: common::Time creationTime; 00063 public: template<typename T> friend class EventT; 00064 }; 00065 00067 template< typename T> 00068 class EventT : public Event 00069 { 00070 public: virtual ~EventT(); 00071 00075 public: ConnectionPtr Connect(const boost::function<T> &subscriber); 00076 00078 public: virtual void Disconnect(ConnectionPtr c); 00079 public: virtual void Disconnect(int id); 00080 00081 public: void operator()() 00082 { this->Signal(); } 00083 00084 public: void Signal() 00085 { 00086 for (unsigned int i=0; i < connections.size(); i++) 00087 { 00088 (*this->connections[i])(); 00089 } 00090 } 00091 00092 public: template< typename P > 00093 void operator()(const P &p) 00094 { this->Signal(p); } 00095 00096 public: template< typename P1, typename P2 > 00097 void operator()(const P1 &p1, const P2 &p2) 00098 { this->Signal(p1, p2); } 00099 00100 public: template< typename P1, typename P2, typename P3 > 00101 void operator()(const P1 &p1, const P2 &p2, const P3 &p3) 00102 { this->Signal(p1, p2, p3); } 00103 00104 public: template< typename P1, typename P2, typename P3, typename P4 > 00105 void operator()(const P1 &p1, const P2 &p2, const P3 &p3, 00106 const P4 &p4) 00107 { this->Signal(p1, p2, p3, p4); } 00108 00109 public: template< typename P1, typename P2, typename P3, typename P4, 00110 typename P5 > 00111 void operator()(const P1 &p1, const P2 &p2, const P3 &p3, 00112 const P4 &p4, const P5 &p5) 00113 { this->Signal(p1, p2, p3, p4, p5); } 00114 00115 public: template< typename P1, typename P2, typename P3, typename P4, 00116 typename P5, typename P6 > 00117 void operator()(const P1 &p1, const P2 &p2, const P3 &p3, 00118 const P4 &p4, const P5 &p5, const P6 &p6) 00119 { this->Signal(p1, p2, p3, p4, p5, p6); } 00120 00121 public: template< typename P1, typename P2, typename P3, typename P4, 00122 typename P5, typename P6, typename P7 > 00123 void operator()(const P1 &p1, const P2 &p2, const P3 &p3, 00124 const P4 &p4, const P5 &p5, const P6 &p6, 00125 const P7 &p7) 00126 { this->Signal(p1, p2, p3, p4, p5, p6, p7); } 00127 00128 public: template< typename P1, typename P2, typename P3, typename P4, 00129 typename P5, typename P6, typename P7, typename P8 > 00130 void operator()(const P1 &p1, const P2 &p2, const P3 &p3, 00131 const P4 &p4, const P5 &p5, const P6 &p6, 00132 const P7 &p7, const P8 &p8) 00133 { this->Signal(p1, p2, p3, p4, p5, p6, p7, p8); } 00134 00135 public: template< typename P1, typename P2, typename P3, typename P4, 00136 typename P5, typename P6, typename P7, typename P8, 00137 typename P9 > 00138 void operator()(const P1 &p1, const P2 &p2, const P3 &p3, 00139 const P4 &p4, const P5 &p5, const P6 &p6, 00140 const P7 &p7, const P8 &p8, const P9 &p9) 00141 { this->Signal(p1, p2, p3, p4, p5, p6, p7, p8, p9); } 00142 00143 public: template< typename P1, typename P2, typename P3, typename P4, 00144 typename P5, typename P6, typename P7, typename P8, 00145 typename P9, typename P10 > 00146 void operator()(const P1 &p1, const P2 &p2, const P3 &p3, 00147 const P4 &p4, const P5 &p5, const P6 &p6, 00148 const P7 &p7, const P8 &p8, const P9 &p9, 00149 const P10 &p10) 00150 { this->Signal(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); } 00151 00152 00153 public: template< typename P > 00154 void Signal(const P &p) 00155 { 00156 for (unsigned int i=0; i < connections.size(); i++) 00157 { 00158 (*this->connections[i])(p); 00159 } 00160 } 00161 00162 public: template< typename P1, typename P2 > 00163 void Signal(const P1 &p1, const P2 &p2) 00164 { 00165 for (unsigned int i=0; i < connections.size(); i++) 00166 { 00167 (*this->connections[i])(p1, p2); 00168 } 00169 } 00170 00171 public: template< typename P1, typename P2, typename P3 > 00172 void Signal(const P1 &p1, const P2 &p2, const P3 &p3) 00173 { 00174 for (unsigned int i=0; i < connections.size(); i++) 00175 { 00176 (*this->connections[i])(p1, p2, p3); 00177 } 00178 } 00179 00180 public: template< typename P1, typename P2, typename P3, typename P4 > 00181 void Signal(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4) 00182 { 00183 for (unsigned int i=0; i < connections.size(); i++) 00184 { 00185 (*this->connections[i])(p1, p2, p3, p4); 00186 } 00187 } 00188 00189 public: template< typename P1, typename P2, typename P3, typename P4, 00190 typename P5 > 00191 void Signal(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, 00192 const P5 &p5) 00193 { 00194 for (unsigned int i=0; i < connections.size(); i++) 00195 { 00196 (*this->connections[i])(p1, p2, p3, p4, p5); 00197 } 00198 } 00199 00200 00201 public: template< typename P1, typename P2, typename P3, typename P4, 00202 typename P5, typename P6 > 00203 void Signal(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, 00204 const P5 &p5, const P6 &p6) 00205 { 00206 for (unsigned int i=0; i < connections.size(); i++) 00207 { 00208 (*this->connections[i])(p1, p2, p3, p4, p5, p6); 00209 } 00210 } 00211 00212 public: template< typename P1, typename P2, typename P3, typename P4, 00213 typename P5, typename P6, typename P7 > 00214 void Signal(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, 00215 const P5 &p5, const P6 &p6, const P7 &p7) 00216 { 00217 for (unsigned int i=0; i < connections.size(); i++) 00218 { 00219 (*this->connections[i])(p1, p2, p3, p4, p5, p6, p7); 00220 } 00221 } 00222 00223 public: template< typename P1, typename P2, typename P3, typename P4, 00224 typename P5, typename P6, typename P7, typename P8 > 00225 void Signal(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, 00226 const P5 &p5, const P6 &p6, const P7 &p7, const P8 &p8) 00227 { 00228 for (unsigned int i=0; i < connections.size(); i++) 00229 { 00230 (*this->connections[i])(p1, p2, p3, p4, p5, p6, p7, p8); 00231 } 00232 } 00233 00234 public: template< typename P1, typename P2, typename P3, typename P4, 00235 typename P5, typename P6, typename P7, typename P8, 00236 typename P9 > 00237 void Signal(const P1 &p1, const P2 &p2, const P3 &p3, const P4 &p4, 00238 const P5 &p5, const P6 &p6, const P7 &p7, const P8 &p8, 00239 const P9 &p9) 00240 { 00241 for (unsigned int i=0; i < connections.size(); i++) 00242 { 00243 (*this->connections[i])(p1, p2, p3, p4, p5, p6, p7, p8, p9); 00244 } 00245 } 00246 00247 public: template< typename P1, typename P2, typename P3, typename P4, 00248 typename P5, typename P6, typename P7, typename P8, 00249 typename P9, typename P10 > 00250 void Signal(const P1 &p1, const P2 &p2, const P3 &p3, 00251 const P4 &p4, const P5 &p5, const P6 &p6, const P7 &p7, 00252 const P8 &p8, const P9 &p9, const P10 &p10) 00253 { 00254 for (unsigned int i=0; i < connections.size(); i++) 00255 { 00256 (*this->connections[i])(p1, p2, p3, p4, p5, 00257 p6, p7, p8, p9, p10); 00258 } 00259 } 00260 00261 private: std::vector<boost::function<T> *> connections; 00262 private: std::vector<int> connectionIds; 00263 private: boost::mutex lock; 00264 }; 00265 00266 template<typename T> 00267 EventT<T>::~EventT() 00268 { 00269 for (unsigned int i = 0; i < this->connections.size(); i++) 00270 delete this->connections[i]; 00271 this->connections.clear(); 00272 this->connectionIds.clear(); 00273 } 00274 00275 template<typename T> 00276 ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber) 00277 { 00278 //this->lock.lock(); 00279 int index = this->connections.size(); 00280 this->connections.push_back(new boost::function<T>(_subscriber)); 00281 this->connectionIds.push_back(index); 00282 //this->lock.unlock(); 00283 return ConnectionPtr(new Connection(this, index)); 00284 } 00285 00286 template<typename T> 00287 void EventT<T>::Disconnect(ConnectionPtr c) 00288 { 00289 this->Disconnect(c->GetId()); 00290 c->event = NULL; 00291 c->id = -1; 00292 } 00293 00294 template<typename T> 00295 void EventT<T>::Disconnect(int _id) 00296 { 00297 //this->lock.lock(); 00298 // search for index of the connection based on id 00299 for(unsigned int i=0; i < this->connectionIds.size(); i++) 00300 { 00301 if (_id == this->connectionIds[i]) 00302 { 00303 this->connectionIds.erase(this->connectionIds.begin()+i); 00304 this->connections.erase(this->connections.begin()+i); 00305 break; 00306 } 00307 } 00308 //this->lock.unlock(); 00309 } 00311 } 00312 } 00313 #endif

1.7.5.1