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 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 
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 
114  public: void operator()()
115  {this->Signal();}
116 
118  public: void Signal()
119  {
120  for (unsigned int i = 0; i < connections.size(); i++)
121  {
122  (*this->connections[i])();
123  }
124  }
125 
128  public: template< typename P >
129  void operator()(const P &_p)
130  { this->Signal(_p); }
131 
135  public: template< typename P1, typename P2 >
136  void operator()(const P1 &_p1, const P2 &_p2)
137  { this->Signal(_p1, _p2); }
138 
143  public: template< typename P1, typename P2, typename P3 >
144  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
145  { this->Signal(_p1, _p2, _p3); }
146 
152  public: template< typename P1, typename P2, typename P3, typename P4 >
153  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
154  const P4 &_p4)
155  { this->Signal(_p1, _p2, _p3, _p4); }
156 
163  public: template< typename P1, typename P2, typename P3, typename P4,
164  typename P5 >
165  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
166  const P4 &_p4, const P5 &_p5)
167  { this->Signal(_p1, _p2, _p3, _p4, _p5); }
168 
176  public: template< typename P1, typename P2, typename P3, typename P4,
177  typename P5, typename P6 >
178  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
179  const P4 &_p4, const P5 &_p5, const P6 &_p6)
180  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6); }
181 
190  public: template< typename P1, typename P2, typename P3, typename P4,
191  typename P5, typename P6, typename P7 >
192  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
193  const P4 &_p4, const P5 &_p5, const P6 &_p6,
194  const P7 &_p7)
195  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7); }
196 
206  public: template< typename P1, typename P2, typename P3, typename P4,
207  typename P5, typename P6, typename P7, typename P8 >
208  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
209  const P4 &_p4, const P5 &_p5, const P6 &_p6,
210  const P7 &_p7, const P8 &_p8)
211  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8); }
212 
223  public: template< typename P1, typename P2, typename P3, typename P4,
224  typename P5, typename P6, typename P7, typename P8,
225  typename P9 >
226  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
227  const P4 &_p4, const P5 &_p5, const P6 &_p6,
228  const P7 &_p7, const P8 &_p8, const P9 &_p9)
229  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9); }
230 
242  public: template< typename P1, typename P2, typename P3, typename P4,
243  typename P5, typename P6, typename P7, typename P8,
244  typename P9, typename P10 >
245  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
246  const P4 &_p4, const P5 &_p5, const P6 &_p6,
247  const P7 &_p7, const P8 &_p8, const P9 &_p9,
248  const P10 &_p10)
249  {
250  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
251  }
252 
255  public: template< typename P >
256  void Signal(const P &_p)
257  {
258  for (unsigned int i = 0; i < connections.size(); i++)
259  {
260  (*this->connections[i])(_p);
261  }
262  }
263 
267  public: template< typename P1, typename P2 >
268  void Signal(const P1 &_p1, const P2 &_p2)
269  {
270  for (unsigned int i = 0; i < connections.size(); i++)
271  {
272  (*this->connections[i])(_p1, _p2);
273  }
274  }
275 
280  public: template< typename P1, typename P2, typename P3 >
281  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
282  {
283  for (unsigned int i = 0; i < connections.size(); i++)
284  {
285  (*this->connections[i])(_p1, _p2, _p3);
286  }
287  }
288 
294  public: template<typename P1, typename P2, typename P3, typename P4>
295  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
296  const P4 &_p4)
297  {
298  for (unsigned int i = 0; i < connections.size(); i++)
299  {
300  (*this->connections[i])(_p1, _p2, _p3, _p4);
301  }
302  }
303 
310  public: template<typename P1, typename P2, typename P3, typename P4,
311  typename P5>
312  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
313  const P4 &_p4, const P5 &_p5)
314  {
315  for (unsigned int i = 0; i < connections.size(); i++)
316  {
317  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5);
318  }
319  }
320 
321 
329  public: template<typename P1, typename P2, typename P3, typename P4,
330  typename P5, typename P6>
331  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
332  const P4 &_p4, const P5 &_p5, const P6 &_p6)
333  {
334  for (unsigned int i = 0; i < connections.size(); i++)
335  {
336  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6);
337  }
338  }
339 
348  public: template<typename P1, typename P2, typename P3, typename P4,
349  typename P5, typename P6, typename P7>
350  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
351  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
352  {
353  for (unsigned int i = 0; i < connections.size(); i++)
354  {
355  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
356  }
357  }
358 
368  public: template<typename P1, typename P2, typename P3, typename P4,
369  typename P5, typename P6, typename P7, typename P8>
370  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
371  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
372  const P8 &_p8)
373  {
374  for (unsigned int i = 0; i < connections.size(); i++)
375  {
376  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
377  }
378  }
379 
390  public: template< typename P1, typename P2, typename P3, typename P4,
391  typename P5, typename P6, typename P7, typename P8,
392  typename P9 >
393  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
394  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
395  const P8 &_p8, const P9 &_p9)
396  {
397  for (unsigned int i = 0; i < connections.size(); i++)
398  {
399  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
400  }
401  }
402 
414  public: template< typename P1, typename P2, typename P3, typename P4,
415  typename P5, typename P6, typename P7, typename P8,
416  typename P9, typename P10 >
417  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
418  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
419  const P8 &_p8, const P9 &_p9, const P10 &_p10)
420  {
421  for (unsigned int i = 0; i < connections.size(); i++)
422  {
423  (*this->connections[i])(_p1, _p2, _p3, _p4, _p5,
424  _p6, _p7, _p8, _p9, _p10);
425  }
426  }
427 
429  private: std::vector<boost::function<T> *> connections;
430 
432  private: std::vector<int> connectionIds;
433 
435  private: boost::mutex lock;
436  };
437 
439  template<typename T>
441  {
442  for (unsigned int i = 0; i < this->connections.size(); i++)
443  delete this->connections[i];
444  this->connections.clear();
445  this->connectionIds.clear();
446  }
447 
450  template<typename T>
451  ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber)
452  {
453  int index = this->connections.size();
454  this->connections.push_back(new boost::function<T>(_subscriber));
455  this->connectionIds.push_back(index);
456  return ConnectionPtr(new Connection(this, index));
457  }
458 
461  template<typename T>
463  {
464  this->Disconnect(_c->GetId());
465  _c->event = NULL;
466  _c->id = -1;
467  }
468 
471  template<typename T>
472  void EventT<T>::Disconnect(int _id)
473  {
474  // search for index of the connection based on id
475  for (unsigned int i = 0; i < this->connectionIds.size(); i++)
476  {
477  if (_id == this->connectionIds[i])
478  {
479  this->connectionIds.erase(this->connectionIds.begin()+i);
480  this->connections.erase(this->connections.begin()+i);
481  break;
482  }
483  }
484  }
486  }
487 }
488 #endif