All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Event.hh
Go to the documentation of this file.
1 /*
2  * Copyright 2012 Open Source Robotics Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16 */
17 
18 #ifndef _EVENT_HH_
19 #define _EVENT_HH_
20 
21 #include <gazebo/gazebo_config.h>
22 #include <gazebo/common/Time.hh>
24 
25 #include <boost/function.hpp>
26 #include <boost/bind.hpp>
27 #include <boost/shared_ptr.hpp>
28 #include <boost/thread/mutex.hpp>
29 
30 #include <iostream>
31 #include <vector>
32 
33 namespace gazebo
34 {
37  namespace event
38  {
41 
44  class Event
45  {
47  public: virtual ~Event() {}
48 
51  public: virtual void Disconnect(ConnectionPtr _c) = 0;
52 
55  public: virtual void Disconnect(int _id) = 0;
56  };
57 
59  class Connection
60  {
62  public: Connection() :event(NULL), id(-1) {}
63 
67  public: Connection(Event *_e, int _i);
68 
70  public: ~Connection();
71 
74  public: int GetId() const;
75 
77  private: Event *event;
78 
80  private: int id;
81 
83  private: static int counter;
84 
86  private: common::Time creationTime;
87 
88  public: template<typename T> friend class EventT;
89  };
90 
93  template< typename T>
94  class EventT : public Event
95  {
97  public: virtual ~EventT();
98 
103  public: ConnectionPtr Connect(const boost::function<T> &_subscriber);
104 
107  public: virtual void Disconnect(ConnectionPtr _c);
108 
111  public: virtual void Disconnect(int _id);
112 
115  public: unsigned int ConnectionCount() const;
116 
118  public: void operator()()
119  {this->Signal();}
120 
122  public: void Signal()
123  {
124  for (unsigned int i = 0; i < connections.size(); i++)
125  {
126  (*this->connections[i])();
127  }
128  }
129 
132  public: template< typename P >
133  void operator()(const P &_p)
134  { this->Signal(_p); }
135 
139  public: template< typename P1, typename P2 >
140  void operator()(const P1 &_p1, const P2 &_p2)
141  { this->Signal(_p1, _p2); }
142 
147  public: template< typename P1, typename P2, typename P3 >
148  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
149  { this->Signal(_p1, _p2, _p3); }
150 
156  public: template< typename P1, typename P2, typename P3, typename P4 >
157  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
158  const P4 &_p4)
159  { this->Signal(_p1, _p2, _p3, _p4); }
160 
167  public: template< typename P1, typename P2, typename P3, typename P4,
168  typename P5 >
169  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
170  const P4 &_p4, const P5 &_p5)
171  { this->Signal(_p1, _p2, _p3, _p4, _p5); }
172 
180  public: template< typename P1, typename P2, typename P3, typename P4,
181  typename P5, typename P6 >
182  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
183  const P4 &_p4, const P5 &_p5, const P6 &_p6)
184  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6); }
185 
194  public: template< typename P1, typename P2, typename P3, typename P4,
195  typename P5, typename P6, typename P7 >
196  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
197  const P4 &_p4, const P5 &_p5, const P6 &_p6,
198  const P7 &_p7)
199  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7); }
200 
210  public: template< typename P1, typename P2, typename P3, typename P4,
211  typename P5, typename P6, typename P7, typename P8 >
212  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
213  const P4 &_p4, const P5 &_p5, const P6 &_p6,
214  const P7 &_p7, const P8 &_p8)
215  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8); }
216 
227  public: template< typename P1, typename P2, typename P3, typename P4,
228  typename P5, typename P6, typename P7, typename P8,
229  typename P9 >
230  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
231  const P4 &_p4, const P5 &_p5, const P6 &_p6,
232  const P7 &_p7, const P8 &_p8, const P9 &_p9)
233  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9); }
234 
246  public: template< typename P1, typename P2, typename P3, typename P4,
247  typename P5, typename P6, typename P7, typename P8,
248  typename P9, typename P10 >
249  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
250  const P4 &_p4, const P5 &_p5, const P6 &_p6,
251  const P7 &_p7, const P8 &_p8, const P9 &_p9,
252  const P10 &_p10)
253  {
254  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
255  }
256 
259  public: template< typename P >
260  void Signal(const P &_p)
261  {
262  for (unsigned int i = 0; i < connections.size(); i++)
263  {
264  (*this->connections[i])(_p);
265  }
266  }
267 
271  public: template< typename P1, typename P2 >
272  void Signal(const P1 &_p1, const P2 &_p2)
273  {
274  for (unsigned int i = 0; i < connections.size(); i++)
275  {
276  (*this->connections[i])(_p1, _p2);
277  }
278  }
279 
284  public: template< typename P1, typename P2, typename P3 >
285  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
286  {
287  for (unsigned int i = 0; i < connections.size(); i++)
288  {
289  (*this->connections[i])(_p1, _p2, _p3);
290  }
291  }
292 
298  public: template<typename P1, typename P2, typename P3, typename P4>
299  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
300  const P4 &_p4)
301  {
302  for (unsigned int i = 0; i < connections.size(); i++)
303  {
304  (*this->connections[i])(_p1, _p2, _p3, _p4);
305  }
306  }
307 
314  public: template<typename P1, typename P2, typename P3, typename P4,
315  typename P5>
316  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
317  const P4 &_p4, const P5 &_p5)
318  {
319  for (unsigned int i = 0; i < connections.size(); i++)
320  {
321  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5);
322  }
323  }
324 
325 
333  public: template<typename P1, typename P2, typename P3, typename P4,
334  typename P5, typename P6>
335  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
336  const P4 &_p4, const P5 &_p5, const P6 &_p6)
337  {
338  for (unsigned int i = 0; i < connections.size(); i++)
339  {
340  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6);
341  }
342  }
343 
352  public: template<typename P1, typename P2, typename P3, typename P4,
353  typename P5, typename P6, typename P7>
354  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
355  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
356  {
357  for (unsigned int i = 0; i < connections.size(); i++)
358  {
359  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
360  }
361  }
362 
372  public: template<typename P1, typename P2, typename P3, typename P4,
373  typename P5, typename P6, typename P7, typename P8>
374  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
375  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
376  const P8 &_p8)
377  {
378  for (unsigned int i = 0; i < connections.size(); i++)
379  {
380  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
381  }
382  }
383 
394  public: template< typename P1, typename P2, typename P3, typename P4,
395  typename P5, typename P6, typename P7, typename P8,
396  typename P9 >
397  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
398  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
399  const P8 &_p8, const P9 &_p9)
400  {
401  for (unsigned int i = 0; i < connections.size(); i++)
402  {
403  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
404  }
405  }
406 
418  public: template< typename P1, typename P2, typename P3, typename P4,
419  typename P5, typename P6, typename P7, typename P8,
420  typename P9, typename P10 >
421  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
422  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
423  const P8 &_p8, const P9 &_p9, const P10 &_p10)
424  {
425  for (unsigned int i = 0; i < connections.size(); i++)
426  {
427  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5,
428  _p6, _p7, _p8, _p9, _p10);
429  }
430  }
431 
433  private: std::vector<boost::function<T> *> connections;
434 
436  private: std::vector<int> connectionIds;
437 
439  private: boost::mutex lock;
440  };
441 
443  template<typename T>
445  {
446  for (unsigned int i = 0; i < this->connections.size(); i++)
447  delete this->connections[i];
448  this->connections.clear();
449  this->connectionIds.clear();
450  }
451 
454  template<typename T>
455  ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber)
456  {
457  int index = this->connections.size();
458  this->connections.push_back(new boost::function<T>(_subscriber));
459  this->connectionIds.push_back(index);
460  return ConnectionPtr(new Connection(this, index));
461  }
462 
465  template<typename T>
467  {
468  if (!_c)
469  return;
470 
471  this->Disconnect(_c->GetId());
472  _c->event = NULL;
473  _c->id = -1;
474  }
475 
476  template<typename T>
477  unsigned int EventT<T>::ConnectionCount() const
478  {
479  return this->connections.size();
480  }
481 
484  template<typename T>
485  void EventT<T>::Disconnect(int _id)
486  {
487  // search for index of the connection based on id
488  for (unsigned int i = 0; i < this->connectionIds.size(); i++)
489  {
490  if (_id == this->connectionIds[i])
491  {
492  this->connectionIds.erase(this->connectionIds.begin()+i);
493  this->connections.erase(this->connections.begin()+i);
494  break;
495  }
496  }
497  }
499  }
500 }
501 #endif