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 (C) 2012-2014 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 <iostream>
22 #include <vector>
23 #include <map>
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 <gazebo/gazebo_config.h>
31 #include <gazebo/common/Time.hh>
33 #include <gazebo/math/Helpers.hh>
34 #include "gazebo/util/system.hh"
35 
36 namespace gazebo
37 {
40  namespace event
41  {
44 
46  // Private data members for Event class.
47  // This must be in the header due to templatization.
49  {
50  // \brief Constructor
51  public: EventPrivate();
52 
54  public: bool signaled;
55  };
56 
60  {
62  public: Event();
63 
65  public: virtual ~Event();
66 
69  public: virtual void Disconnect(ConnectionPtr _c) = 0;
70 
73  public: virtual void Disconnect(int _id) = 0;
74 
77  public: bool GetSignaled() const;
78 
81  protected: Event(EventPrivate &_d);
82 
84  protected: EventPrivate *dataPtr;
85  };
86 
88  // Private data members for Connection class.
90  {
92  public: ConnectionPrivate();
93 
97  public: ConnectionPrivate(Event *_e, int _i);
98 
100  public: Event *event;
101 
103  public: int id;
104 
107  };
108 
111  {
113  public: Connection();
114 
118  public: Connection(Event *_e, int _i);
119 
121  public: ~Connection();
122 
125  public: int GetId() const;
126 
128  private: ConnectionPrivate *dataPtr;
129 
131  public: template<typename T> friend class EventT;
132  };
133 
135  // Private data members for EventT<T> class.
136  template< typename T>
138  {
141  typedef std::map<int, boost::function<T>*> EvtConnectionMap;
142 
144  public: EvtConnectionMap connections;
145 
147  public: std::vector<int> connectionsToErase;
148 
150  public: boost::mutex connectionsEraseMutex;
151  };
152 
155  template< typename T>
156  class GAZEBO_VISIBLE EventT : public Event
157  {
160  typedef std::map<int, boost::function<T>*> EvtConnectionMap;
161 
163  public: EventT();
164 
166  public: virtual ~EventT();
167 
172  public: ConnectionPtr Connect(const boost::function<T> &_subscriber);
173 
176  public: virtual void Disconnect(ConnectionPtr _c);
177 
180  public: virtual void Disconnect(int _id);
181 
184  public: unsigned int ConnectionCount() const;
185 
187  public: void operator()()
188  {this->Signal();}
189 
191  public: void Signal()
192  {
193  this->myDataPtr->signaled = true;
194  this->Cleanup();
195  for (typename EvtConnectionMap::iterator iter =
196  this->myDataPtr->connections.begin();
197  iter != this->myDataPtr->connections.end(); ++iter)
198  {
199  (*iter->second)();
200  }
201  }
202 
205  public: template< typename P >
206  void operator()(const P &_p)
207  { this->Signal(_p); }
208 
212  public: template< typename P1, typename P2 >
213  void operator()(const P1 &_p1, const P2 &_p2)
214  { this->Signal(_p1, _p2); }
215 
220  public: template< typename P1, typename P2, typename P3 >
221  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
222  { this->Signal(_p1, _p2, _p3); }
223 
229  public: template< typename P1, typename P2, typename P3, typename P4 >
230  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
231  const P4 &_p4)
232  { this->Signal(_p1, _p2, _p3, _p4); }
233 
240  public: template< typename P1, typename P2, typename P3, typename P4,
241  typename P5 >
242  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
243  const P4 &_p4, const P5 &_p5)
244  { this->Signal(_p1, _p2, _p3, _p4, _p5); }
245 
253  public: template< typename P1, typename P2, typename P3, typename P4,
254  typename P5, typename P6 >
255  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
256  const P4 &_p4, const P5 &_p5, const P6 &_p6)
257  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6); }
258 
267  public: template< typename P1, typename P2, typename P3, typename P4,
268  typename P5, typename P6, typename P7 >
269  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
270  const P4 &_p4, const P5 &_p5, const P6 &_p6,
271  const P7 &_p7)
272  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7); }
273 
283  public: template< typename P1, typename P2, typename P3, typename P4,
284  typename P5, typename P6, typename P7, typename P8 >
285  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
286  const P4 &_p4, const P5 &_p5, const P6 &_p6,
287  const P7 &_p7, const P8 &_p8)
288  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8); }
289 
300  public: template< typename P1, typename P2, typename P3, typename P4,
301  typename P5, typename P6, typename P7, typename P8,
302  typename P9 >
303  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
304  const P4 &_p4, const P5 &_p5, const P6 &_p6,
305  const P7 &_p7, const P8 &_p8, const P9 &_p9)
306  { this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9); }
307 
319  public: template< typename P1, typename P2, typename P3, typename P4,
320  typename P5, typename P6, typename P7, typename P8,
321  typename P9, typename P10 >
322  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
323  const P4 &_p4, const P5 &_p5, const P6 &_p6,
324  const P7 &_p7, const P8 &_p8, const P9 &_p9,
325  const P10 &_p10)
326  {
327  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
328  }
329 
332  public: template< typename P >
333  void Signal(const P &_p)
334  {
335  this->myDataPtr->signaled = true;
336  this->Cleanup();
337  for (typename EvtConnectionMap::iterator iter =
338  this->myDataPtr->connections.begin();
339  iter != this->myDataPtr->connections.end(); ++iter)
340  {
341  (*iter->second)(_p);
342  }
343  }
344 
348  public: template< typename P1, typename P2 >
349  void Signal(const P1 &_p1, const P2 &_p2)
350  {
351  this->myDataPtr->signaled = true;
352  this->Cleanup();
353  for (typename EvtConnectionMap::iterator iter =
354  this->myDataPtr->connections.begin();
355  iter != this->myDataPtr->connections.end(); ++iter)
356  {
357  (*iter->second)(_p1, _p2);
358  }
359  }
360 
365  public: template< typename P1, typename P2, typename P3 >
366  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
367  {
368  this->myDataPtr->signaled = true;
369  this->Cleanup();
370  for (typename EvtConnectionMap::iterator iter =
371  this->myDataPtr->connections.begin();
372  iter != this->myDataPtr->connections.end(); ++iter)
373  {
374  (*iter->second)(_p1, _p2, _p3);
375  }
376  }
377 
383  public: template<typename P1, typename P2, typename P3, typename P4>
384  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
385  const P4 &_p4)
386  {
387  this->myDataPtr->signaled = true;
388  this->Cleanup();
389  for (typename EvtConnectionMap::iterator iter =
390  this->myDataPtr->connections.begin();
391  iter != this->myDataPtr->connections.end(); ++iter)
392  {
393  (*iter->second)(_p1, _p2, _p3, _p4);
394  }
395  }
396 
403  public: template<typename P1, typename P2, typename P3, typename P4,
404  typename P5>
405  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
406  const P4 &_p4, const P5 &_p5)
407  {
408  this->myDataPtr->signaled = true;
409  this->Cleanup();
410  for (typename EvtConnectionMap::iterator iter =
411  this->myDataPtr->connections.begin();
412  iter != this->myDataPtr->connections.end(); ++iter)
413  {
414  (*iter->second)(_p1, _p2, _p3, _p4, _p5);
415  }
416  }
417 
418 
426  public: template<typename P1, typename P2, typename P3, typename P4,
427  typename P5, typename P6>
428  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
429  const P4 &_p4, const P5 &_p5, const P6 &_p6)
430  {
431  this->myDataPtr->signaled = true;
432  this->Cleanup();
433  for (typename EvtConnectionMap::iterator iter =
434  this->myDataPtr->connections.begin();
435  iter != this->myDataPtr->connections.end(); ++iter)
436  {
437  (*iter->second)(_p1, _p2, _p3, _p4, _p5, _p6);
438  }
439  }
440 
449  public: template<typename P1, typename P2, typename P3, typename P4,
450  typename P5, typename P6, typename P7>
451  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
452  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
453  {
454  this->myDataPtr->signaled = true;
455  this->Cleanup();
456  for (typename EvtConnectionMap::iterator iter =
457  this->myDataPtr->connections.begin();
458  iter != this->myDataPtr->connections.end(); ++iter)
459  {
460  (*iter->second)(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
461  }
462  }
463 
473  public: template<typename P1, typename P2, typename P3, typename P4,
474  typename P5, typename P6, typename P7, typename P8>
475  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
476  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
477  const P8 &_p8)
478  {
479  this->myDataPtr->signaled = true;
480  this->Cleanup();
481  for (typename EvtConnectionMap::iterator iter =
482  this->myDataPtr->connections.begin();
483  iter != this->myDataPtr->connections.end(); ++iter)
484  {
485  (*iter->second)(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
486  }
487  }
488 
499  public: template< typename P1, typename P2, typename P3, typename P4,
500  typename P5, typename P6, typename P7, typename P8,
501  typename P9 >
502  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
503  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
504  const P8 &_p8, const P9 &_p9)
505  {
506  this->myDataPtr->signaled = true;
507  this->Cleanup();
508  for (typename EvtConnectionMap::iterator iter =
509  this->myDataPtr->connections.begin();
510  iter != this->myDataPtr->connections.end(); ++iter)
511  {
512  (*iter->second)(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
513  }
514  }
515 
527  public: template< typename P1, typename P2, typename P3, typename P4,
528  typename P5, typename P6, typename P7, typename P8,
529  typename P9, typename P10 >
530  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
531  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
532  const P8 &_p8, const P9 &_p9, const P10 &_p10)
533  {
534  this->myDataPtr->signaled = true;
535  this->Cleanup();
536  for (typename EvtConnectionMap::iterator iter =
537  this->myDataPtr->connections.begin();
538  iter != this->myDataPtr->connections.end(); ++iter)
539  {
540  (*iter->second)(_p1, _p2, _p3, _p4, _p5,
541  _p6, _p7, _p8, _p9, _p10);
542  }
543  }
544 
546  private: void Cleanup();
547 
549  private: EventTPrivate<T> *myDataPtr;
550  };
551 
553  template<typename T>
555  : Event(*(new EventTPrivate<T>()))
556  {
557  this->myDataPtr = static_cast<EventTPrivate<T>*>(this->dataPtr);
558  }
559 
561  template<typename T>
563  {
564  for (typename EvtConnectionMap::iterator iter =
565  this->myDataPtr->connections.begin();
566  iter != this->myDataPtr->connections.end(); ++iter)
567  {
568  delete iter->second;
569  }
570 
571  this->myDataPtr->connections.clear();
572  }
573 
576  template<typename T>
577  ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber)
578  {
579  int index = 0;
580  if (!this->myDataPtr->connections.empty())
581  {
582  typename EvtConnectionMap::reverse_iterator iter =
583  this->myDataPtr->connections.rbegin();
584  index = iter->first + 1;
585  }
586  this->myDataPtr->connections[index] = new boost::function<T>(_subscriber);
587  return ConnectionPtr(new Connection(this, index));
588  }
589 
592  template<typename T>
594  {
595  if (!_c)
596  return;
597 
598  this->Disconnect(_c->GetId());
599  _c->dataPtr->event = NULL;
600  _c->dataPtr->id = -1;
601  }
602 
605  template<typename T>
606  unsigned int EventT<T>::ConnectionCount() const
607  {
608  return this->myDataPtr->connections.size();
609  }
610 
613  template<typename T>
614  void EventT<T>::Disconnect(int _id)
615  {
616  boost::mutex::scoped_lock lock(this->myDataPtr->connectionsEraseMutex);
617  this->myDataPtr->connectionsToErase.push_back(_id);
618  }
619 
621  template<typename T>
622  void EventT<T>::Cleanup()
623  {
624  if (this->myDataPtr->connectionsToErase.empty())
625  return;
626  boost::mutex::scoped_lock lock(this->myDataPtr->connectionsEraseMutex);
627 
628  for (std::vector<int>::iterator iter =
629  this->myDataPtr->connectionsToErase.begin();
630  iter != this->myDataPtr->connectionsToErase.end(); ++iter)
631  {
632  typename EvtConnectionMap::iterator iter2 =
633  this->myDataPtr->connections.find(*iter);
634  if (iter2 != this->myDataPtr->connections.end())
635  {
636  delete iter2->second;
637  this->myDataPtr->connections.erase(iter2);
638  }
639  }
640  this->myDataPtr->connectionsToErase.clear();
641  }
643  }
644 }
645 #endif