Event.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012-2015 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 _GAZEBO_EVENT_HH_
19 #define _GAZEBO_EVENT_HH_
20 
21 #include <atomic>
22 #include <iostream>
23 #include <vector>
24 #include <map>
25 #include <memory>
26 #include <mutex>
27 #include <list>
28 
29 #include <boost/function.hpp>
30 #include <boost/bind.hpp>
31 
32 #include <gazebo/gazebo_config.h>
33 #include <gazebo/common/Time.hh>
35 #include <gazebo/math/Helpers.hh>
36 #include "gazebo/util/system.hh"
37 
38 namespace gazebo
39 {
42  namespace event
43  {
46 
48  // Private data members for Event class.
49  // This must be in the header due to templatization.
51  {
52  // \brief Constructor
53  public: EventPrivate();
54 
56  public: bool signaled;
57  };
58 
62  {
64  public: Event();
65 
67  public: virtual ~Event();
68 
71  public: virtual void Disconnect(ConnectionPtr _c) = 0;
72 
75  public: virtual void Disconnect(int _id) = 0;
76 
79  public: bool GetSignaled() const;
80 
83  protected: Event(EventPrivate &_d);
84 
86  protected: EventPrivate *dataPtr;
87  };
88 
90  // Private data members for Connection class.
92  {
94  public: ConnectionPrivate();
95 
99  public: ConnectionPrivate(Event *_e, int _i);
100 
102  public: Event *event;
103 
105  public: int id;
106 
109  };
110 
113  {
115  public: Connection();
116 
120  public: Connection(Event *_e, int _i);
121 
123  public: ~Connection();
124 
127  public: int GetId() const;
128 
130  private: ConnectionPrivate *dataPtr;
131 
133  public: template<typename T> friend class EventT;
134  };
135 
137  template<typename T>
139  {
141  public: EventConnection(const bool _on,
142  boost::function<T> *_cb)
143  : on(_on), callback(_cb)
144  {
145  }
146 
148  public: std::atomic_bool on;
149 
151  public: std::shared_ptr<boost::function<T> > callback;
152  };
153 
155  // Private data members for EventT<T> class.
156  template< typename T>
158  {
161  typedef std::map<int, std::shared_ptr<EventConnection<T> > >
162  EvtConnectionMap;
163 
165  public: EvtConnectionMap connections;
166 
168  public: std::mutex mutex;
169 
171  public: std::list<typename EvtConnectionMap::const_iterator>
173  };
174 
177  template< typename T>
178  class EventT : public Event
179  {
181  public: EventT();
182 
184  public: virtual ~EventT();
185 
190  public: ConnectionPtr Connect(const boost::function<T> &_subscriber);
191 
194  public: virtual void Disconnect(ConnectionPtr _c);
195 
198  public: virtual void Disconnect(int _id);
199 
202  public: unsigned int ConnectionCount() const;
203 
205  public: void operator()()
206  {this->Signal();}
207 
210  public: template< typename P >
211  void operator()(const P &_p)
212  {
213  this->Signal(_p);
214  }
215 
219  public: template< typename P1, typename P2 >
220  void operator()(const P1 &_p1, const P2 &_p2)
221  {
222  this->Signal(_p1, _p2);
223  }
224 
229  public: template< typename P1, typename P2, typename P3 >
230  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
231  {
232  this->Signal(_p1, _p2, _p3);
233  }
234 
240  public: template< typename P1, typename P2, typename P3, typename P4 >
241  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
242  const P4 &_p4)
243  {
244  this->Signal(_p1, _p2, _p3, _p4);
245  }
246 
253  public: template< typename P1, typename P2, typename P3, typename P4,
254  typename P5 >
255  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
256  const P4 &_p4, const P5 &_p5)
257  {
258  this->Signal(_p1, _p2, _p3, _p4, _p5);
259  }
260 
268  public: template< typename P1, typename P2, typename P3, typename P4,
269  typename P5, typename P6 >
270  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
271  const P4 &_p4, const P5 &_p5, const P6 &_p6)
272  {
273  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6);
274  }
275 
284  public: template< typename P1, typename P2, typename P3, typename P4,
285  typename P5, typename P6, typename P7 >
286  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
287  const P4 &_p4, const P5 &_p5, const P6 &_p6,
288  const P7 &_p7)
289  {
290  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
291  }
292 
302  public: template< typename P1, typename P2, typename P3, typename P4,
303  typename P5, typename P6, typename P7, typename P8 >
304  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
305  const P4 &_p4, const P5 &_p5, const P6 &_p6,
306  const P7 &_p7, const P8 &_p8)
307  {
308  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
309  }
310 
321  public: template< typename P1, typename P2, typename P3, typename P4,
322  typename P5, typename P6, typename P7, typename P8,
323  typename P9 >
324  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
325  const P4 &_p4, const P5 &_p5, const P6 &_p6,
326  const P7 &_p7, const P8 &_p8, const P9 &_p9)
327  {
328  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
329  }
330 
342  public: template< typename P1, typename P2, typename P3, typename P4,
343  typename P5, typename P6, typename P7, typename P8,
344  typename P9, typename P10 >
345  void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3,
346  const P4 &_p4, const P5 &_p5, const P6 &_p6,
347  const P7 &_p7, const P8 &_p8, const P9 &_p9,
348  const P10 &_p10)
349  {
350  this->Signal(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
351  }
352 
354  public: void Signal()
355  {
356  this->Cleanup();
357 
358  this->myDataPtr->signaled = true;
359  for (auto iter: this->myDataPtr->connections)
360  {
361  if (iter.second->on)
362  (*iter.second->callback)();
363  }
364  }
365 
368  public: template< typename P >
369  void Signal(const P &_p)
370  {
371  this->Cleanup();
372 
373  this->myDataPtr->signaled = true;
374  for (auto iter: this->myDataPtr->connections)
375  {
376  if (iter.second->on)
377  (*iter.second->callback)(_p);
378  }
379  }
380 
384  public: template< typename P1, typename P2 >
385  void Signal(const P1 &_p1, const P2 &_p2)
386  {
387  this->Cleanup();
388 
389  this->myDataPtr->signaled = true;
390  for (auto iter: this->myDataPtr->connections)
391  {
392  if (iter.second->on)
393  (*iter.second->callback)(_p1, _p2);
394  }
395  }
396 
401  public: template< typename P1, typename P2, typename P3 >
402  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
403  {
404  this->Cleanup();
405 
406  this->myDataPtr->signaled = true;
407  for (auto iter: this->myDataPtr->connections)
408  {
409  if (iter.second->on)
410  (*iter.second->callback)(_p1, _p2, _p3);
411  }
412  }
413 
419  public: template<typename P1, typename P2, typename P3, typename P4>
420  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
421  const P4 &_p4)
422  {
423  this->Cleanup();
424 
425  this->myDataPtr->signaled = true;
426  for (auto iter: this->myDataPtr->connections)
427  {
428  if (iter.second->on)
429  (*iter.second->callback)(_p1, _p2, _p3, _p4);
430  }
431  }
432 
439  public: template<typename P1, typename P2, typename P3, typename P4,
440  typename P5>
441  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
442  const P4 &_p4, const P5 &_p5)
443  {
444  this->Cleanup();
445 
446  this->myDataPtr->signaled = true;
447  for (auto iter: this->myDataPtr->connections)
448  {
449  if (iter.second->on)
450  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5);
451  }
452  }
453 
461  public: template<typename P1, typename P2, typename P3, typename P4,
462  typename P5, typename P6>
463  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
464  const P4 &_p4, const P5 &_p5, const P6 &_p6)
465  {
466  this->Cleanup();
467 
468  this->myDataPtr->signaled = true;
469  for (auto iter: this->myDataPtr->connections)
470  {
471  if (iter.second->on)
472  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6);
473  }
474  }
475 
484  public: template<typename P1, typename P2, typename P3, typename P4,
485  typename P5, typename P6, typename P7>
486  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
487  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
488  {
489  this->Cleanup();
490 
491  this->myDataPtr->signaled = true;
492  for (auto iter: this->myDataPtr->connections.begin())
493  {
494  if (iter.second->on)
495  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6, _p7);
496  }
497  }
498 
508  public: template<typename P1, typename P2, typename P3, typename P4,
509  typename P5, typename P6, typename P7, typename P8>
510  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
511  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
512  const P8 &_p8)
513  {
514  this->Cleanup();
515 
516  this->myDataPtr->signaled = true;
517  for (auto iter: this->myDataPtr->connections)
518  {
519  if (iter.second->on)
520  {
521  (*iter.second->callback)(_p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8);
522  }
523  }
524  }
525 
536  public: template< typename P1, typename P2, typename P3, typename P4,
537  typename P5, typename P6, typename P7, typename P8,
538  typename P9 >
539  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
540  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
541  const P8 &_p8, const P9 &_p9)
542  {
543  this->Cleanup();
544 
545  this->myDataPtr->signaled = true;
546  for (auto iter: this->myDataPtr->connections)
547  {
548  if (iter.second->on)
549  {
550  (*iter.second->callback)(
551  _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9);
552  }
553  }
554  }
555 
567  public: template< typename P1, typename P2, typename P3, typename P4,
568  typename P5, typename P6, typename P7, typename P8,
569  typename P9, typename P10 >
570  void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3,
571  const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7,
572  const P8 &_p8, const P9 &_p9, const P10 &_p10)
573  {
574  this->Cleanup();
575 
576  this->myDataPtr->signaled = true;
577  for (auto iter: this->myDataPtr->connections)
578  {
579  if (iter.second->on)
580  {
581  (*iter.second->callback)(
582  _p1, _p2, _p3, _p4, _p5, _p6, _p7, _p8, _p9, _p10);
583  }
584  }
585  }
586 
590  private: void Cleanup();
591 
593  private: EventTPrivate<T> *myDataPtr;
594  };
595 
597  template<typename T>
599  : Event(*(new EventTPrivate<T>()))
600  {
601  this->myDataPtr = static_cast<EventTPrivate<T>*>(this->dataPtr);
602  }
603 
605  template<typename T>
607  {
608  this->myDataPtr->connections.clear();
609  }
610 
613  template<typename T>
614  ConnectionPtr EventT<T>::Connect(const boost::function<T> &_subscriber)
615  {
616  int index = 0;
617  if (!this->myDataPtr->connections.empty())
618  {
619  auto const &iter = this->myDataPtr->connections.rbegin();
620  index = iter->first + 1;
621  }
622  this->myDataPtr->connections[index].reset(new EventConnection<T>(true,
623  new boost::function<T>(_subscriber)));
624  return ConnectionPtr(new Connection(this, index));
625  }
626 
629  template<typename T>
631  {
632  if (!_c)
633  return;
634 
635  this->Disconnect(_c->GetId());
636  _c->dataPtr->event = NULL;
637  _c->dataPtr->id = -1;
638  }
639 
642  template<typename T>
643  unsigned int EventT<T>::ConnectionCount() const
644  {
645  return this->myDataPtr->connections.size();
646  }
647 
650  template<typename T>
651  void EventT<T>::Disconnect(int _id)
652  {
653  // Find the connection
654  auto const &it = this->myDataPtr->connections.find(_id);
655 
656  if (it != this->myDataPtr->connections.end())
657  {
658  it->second->on = false;
659  this->myDataPtr->connectionsToRemove.push_back(it);
660  }
661  }
662 
664  template<typename T>
665  void EventT<T>::Cleanup()
666  {
667  std::lock_guard<std::mutex> lock(this->myDataPtr->mutex);
668  // Remove all queue connections.
669  for (auto &conn : this->myDataPtr->connectionsToRemove)
670  this->myDataPtr->connections.erase(conn);
671  this->myDataPtr->connectionsToRemove.clear();
672  }
673 
675  }
676 }
677 #endif
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8, const P9 &_p9)
Signal the event with nine parameter.
Definition: Event.hh:539
boost::shared_ptr< Connection > ConnectionPtr
Definition: CommonTypes.hh:147
Base class for all events.
Definition: Event.hh:61
std::list< typename EvtConnectionMap::const_iterator > connectionsToRemove
List of connections to remove.
Definition: Event.hh:172
A class that encapsulates a connection.
Definition: Event.hh:112
EventPrivate * dataPtr
Data pointer.
Definition: Event.hh:86
Definition: Event.hh:50
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
Signal the event with seven parameter.
Definition: Event.hh:486
std::shared_ptr< boost::function< T > > callback
Callback function.
Definition: Event.hh:151
virtual void Disconnect(ConnectionPtr _c)
Disconnect a callback to this event.
Definition: Event.hh:630
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameter.
Definition: Event.hh:420
Definition: Event.hh:138
void Signal()
Signal the event for all subscribers.
Definition: Event.hh:354
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5)
Signal the event with five parameter.
Definition: Event.hh:441
Definition: Event.hh:157
void operator()(const P &_p)
Signal the event with one parameter.
Definition: Event.hh:211
int id
the id set in the constructor
Definition: Event.hh:105
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameters.
Definition: Event.hh:230
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7)
Signal the event with seven parameters.
Definition: Event.hh:286
EventConnection(const bool _on, boost::function< T > *_cb)
Constructor.
Definition: Event.hh:141
Event * event
the event for this connection
Definition: Event.hh:102
std::mutex mutex
A thread lock.
Definition: Event.hh:168
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5)
Signal the event with five parameters.
Definition: Event.hh:255
void operator()(const P1 &_p1, const P2 &_p2)
Signal the event with two parameters.
Definition: Event.hh:220
virtual ~EventT()
Destructor.
Definition: Event.hh:606
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3)
Signal the event with three parameter.
Definition: Event.hh:402
EvtConnectionMap connections
Array of connection callbacks.
Definition: Event.hh:165
void Signal(const P1 &_p1, const P2 &_p2)
Signal the event with two parameter.
Definition: Event.hh:385
#define GZ_COMMON_VISIBLE
Definition: system.hh:91
bool signaled
True if the event has been signaled.
Definition: Event.hh:56
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8)
Signal the event with eight parameters.
Definition: Event.hh:304
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8)
Signal the event with eight parameter.
Definition: Event.hh:510
void Signal(const P &_p)
Signal the event with one parameter.
Definition: Event.hh:369
std::atomic_bool on
On/off value for the event callback.
Definition: Event.hh:148
ConnectionPtr Connect(const boost::function< T > &_subscriber)
Connect a callback to this event.
Definition: Event.hh:614
void operator()()
Access the signal.
Definition: Event.hh:205
common::Time creationTime
set during the constructor
Definition: Event.hh:108
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8, const P9 &_p9)
Signal the event with nine parameters.
Definition: Event.hh:324
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8, const P9 &_p9, const P10 &_p10)
Signal the event with ten parameter.
Definition: Event.hh:570
#define NULL
Definition: CommonTypes.hh:30
Definition: Event.hh:91
A class for event processing.
Definition: Event.hh:178
unsigned int ConnectionCount() const
Get the number of connections.
Definition: Event.hh:643
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4)
Signal the event with four parameters.
Definition: Event.hh:241
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6)
Signal the event with six parameters.
Definition: Event.hh:270
void Signal(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6)
Signal the event with six parameter.
Definition: Event.hh:463
void operator()(const P1 &_p1, const P2 &_p2, const P3 &_p3, const P4 &_p4, const P5 &_p5, const P6 &_p6, const P7 &_p7, const P8 &_p8, const P9 &_p9, const P10 &_p10)
Signal the event with ten parameters.
Definition: Event.hh:345
A Time class, can be used to hold wall- or sim-time.
Definition: Time.hh:39
EventT()
Constructor.
Definition: Event.hh:598