sandbox
Loading...
Searching...
No Matches
connection.hpp
1#ifndef LIBSBX_SIGNAL_CONNECTION_HPP_
2#define LIBSBX_SIGNAL_CONNECTION_HPP_
3
4#include <memory>
5
6#include <libsbx/signals/lockable.hpp>
7#include <libsbx/signals/slot_state.hpp>
8
9namespace sbx::signals {
10
12
13 friend class connection;
14
15public:
16
17 connection_blocker() = default;
18
19 connection_blocker(const connection_blocker& other) = delete;
20
22 : _state{std::move(other._state)} { }
23
24 ~connection_blocker() noexcept {
25 release();
26 }
27
28 auto operator=(const connection_blocker& other) -> connection_blocker& = delete;
29
30 auto operator=(connection_blocker&& other) noexcept -> connection_blocker& {
31 release();
32 _state.swap(other._state);
33
34 return *this;
35 }
36
37private:
38
39 explicit connection_blocker(std::weak_ptr<slot_state> state) noexcept
40 : _state{std::move(state)} {
41 if (auto state = _state.lock()) {
42 state->block();
43 }
44 }
45
46 void release() noexcept {
47 if (auto state = _state.lock()) {
48 state->unblock();
49 }
50 }
51
52private:
53
54 std::weak_ptr<slot_state> _state;
55
56}; // class connection_blocker
57
59
60 template<lockable, typename...>
61 friend class signal_base;
62
63public:
64
65 connection() = default;
66
67 connection(const connection&) noexcept = default;
68
69 connection(connection&&) noexcept = default;
70
71 virtual ~connection() = default;
72
73 auto operator=(const connection& other) noexcept -> connection& = default;
74
75 auto operator=(connection&& other) noexcept -> connection& = default;
76
77 bool is_valid() const noexcept {
78 return !_state.expired();
79 }
80
81 bool is_connected() const noexcept {
82 const auto state = _state.lock();
83 return state && state->is_connected();
84 }
85
86 bool disconnect() noexcept {
87 auto state = _state.lock();
88 return state && state->disconnect();
89 }
90
91 bool is_blocked() const noexcept {
92 const auto state = _state.lock();
93 return state && state->is_blocked();
94 }
95
96 void block() noexcept {
97 if (auto state = _state.lock()) {
98 state->block();
99 }
100 }
101
102 void unblock() noexcept {
103 if (auto state = _state.lock()) {
104 state->unblock();
105 }
106 }
107
108 auto blocker() const noexcept -> connection_blocker {
109 return connection_blocker{_state};
110 }
111
112protected:
113
114 explicit connection(std::weak_ptr<slot_state> state) noexcept
115 : _state{std::move(state)} { }
116
117 std::weak_ptr<slot_state> _state;
118
119}; // class connection
120
121class scoped_connection final : public connection {
122
123 template <lockable, typename...>
124 friend class signal_base;
125
126public:
127 scoped_connection() = default;
128
129 scoped_connection(const connection& c) noexcept
130 : connection{c} { }
131
132 scoped_connection(connection&& c) noexcept
133 : connection{std::move(c)} { }
134
135 scoped_connection(const scoped_connection& other) noexcept = delete;
136
137 scoped_connection(scoped_connection&& other) noexcept
138 : connection{std::move(other._state)} { }
139
140 ~scoped_connection() override {
141 disconnect();
142 }
143
144 auto operator=(const scoped_connection& other) noexcept -> scoped_connection& = delete;
145
146 auto operator=(scoped_connection&& other) noexcept -> scoped_connection& {
147 disconnect();
148 _state.swap(other._state);
149 return *this;
150 }
151
152private:
153
154 explicit scoped_connection(std::weak_ptr<slot_state> state) noexcept
155 : connection{std::move(state)} { }
156
157}; // class scoped_connection
158
159} // namespace sbx::signals
160
161#endif // LIBSBX_SIGNAL_CONNECTION_HPP_
Definition: connection.hpp:11
Definition: connection.hpp:58
Definition: connection.hpp:121
Definition: signal.hpp:16