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