32template<
typename... Args>
103 if (
auto shared_impl = checkedLock()) {
104 shared_impl->disconnect(m_id);
107 m_signalImpl.reset();
118 return static_cast<bool>(checkedLock());
139 if (
auto shared_impl = checkedLock()) {
140 return shared_impl->blockConnection(m_id, blocked);
142 throw std::out_of_range(
"Cannot block a non-active connection!");
154 if (
auto shared_impl = checkedLock()) {
155 return shared_impl->isConnectionBlocked(m_id);
157 throw std::out_of_range(
"Cannot check whether a non-active connection is blocked!");
165 template<
typename... Args>
168 auto shared_impl = m_signalImpl.lock();
169 return shared_impl && shared_impl == std::static_pointer_cast<Private::SignalImplBase>(signal.m_impl);
173 template<
typename...>
176 std::weak_ptr<Private::SignalImplBase> m_signalImpl;
181 : m_signalImpl{
std::move(signalImpl) }, m_id{
std::move(id) }
187 std::shared_ptr<Private::SignalImplBase> checkedLock()
const
189 auto shared_impl = m_signalImpl.lock();
190 if (shared_impl && shared_impl->isConnectionActive(m_id)) {
216template<
typename... Args>
220 std::conjunction<std::negation<std::is_rvalue_reference<Args>>...>::value,
221 "R-value references are not allowed as Signal parameters!");
234 Impl(Impl
const &other) =
delete;
235 Impl &operator=(Impl
const &other) =
delete;
238 Impl(Impl &&other) =
delete;
239 Impl &operator=(Impl &&other) =
delete;
245 return m_connections.insert({ slot });
251 m_connections.erase(
id);
257 m_connections.clear();
262 Connection *connection = m_connections.get(
id);
264 const bool wasBlocked = connection->blocked;
265 connection->blocked = blocked;
268 throw std::out_of_range(
"Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
274 return m_connections.get(
id);
279 auto connection = m_connections.get(
id);
281 return connection->blocked;
283 throw std::out_of_range(
"Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
288 void emit(Args... p)
const
290 const auto numEntries = m_connections.entriesSize();
294 for (
auto i =
decltype(numEntries){ 0 }; i < numEntries; ++i) {
295 const auto index = m_connections.indexAtEntry(i);
298 const auto con = m_connections.get(*index);
308 std::function<void(Args...)> slot;
309 bool blocked{
false };
389 template<
typename Func,
typename... FuncArgs,
typename = std::enable_if_t<std::disjunction_v<std::negation<std::is_convertible<Func, std::function<void(Args...)>>>, std::integral_constant<bool,
sizeof...(FuncArgs) >>>>
392 std::function<void(Args...)> bound =
Private::bind_first(std::forward<Func>(slot), std::forward<FuncArgs>(args)...);
408 m_impl->disconnect(handle.m_id);
411 throw std::out_of_range(
"Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
424 m_impl->disconnectAll();
453 return m_impl->blockConnection(handle.m_id, blocked);
455 throw std::out_of_range(
"Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
472 throw std::out_of_range(
"Provided ConnectionHandle does not match any connection\nLikely the connection was deleted before!");
475 return m_impl->isConnectionBlocked(handle.m_id);
505 m_impl = std::make_shared<Impl>();
521 mutable std::shared_ptr<Impl> m_impl;
554 m_connection.disconnect();
555 m_connection = std::move(other.m_connection);
563 : m_connection(
std::move(h))
596 return &m_connection;
604 return &m_connection;
612 m_connection.disconnect();
642 m_wasBlocked = m_handle.
block(
true);
651 m_handle.block(m_wasBlocked);
656 bool m_wasBlocked{
false };
A ConnectionBlocker is a convenient RAII-style mechanism for temporarily blocking a connection.
ConnectionBlocker(const ConnectionHandle &handle)
A ConnectionHandle represents the connection of a Signal to a slot (i.e. a function that is called wh...
ConnectionHandle(ConnectionHandle &&)=default
ConnectionHandle & operator=(const ConnectionHandle &)=default
bool belongsTo(const Signal< Args... > &signal) const
ConnectionHandle(const ConnectionHandle &)=default
ConnectionHandle()=default
ConnectionHandle & operator=(ConnectionHandle &&)=default
virtual ~SignalImplBase()=default
virtual bool isConnectionBlocked(const GenerationalIndex &id) const =0
virtual bool blockConnection(const GenerationalIndex &id, bool blocked)=0
virtual bool isConnectionActive(const GenerationalIndex &id) const =0
virtual void disconnect(const GenerationalIndex &id)=0
A ScopedConnection is a RAII-style way to make sure a Connection is disconnected.
ConnectionHandle * operator->()
ScopedConnection()=default
A ScopedConnection can be default constructed.
ScopedConnection(const ScopedConnection &)=delete
ScopedConnection & operator=(ScopedConnection &&other)
ConnectionHandle & handle()
const ConnectionHandle * operator->() const
ScopedConnection(ScopedConnection &&)=default
ScopedConnection & operator=(ConnectionHandle &&h)
ScopedConnection & operator=(const ScopedConnection &)=delete
ScopedConnection(ConnectionHandle &&h)
const ConnectionHandle & handle() const
A Signal provides a mechanism for communication between objects.
ConnectionHandle connect(Func &&slot, FuncArgs &&...args)
Signal(Signal &&other) noexcept=default
bool isConnectionBlocked(const ConnectionHandle &handle) const
void disconnect(const ConnectionHandle &handle)
bool blockConnection(const ConnectionHandle &handle, bool blocked)
Signal & operator=(Signal const &other)=delete
Signal & operator=(Signal &&other) noexcept=default
void emit(Args... p) const
Signal(const Signal &)=delete
friend class ConnectionHandle
ConnectionHandle connect(std::function< void(Args...)> const &slot)
auto bind_first(Func &&fun, Args &&...args)
typename operator_node_result< Operator, Ts... >::type operator_node_result_t
The main namespace of the KDBindings library.