libosmscout
1.1.1
Toggle main menu visibility
Loading...
Searching...
No Matches
libosmscout
include
osmscout
async
Signal.h
Go to the documentation of this file.
1
#ifndef LIBOSMSCOUT_SIGNAL_H
2
#define LIBOSMSCOUT_SIGNAL_H
3
4
/*
5
This source is part of the libosmscout library
6
Copyright (C) 2023 Lukas Karas
7
8
This library is free software; you can redistribute it and/or
9
modify it under the terms of the GNU Lesser General Public
10
License as published by the Free Software Foundation; either
11
version 2.1 of the License, or (at your option) any later version.
12
13
This library is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
Lesser General Public License for more details.
17
18
You should have received a copy of the GNU Lesser General Public
19
License along with this library; if not, write to the Free Software
20
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
*/
22
23
#include <
osmscout/lib/CoreImportExport.h
>
24
25
#include <functional>
26
#include <mutex>
27
#include <set>
28
#include <memory>
29
#include <vector>
30
31
namespace
osmscout
{
32
33
template
<
typename
... Args>
34
class
Slot
;
35
45
template
<
typename
... Args>
46
class
Signal
47
{
48
private
:
49
struct
Connection
50
{
51
// Note: when just signal or slot is locked, always lock connection when accessing it
52
mutable
std::mutex mutex;
53
Slot
<Args...>* slot =
nullptr
;
54
Signal
<Args...>* signal =
nullptr
;
55
};
56
57
private
:
58
// Note: when signal and slot mutexes are locked at the same time, always lock signal's one first
59
mutable
std::mutex mutex;
60
std::vector<std::shared_ptr<Connection>> connections;
61
62
public
:
63
friend
class
Slot
<Args...>;
64
65
Signal
() =
default
;
66
Signal
(
const
Signal
&) =
delete
;
67
Signal
(
Signal
&&) =
delete
;
68
69
Signal
&
operator=
(
const
Signal
&) =
delete
;
70
Signal
&
operator=
(
Signal
&&) =
delete
;
71
72
virtual
~Signal
();
73
78
void
Emit
(
const
Args&... args)
const
;
79
83
void
Connect
(
Slot<Args...>
&slot);
84
89
void
Disconnect
(
Slot<Args...>
&slot);
90
93
void
Disconnect
();
94
};
95
96
template
<
typename
... Args>
97
class
Slot
98
{
99
private
:
100
// Note: when signal and slot mutexes are locked at the same time, always lock signal's one first
101
mutable
std::mutex mutex;
102
const
std::function<void(
const
Args&...)> callback;
103
std::vector<std::shared_ptr<
typename
Signal
<Args...>::Connection>> connections;
104
105
public
:
106
friend
class
Signal
<Args...>;
107
111
explicit
Slot
(
const
std::function<
void
(
const
Args&...)> &callback);
112
113
Slot
(
const
Slot
&) =
delete
;
114
Slot
(
Slot
&&) =
delete
;
115
116
Slot
&
operator=
(
const
Slot
&) =
delete
;
117
Slot
&
operator=
(
Slot
&&) =
delete
;
118
119
virtual
~Slot
();
120
123
void
Disconnect
();
124
125
private
:
130
void
Call(
const
Args&... args)
const
;
131
};
132
133
template
<
typename
... Args>
134
Slot<Args...>::Slot
(
const
std::function<
void
(
const
Args&...)> &callback):
135
callback(callback)
136
{}
137
138
template
<
typename
... Args>
139
void
Slot<Args...>::Call(
const
Args&... args)
const
140
{
141
callback(args...);
142
}
143
144
template
<
typename
... Args>
145
void
Signal<Args...>::Emit
(
const
Args&... args)
const
146
{
147
std::unique_lock lock(mutex);
148
for
(
const
auto
&con: connections) {
149
std::unique_lock lockCon(con->mutex);
150
if
(
auto
slot = con->slot; slot !=
nullptr
) {
151
slot->Call(args...);
152
}
153
}
154
}
155
156
template
<
typename
... Args>
157
void
Signal<Args...>::Connect
(
Slot<Args...>
&slot)
158
{
159
std::unique_lock lock(mutex);
160
std::unique_lock slotLock(slot.mutex);
161
162
auto
con=std::make_shared<Connection>();
163
con->slot = &slot;
164
con->signal =
this
;
165
connections.push_back(con);
166
slot.connections.push_back(con);
167
}
168
169
template
<
typename
... Args>
170
void
Signal<Args...>::Disconnect
(
Slot<Args...>
&slot)
171
{
172
std::unique_lock lock(mutex);
173
std::unique_lock slotLock(slot.mutex);
174
175
if
(
auto
it = connections.find([&slot](
auto
const
&con) ->
bool
{ return con && con->slot == &slot; });
176
it != connections.end()) {
177
connections.erase(it);
178
}
179
if
(
auto
it = slot.connections.find([
this
](
auto
const
&con) ->
bool
{ return con && con->signal == this; });
180
it != slot.connections.end()) {
181
slot.connections.erase(it);
182
}
183
}
184
185
template
<
typename
... Args>
186
void
Signal<Args...>::Disconnect
()
187
{
188
std::unique_lock lock(mutex);
189
for
(
auto
&con: connections) {
190
std::unique_lock lockCon(con->mutex);
191
con->signal =
nullptr
;
192
con->slot =
nullptr
;
193
}
194
connections.clear();
195
}
196
197
template
<
typename
... Args>
198
void
Slot<Args...>::Disconnect
()
199
{
200
std::unique_lock lock(mutex);
201
for
(
auto
&con: connections) {
202
std::unique_lock lockCon(con->mutex);
203
con->signal =
nullptr
;
204
con->slot =
nullptr
;
205
}
206
connections.clear();
207
}
208
209
template
<
typename
... Args>
210
Signal<Args...>::~Signal
() {
211
Disconnect
();
212
}
213
214
template
<
typename
... Args>
215
Slot<Args...>::~Slot
() {
216
Disconnect
();
217
}
218
219
}
// namespace
220
221
#endif
//LIBOSMSCOUT_SIGNAL_H
CoreImportExport.h
osmscout::Signal
Definition
Signal.h:47
osmscout::Signal::Connect
void Connect(Slot< Args... > &slot)
Definition
Signal.h:157
osmscout::Signal::Signal
Signal(Signal &&)=delete
osmscout::Signal::Disconnect
void Disconnect()
Definition
Signal.h:186
osmscout::Signal::operator=
Signal & operator=(const Signal &)=delete
osmscout::Signal::Emit
void Emit(const Args &... args) const
Definition
Signal.h:145
osmscout::Signal::operator=
Signal & operator=(Signal &&)=delete
osmscout::Signal::Disconnect
void Disconnect(Slot< Args... > &slot)
Definition
Signal.h:170
osmscout::Signal::Signal
Signal()=default
osmscout::Signal::Signal
Signal(const Signal &)=delete
osmscout::Signal::~Signal
virtual ~Signal()
Definition
Signal.h:210
osmscout::Slot
Definition
Signal.h:98
osmscout::Slot::~Slot
virtual ~Slot()
Definition
Signal.h:215
osmscout::Slot::operator=
Slot & operator=(const Slot &)=delete
osmscout::Slot::Disconnect
void Disconnect()
Definition
Signal.h:198
osmscout::Slot::Slot
Slot(const std::function< void(const Args &...)> &callback)
Definition
Signal.h:134
osmscout::Slot::operator=
Slot & operator=(Slot &&)=delete
osmscout::Slot::Slot
Slot(const Slot &)=delete
osmscout::Slot::Slot
Slot(Slot &&)=delete
osmscout
Definition
Area.h:39
Generated by
1.17.0