Skip to content

Commit

Permalink
Refactor connectReflective
Browse files Browse the repository at this point in the history
It now reuses the mechanism established by connectReflective.
  • Loading branch information
LeonMatthesKDAB committed Jun 12, 2024
1 parent ad5a733 commit 22837e0
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 32 deletions.
10 changes: 0 additions & 10 deletions src/kdbindings/connection_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,6 @@ class ConnectionHandle
template<typename...>
friend class Signal;

std::weak_ptr<ConnectionHandle> self; // Allows for safe self-reference

std::weak_ptr<Private::SignalImplBase> m_signalImpl;
std::optional<Private::GenerationalIndex> m_id;

Expand All @@ -208,14 +206,6 @@ class ConnectionHandle
}
return nullptr;
}

// Factory method to create a ConnectionHandle
static std::shared_ptr<ConnectionHandle> create(const std::weak_ptr<Private::SignalImplBase> &signalImpl, std::optional<Private::GenerationalIndex> id)
{
auto handle = std::shared_ptr<ConnectionHandle>(new ConnectionHandle(signalImpl, id));
handle->self = handle; // Keep a weak reference to self
return handle;
}
};

/**
Expand Down
39 changes: 17 additions & 22 deletions src/kdbindings/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class Signal
{
auto weakEvaluator = std::weak_ptr<ConnectionEvaluator>(evaluator);

auto deferredSlot = [weakEvaluator = std::move(weakEvaluator), slot](const ConnectionHandle &handle, Args... args) {
auto deferredSlot = [weakEvaluator = std::move(weakEvaluator), slot](ConnectionHandle &handle, Args... args) {
if (auto evaluatorPtr = weakEvaluator.lock()) {
auto lambda = [slot, args...]() {
slot(args...);
Expand All @@ -109,7 +109,15 @@ class Signal

Connection newConnection;
newConnection.m_connectionEvaluator = evaluator;
newConnection.slotDeferred = deferredSlot;
newConnection.slotReflective = deferredSlot;

return m_connections.insert(std::move(newConnection));
}

Private::GenerationalIndex connectReflective(std::function<void(ConnectionHandle &handle, Args...)> const &slot)
{
Connection newConnection;
newConnection.slotReflective = slot;

return m_connections.insert(std::move(newConnection));
}
Expand All @@ -127,7 +135,7 @@ class Signal

// Retrieve the connection associated with this id
auto connection = m_connections.get(id);
if (connection && connection->slotDeferred) {
if (connection && connection->m_connectionEvaluator.lock()) {
if (auto evaluatorPtr = connection->m_connectionEvaluator.lock()) {
evaluatorPtr->dequeueSlotInvocation(handle);
}
Expand All @@ -138,7 +146,8 @@ class Signal
}

// Disconnects all previously connected functions
void disconnectAll()
void
disconnectAll()
{
const auto numEntries = m_connections.entriesSize();

Expand Down Expand Up @@ -194,10 +203,10 @@ class Signal
const auto con = m_connections.get(*index);

if (!con->blocked) {
if (con->slotDeferred) {
if (con->slotReflective) {
if (auto sharedThis = shared_from_this(); sharedThis) {
ConnectionHandle handle(sharedThis, *index);
con->slotDeferred(handle, p...);
con->slotReflective(handle, p...);
}
} else if (con->slot) {
con->slot(p...);
Expand All @@ -211,7 +220,7 @@ class Signal
friend class Signal;
struct Connection {
std::function<void(Args...)> slot;
std::function<void(const ConnectionHandle &, Args...)> slotDeferred;
std::function<void(ConnectionHandle &, Args...)> slotReflective;
std::weak_ptr<ConnectionEvaluator> m_connectionEvaluator;
bool blocked{ false };
};
Expand Down Expand Up @@ -274,21 +283,7 @@ class Signal
{
ensureImpl();

// Create a new ConnectionHandle with no ID initially. This handle will be used to manage the connection lifecycle.
auto handle = ConnectionHandle::create(m_impl, std::nullopt);

// Prepare the lambda that matches the signature expected by m_impl->connect
auto wrappedSlot = [this, handle, slot](Args... args) mutable {
// Directly invoke the user-provided slot with the handle and args
slot(*handle, args...);
};

// Connect the wrapped slot to the signal implementation.
// The handle ID is set after successful connection to manage this connection specifically.
handle->setId(m_impl->connect(wrappedSlot));

// Return the ConnectionHandle, allowing the caller to manage the connection directly.
return *handle;
return ConnectionHandle{ m_impl, m_impl->connectReflective(slot) };
}

/**
Expand Down

0 comments on commit 22837e0

Please sign in to comment.