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