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;
31 class Connection
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
141 class ScopedConnection
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
156 ScopedConnection(const ScopedConnection&) = delete;
157
161 inline ~ScopedConnection() noexcept(true)
162 {
163 try
164 {
165 connection.disconnect();
166 } catch(...)
167 {
168 }
169 }
170
171 inline ScopedConnection& operator=(ScopedConnection&& rhs)
172 {
173 connection = std::move(rhs.connection);
174 return *this;
175 }
176
177 ScopedConnection& operator=(const ScopedConnection&) = delete;
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_
core::Connection
The Connection class models a signal-slot connection.
Definition: connection.h:32
core::Connection::dispatch_via
void dispatch_via(const Dispatcher &dispatcher)
Installs a dispatcher for this signal-slot connection.
Definition: connection.h:61
core::Connection::disconnect
void disconnect()
End a signal-slot connection.
Definition: connection.h:51
core::Connection::is_connected
bool is_connected() const
Checks if this instance corresponds to an active signal-slot connection.
Definition: connection.h:40
core::Connection::Dispatcher
std::function< void(const std::function< void()> &)> Dispatcher
Definition: connection.h:34
core::ScopedConnection
Scoped helper class to map signal-slot connection mgmt. to RAII.
Definition: connection.h:142
core::ScopedConnection::ScopedConnection
ScopedConnection(const ScopedConnection &)=delete
core::ScopedConnection::ScopedConnection
ScopedConnection(const Connection &c)
Constructs an instance for an existing signal-slot connection.
Definition: connection.h:148
core::ScopedConnection::operator=
ScopedConnection & operator=(const ScopedConnection &)=delete
core::ScopedConnection::operator==
bool operator==(const ScopedConnection &)=delete
core::ScopedConnection::~ScopedConnection
~ScopedConnection() noexcept(true)
Disconnects the signal-slot connection.
Definition: connection.h:161
core::ScopedConnection::operator<
bool operator<(const ScopedConnection &rhs) const
Definition: connection.h:180
core::ScopedConnection::operator=
ScopedConnection & operator=(ScopedConnection &&rhs)
Definition: connection.h:171
core::ScopedConnection::ScopedConnection
ScopedConnection(ScopedConnection &&rhs)
Definition: connection.h:152
core::Signal
A signal class that observers can subscribe to.
Definition: signal.h:37
core
Definition: connection.h:26