VCCC  2024.05
VisualCamp Common C++ library
connection.h
Go to the documentation of this file.
1 # /*
2 # * Created by YongGyu Lee on 2021/06/03.
3 # */
4 #
5 # ifndef VCCC_SIGNAL_CONNECTION_H_
6 # define VCCC_SIGNAL_CONNECTION_H_
7 #
8 # include <atomic>
9 # include <memory>
10 # include <utility>
11 #
14 
15 namespace vccc {
16 
19 
20 class connection;
21 
23 struct connection_impl_base {
24  virtual ~connection_impl_base() = default;
25  virtual bool is_connected() const = 0;
26  virtual void disconnect() = 0;
27  virtual void track(connection* conn, std::weak_ptr<void> target) = 0;
28 };
29 
30 template<typename Signal, typename SlotPtr>
31 struct connection_impl : public connection_impl_base {
32  using signal_type = Signal;
33  using slot_ptr = SlotPtr;
34 
35  connection_impl()
36  : connected(false) {}
37 
38  connection_impl(const std::shared_ptr<signal_type>& signal_ptr, SlotPtr&& slot)
39  : signal_ptr_(signal_ptr), slot_(std::move(slot)), connected(true) {}
40 
41  // TODO(Tony): Optimize
42  void disconnect() override {
43  auto ptr = signal_ptr_.lock();
44  if (ptr == nullptr)
45  return;
46 
47  bool state = true;
48  if (!connected.compare_exchange_strong(state, false))
49  return;
50 
51  auto weak_slot = slot_.first;
52  if (weak_slot.lock() == nullptr)
53  return;
54 
55  ptr->disconnect(slot_.second);
56  }
57 
58  bool is_connected() const override {
59  return connected.load();
60  }
61 
62  // WIP: use to signal::connect() only (slot != expired() must be guaranteed)
63  // signal.connect(...).track(...); // Good
64  // std::move(conn).track(...); // Bad
65  void track(connection* conn, std::weak_ptr<void> target) override {
66  auto signal = signal_ptr_.lock();
67  if (signal == nullptr)
68  return;
69  signal->set_track(conn, std::addressof(slot_.second), std::move(target));
70  }
71 
72  private:
73  std::weak_ptr<signal_type> signal_ptr_;
74  slot_ptr slot_;
75  std::atomic_bool connected{false};
76 };
77 
79 
83 class connection {
84  public:
85  connection() = default;
86 
87  explicit connection(std::shared_ptr<connection_impl_base> ptr)
88  : pimpl(std::move(ptr)) {}
89 
90  connection(connection const&) = default;
91  connection(connection&&) noexcept = default;
92  connection& operator=(connection const& other) = default;
93  connection& operator=(connection&& other) noexcept = default;
94 
98  void disconnect() const {
99  if(pimpl == nullptr)
100  return;
101  pimpl->disconnect();
102  }
103 
104  bool is_connected() const {
105  return pimpl != nullptr && pimpl->is_connected();
106  }
107 
108  connection track(std::weak_ptr<void> target) && {
109  pimpl->track(this, std::move(target));
110  return std::move(*this);
111  }
112 
113  protected:
114  std::shared_ptr<connection_impl_base> pimpl;
115 };
116 
121  using base = connection;
122  public:
123  using base::is_connected;
124  using base::disconnect;
125 
126  raii_connection() = default;
128  disconnect();
129  }
130 
131  raii_connection(const raii_connection& other) = delete;
132  raii_connection(raii_connection&& other) noexcept : base(other) {}
133  raii_connection(const connection& conn) : base(conn) {}
134  raii_connection(connection&& conn) noexcept : base(std::move(conn)) {}
135 
138  if (this != std::addressof(other)) {
139  disconnect();
140  base::operator=(std::move(other));
141  }
142  return *this;
143  }
144 
146  disconnect();
147  base::operator=(conn);
148  return *this;
149  }
150 
152  if (this != std::addressof(conn)) {
153  disconnect();
154  base::operator=(std::move(conn));
155  }
156  return *this;
157  }
158 };
159 
161 
162 } // namespace vccc
163 
164 # endif // VCCC_SIGNAL_CONNECTION_H_
Connection manager for a single slot.
Definition: connection.h:83
void disconnect() const
Definition: connection.h:98
connection(std::shared_ptr< connection_impl_base > ptr)
Definition: connection.h:87
connection(connection &&) noexcept=default
connection & operator=(connection const &other)=default
connection(connection const &)=default
connection track(std::weak_ptr< void > target) &&
Definition: connection.h:108
std::shared_ptr< connection_impl_base > pimpl
Definition: connection.h:114
connection()=default
bool is_connected() const
Definition: connection.h:104
Scoped connection manager for a single slot.
Definition: connection.h:120
void disconnect() const
Definition: connection.h:98
raii_connection(const connection &conn)
Definition: connection.h:133
raii_connection(connection &&conn) noexcept
Definition: connection.h:134
raii_connection & operator=(const connection &conn)
Definition: connection.h:145
~raii_connection()
Definition: connection.h:127
raii_connection & operator=(connection &&conn)
Definition: connection.h:151
raii_connection(raii_connection &&other) noexcept
Definition: connection.h:132
raii_connection & operator=(const raii_connection &rhs)=delete
raii_connection & operator=(raii_connection &&other)
Definition: connection.h:137
raii_connection(const raii_connection &other)=delete
std::enable_if_t< std::is_object< T >::value, T * > addressof(T &t) noexcept
Definition: addressof.hpp:33
Definition: matrix.hpp:495
Definition: directory.h:12