properties-cpp  0.0.1
A very simple convenience library for handling properties and signals in C++11.
connection.h
Go to the documentation of this file.
1 /*
2  * Copyright © 2013 Canonical Ltd.
3  *
4  * This program is free software: you can redistribute it and/or modify it
5  * under the terms of the GNU Lesser General Public License version 3,
6  * as published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * Authored by: Thomas Voß <thomas.voss@canonical.com>
17  */
18 #ifndef COM_UBUNTU_CONNECTION_H_
19 #define COM_UBUNTU_CONNECTION_H_
20 
21 #include <functional>
22 #include <memory>
23 #include <mutex>
24 
25 namespace core
26 {
27 class ScopedConnection;
32 {
33 public:
34  typedef std::function<void(const std::function<void()>&)> Dispatcher;
35 
40  inline bool is_connected() const
41  {
42  if (!d)
43  return false;
44 
45  return (d->disconnector ? true : false);
46  }
47 
51  inline void disconnect()
52  {
53  if (d)
54  d->disconnect();
55  }
56 
61  inline void dispatch_via(const Dispatcher& dispatcher)
62  {
63  if (d && d->dispatcher_installer)
64  d->dispatcher_installer(dispatcher);
65  }
66 
67 private:
68  friend class ScopedConnection;
69 
70  typedef std::function<void()> Disconnector;
71  typedef std::function<void(const Dispatcher&)> DispatcherInstaller;
72 
73  template<typename ... Arguments> friend class Signal;
74 
75  inline Connection(const Disconnector& disconnector,
76  const DispatcherInstaller& installer)
77  : d(std::make_shared<Private>(disconnector, installer))
78  {
79  }
80 
81  inline bool operator<(const Connection& rhs) const
82  {
83  return d < rhs.d;
84  }
85 
86  inline void reset()
87  {
88  if (d)
89  d->reset();
90  }
91 
92  struct Private
93  {
94  Private(const Connection::Disconnector& disconnector,
95  const Connection::DispatcherInstaller& dispatcher_installer)
96  : disconnector(disconnector),
97  dispatcher_installer(dispatcher_installer)
98  {
99  }
100 
101  inline void reset()
102  {
103  std::lock_guard<std::mutex> lg(guard);
104  reset_locked();
105  }
106 
107  inline void reset_locked()
108  {
109  static const Connection::Disconnector empty_disconnector{};
110  static const Connection::DispatcherInstaller empty_dispatcher_installer{};
111 
112  disconnector = empty_disconnector;
113  dispatcher_installer = empty_dispatcher_installer;
114  }
115 
116  inline void disconnect()
117  {
118  static const Connection::Disconnector empty_disconnector{};
119 
120  std::lock_guard<std::mutex> lg(guard);
121 
122  if (disconnector)
123  disconnector();
124 
125  reset_locked();
126  }
127 
128  std::mutex guard;
129  Connection::Disconnector disconnector;
130  Connection::DispatcherInstaller dispatcher_installer;
131  };
132 
133  // The whole class is implicitly shared and we thus forward our complete
134  // shared state to a private structure that is lifetime-managed by a shared_ptr.
135  std::shared_ptr<Private> d;
136 };
137 
142 {
143 public:
148  inline ScopedConnection(const Connection& c) : connection(c)
149  {
150  }
151 
152  inline ScopedConnection(ScopedConnection&& rhs) : connection(std::move(rhs.connection))
153  {
154  }
155 
157 
161  inline ~ScopedConnection() noexcept(true)
162  {
163  try
164  {
165  connection.disconnect();
166  } catch(...)
167  {
168  }
169  }
170 
172  {
173  connection = std::move(rhs.connection);
174  return *this;
175  }
176 
178  bool operator==(const ScopedConnection&) = delete;
179 
180  inline bool operator<(const ScopedConnection& rhs) const
181  {
182  return connection < rhs.connection;
183  }
184 
185 private:
186  Connection connection;
187 };
188 }
189 
190 #endif // COM_UBUNTU_CONNECTION_H_
The Connection class models a signal-slot connection.
Definition: connection.h:32
void dispatch_via(const Dispatcher &dispatcher)
Installs a dispatcher for this signal-slot connection.
Definition: connection.h:61
void disconnect()
End a signal-slot connection.
Definition: connection.h:51
bool is_connected() const
Checks if this instance corresponds to an active signal-slot connection.
Definition: connection.h:40
std::function< void(const std::function< void()> &)> Dispatcher
Definition: connection.h:34
Scoped helper class to map signal-slot connection mgmt. to RAII.
Definition: connection.h:142
ScopedConnection(const ScopedConnection &)=delete
ScopedConnection(const Connection &c)
Constructs an instance for an existing signal-slot connection.
Definition: connection.h:148
ScopedConnection & operator=(const ScopedConnection &)=delete
ScopedConnection & operator=(ScopedConnection &&rhs)
Definition: connection.h:171
bool operator==(const ScopedConnection &)=delete
~ScopedConnection() noexcept(true)
Disconnects the signal-slot connection.
Definition: connection.h:161
bool operator<(const ScopedConnection &rhs) const
Definition: connection.h:180
ScopedConnection(ScopedConnection &&rhs)
Definition: connection.h:152
A signal class that observers can subscribe to.
Definition: signal.h:37