Ignition Common

API Reference

3.9.0
Event.hh
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 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 #ifndef IGNITION_COMMON_EVENT_HH_
18 #define IGNITION_COMMON_EVENT_HH_
19 
20 #include <atomic>
21 #include <functional>
22 #include <list>
23 #include <map>
24 #include <memory>
25 #include <mutex>
26 #include <utility>
27 
28 #include <ignition/common/config.hh>
29 #include <ignition/common/events/Export.hh>
31 
32 namespace ignition
33 {
34  namespace common
35  {
38  class IGNITION_COMMON_EVENTS_VISIBLE Event
39  {
41  public: Event();
42 
44  public: virtual ~Event();
45 
48  public: virtual void Disconnect(int _id) = 0;
49 
52  public: bool Signaled() const;
53 
56  public: void SetSignaled(const bool _sig);
57 
59  private: bool signaled;
60  };
61 
63  class IGNITION_COMMON_EVENTS_VISIBLE Connection
64  {
68  public: Connection(Event *_e, const int _i);
69 
71  public: ~Connection();
72 
75  public: int Id() const;
76 
78  private: Event *event = nullptr;
79 
81  private: int id = -1;
82 
83 #ifdef _WIN32
84 // Disable warning C4251
85 #pragma warning(push)
86 #pragma warning(disable: 4251)
87 #endif
90 #ifdef _WIN32
91 #pragma warning(pop)
92 #endif
93 
95  public: template<typename T, typename N> friend class EventT;
96  };
97 
102  template<typename T, typename N = void>
103  class EventT : public Event
104  {
105  public: using CallbackT = std::function<T>;
107  "Event callback must have void return type");
108 
110  public: EventT();
111 
113  public: virtual ~EventT();
114 
119  public: ConnectionPtr Connect(const CallbackT &_subscriber);
120 
123  public: virtual void Disconnect(int _id);
124 
127  public: unsigned int ConnectionCount() const;
128 
130  public: template<typename ... Args>
131  void operator()(Args && ... args)
132  {
133  this->Signal(std::forward<Args>(args)...);
134  }
135 
137  public: template <typename ... Args>
138  void Signal(Args && ... args)
139  {
140  this->Cleanup();
141 
142  this->SetSignaled(true);
143  for (const auto &iter : this->connections)
144  {
145  if (iter.second->on)
146  iter.second->callback(std::forward<Args>(args)...);
147  }
148  }
149 
153  private: void Cleanup();
154 
156  private: class EventConnection
157  {
159  public: EventConnection(const bool _on, const std::function<T> &_cb)
160  : callback(_cb)
161  {
162  // Windows Visual Studio 2012 does not have atomic_bool constructor,
163  // so we have to set "on" using operator=
164  this->on = _on;
165  }
166 
168  public: std::atomic_bool on;
169 
171  public: std::function<T> callback;
172  };
173 
177 
179  private: EvtConnectionMap connections;
180 
182  private: std::mutex mutex;
183 
186  connectionsToRemove;
187  };
188 
190  template<typename T, typename N>
192  : Event()
193  {
194  }
195 
197  template<typename T, typename N>
199  {
200  this->connections.clear();
201  }
202 
205  template<typename T, typename N>
207  {
208  int index = 0;
209  if (!this->connections.empty())
210  {
211  auto const &iter = this->connections.rbegin();
212  index = iter->first + 1;
213  }
214  this->connections[index].reset(new EventConnection(true, _subscriber));
215  return ConnectionPtr(new Connection(this, index));
216  }
217 
220  template<typename T, typename N>
221  unsigned int EventT<T, N>::ConnectionCount() const
222  {
223  return this->connections.size();
224  }
225 
228  template<typename T, typename N>
230  {
231  // Find the connection
232  auto const &it = this->connections.find(_id);
233 
234  if (it != this->connections.end())
235  {
236  it->second->on = false;
237  this->connectionsToRemove.push_back(it);
238  }
239  }
240 
242  template<typename T, typename N>
243  void EventT<T, N>::Cleanup()
244  {
245  std::lock_guard<std::mutex> lock(this->mutex);
246  // Remove all queue connections.
247  for (auto &conn : this->connectionsToRemove)
248  this->connections.erase(conn);
249  this->connectionsToRemove.clear();
250  }
251  }
252 }
253 #endif
T empty(T... args)
void Signal(Args &&... args)
Signal the event for all subscribers.
Definition: Event.hh:138
A class that encapsulates a connection.
Definition: Event.hh:63
virtual ~EventT()
Destructor.
Definition: Event.hh:198
ConnectionPtr Connect(const CallbackT &_subscriber)
Connect a callback to this event.
Definition: Event.hh:206
T end(T... args)
Base class for all events.
Definition: Event.hh:38
STL class.
EventT()
Constructor.
Definition: Event.hh:191
T push_back(T... args)
T erase(T... args)
unsigned int ConnectionCount() const
Get the number of connections.
Definition: Event.hh:221
T clear(T... args)
virtual void Disconnect(int _id)
Disconnect a callback to this event.
Definition: Event.hh:229
void operator()(Args &&... args)
Access the signal.
Definition: Event.hh:131
T find(T... args)
T size(T... args)
std::shared_ptr< Connection > ConnectionPtr
Definition: events/include/ignition/common/events/Types.hh:32
A class for event processing.
Definition: Event.hh:103
Forward declarations for the common classes.
T rbegin(T... args)