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 2011 Nate Koenig
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 
43  class Event
44  {
46  public: virtual ~Event() {}
47 
50  public: virtual void Disconnect(ConnectionPtr _c) = 0;
51 
54  public: virtual void Disconnect(int _id) = 0;
55  };
56 
58  class Connection
59  {
61  public: Connection() :event(NULL), id(-1) {}
62 
66  public: Connection(Event *_e, int _i);
67 
69  public: ~Connection();
70 
73  public: int GetId() const;
74 
76  private: Event *event;
77 
79  private: int id;
80 
82  private: static int counter;
83 
85  private: common::Time creationTime;
86 
87  public: template<typename T> friend class EventT;
88  };
89 
91  template< typename T>
92  class EventT : public Event
93  {
95  public: virtual ~EventT();
96 
101  public: ConnectionPtr Connect(const boost::function<T> &_subscriber);
102 
105  public: virtual void Disconnect(ConnectionPtr _c);
106 
109  public: virtual void Disconnect(int _id);
110 
112  public: void operator()()
113  {this->Signal();}
114 
116  public: void Signal()
117  {
118  for (unsigned int i = 0; i < connections.size(); i++)
119  {
120  (*this->connections[i])();
121  }
122  }
123 
126  public: template< typename P >
127  void operator()(const P &_p)
128  { this->Signal(_p); }
129 
133  public: template< typename P1, typename P2 >
134  void operator()(const P1 &_p1, const P2 &_p2)
135  { this->Signal(_p1, _p2); }
136 
141  public: template< typename P1, typename P2, typename P3 >
142  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
143  { this->Signal(_p1, _p2, _p3); }
144 
150  public: template< typename P1, typename P2, typename P3, typename P4 >
151  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
152  const P4 &_p4)
153  { this->Signal(_p1, _p2, _p3, _p4); }
154 
161  public: template< typename P1, typename P2, typename P3, typename P4,
162  typename P5 >
163  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
164  const P4 &_p4, const P5 &_p5)
165  { this->Signal(_p1, _p2, _p3, _p4, _p5); }
166 
174  public: template< typename P1, typename P2, typename P3, typename P4,
175  typename P5, typename P6 >
176  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
177  const P4 &_p4, const P5 &_p5, const P6 &_p6)
178  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6); }
179 
188  public: template< typename P1, typename P2, typename P3, typename P4,
189  typename P5, typename P6, typename P7 >
190  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
191  const P4 &_p4, const P5 &_p5, const P6 &_p6,
192  const P7 &_p7)
193  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7); }
194 
204  public: template< typename P1, typename P2, typename P3, typename P4,
205  typename P5, typename P6, typename P7, typename P8 >
206  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
207  const P4 &_p4, const P5 &_p5, const P6 &_p6,
208  const P7 &_p7, const P8 &_p8)
209  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8); }
210 
221  public: template< typename P1, typename P2, typename P3, typename P4,
222  typename P5, typename P6, typename P7, typename P8,
223  typename P9 >
224  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
225  const P4 &_p4, const P5 &_p5, const P6 &_p6,
226  const P7 &_p7, const P8 &_p8, const P9 &_p9)
227  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9); }
228 
240  public: template< typename P1, typename P2, typename P3, typename P4,
241  typename P5, typename P6, typename P7, typename P8,
242  typename P9, typename P10 >
243  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
244  const P4 &_p4, const P5 &_p5, const P6 &_p6,
245  const P7 &_p7, const P8 &_p8, const P9 &_p9,
246  const P10 &_p10)
247  {
248  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
249  }
250 
253  public: template< typename P >
254  void Signal(const P &_p)
255  {
256  for (unsigned int i = 0; i < connections.size(); i++)
257  {
258  (*this->connections[i])(_p);
259  }
260  }
261 
265  public: template< typename P1, typename P2 >
266  void Signal(const P1 &_p1, const P2 &_p2)
267  {
268  for (unsigned int i = 0; i < connections.size(); i++)
269  {
270  (*this->connections[i])(_p1, _p2);
271  }
272  }
273 
278  public: template< typename P1, typename P2, typename P3 >
279  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
280  {
281  for (unsigned int i = 0; i < connections.size(); i++)
282  {
283  (*this->connections[i])(_p1, _p2, _p3);
284  }
285  }
286 
292  public: template<typename P1, typename P2, typename P3, typename P4>
293  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
294  const P4 &_p4)
295  {
296  for (unsigned int i = 0; i < connections.size(); i++)
297  {
298  (*this->connections[i])(_p1, _p2, _p3, _p4);
299  }
300  }
301 
308  public: template<typename P1, typename P2, typename P3, typename P4,
309  typename P5>
310  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
311  const P4 &_p4, const P5 &_p5)
312  {
313  for (unsigned int i = 0; i < connections.size(); i++)
314  {
315  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5);
316  }
317  }
318 
319 
327  public: template<typename P1, typename P2, typename P3, typename P4,
328  typename P5, typename P6>
329  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
330  const P4 &_p4, const P5 &_p5, const P6 &_p6)
331  {
332  for (unsigned int i = 0; i < connections.size(); i++)
333  {
334  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6);
335  }
336  }
337 
346  public: template<typename P1, typename P2, typename P3, typename P4,
347  typename P5, typename P6, typename P7>
348  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
349  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
350  {
351  for (unsigned int i = 0; i < connections.size(); i++)
352  {
353  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
354  }
355  }
356 
366  public: template<typename P1, typename P2, typename P3, typename P4,
367  typename P5, typename P6, typename P7, typename P8>
368  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
369  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
370  const P8 &_p8)
371  {
372  for (unsigned int i = 0; i < connections.size(); i++)
373  {
374  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
375  }
376  }
377 
388  public: template< typename P1, typename P2, typename P3, typename P4,
389  typename P5, typename P6, typename P7, typename P8,
390  typename P9 >
391  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
392  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
393  const P8 &_p8, const P9 &_p9)
394  {
395  for (unsigned int i = 0; i < connections.size(); i++)
396  {
397  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
398  }
399  }
400 
412  public: template< typename P1, typename P2, typename P3, typename P4,
413  typename P5, typename P6, typename P7, typename P8,
414  typename P9, typename P10 >
415  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
416  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
417  const P8 &_p8, const P9 &_p9, const P10 &_p10)
418  {
419  for (unsigned int i = 0; i < connections.size(); i++)
420  {
421  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5,
422  _p6, _p7, _p8, _p9, _p10);
423  }
424  }
425 
427  private: std::vector<boost::function<T> *> connections;
428 
430  private: std::vector<int> connectionIds;
431 
433  private: boost::mutex lock;
434  };
435 
437  template<typename T>
439  {
440  for (unsigned int i = 0; i < this->connections.size(); i++)
441  delete this->connections[i];
442  this->connections.clear();
443  this->connectionIds.clear();
444  }
445 
448  template<typename T>
449  ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber)
450  {
451  int index = this->connections.size();
452  this->connections.push_back(new boost::function<T>(_subscriber));
453  this->connectionIds.push_back(index);
454  return ConnectionPtr(new Connection(this, index));
455  }
456 
459  template<typename T>
461  {
462  this->Disconnect(_c->GetId());
463  _c->event = NULL;
464  _c->id = -1;
465  }
466 
469  template<typename T>
470  void EventT<T>::Disconnect(int _id)
471  {
472  // search for index of the connection based on id
473  for (unsigned int i = 0; i < this->connectionIds.size(); i++)
474  {
475  if (_id == this->connectionIds[i])
476  {
477  this->connectionIds.erase(this->connectionIds.begin()+i);
478  this->connections.erase(this->connections.begin()+i);
479  break;
480  }
481  }
482  }
484  }
485 }
486 #endif