Skip to content

Commit

Permalink
Add a convenience for single shot connections
Browse files Browse the repository at this point in the history
Although this is a trivial wrapper around connectReflective it is
useful to have this to make it easy to find and reduce the burden
on the developer.
  • Loading branch information
seanharmer committed Oct 1, 2024
1 parent 85ca6d1 commit bf6a0f6
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
24 changes: 24 additions & 0 deletions src/kdbindings/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,30 @@ class Signal
return ConnectionHandle{ m_impl, m_impl->connectReflective(slot) };
}

/**
* Establishes a single-shot connection between a signal and a slot and when the signal is emitted, the connection will be
* disconnected and the slot will be called. Note that the slot will be disconnected before it is called. If the slot
* triggers another signal emission of the same signal, the slot will not be called again.
*
* @param slot A std::function that takes the signal's parameter types.
* @return An instance of ConnectionHandle, that can be used to disconnect.
*
* @warning Connecting functions to a signal that throw an exception when called is currently undefined behavior.
* All connected functions should handle their own exceptions.
* For backwards-compatibility, the slot function is not required to be noexcept.
*/
KDBINDINGS_WARN_UNUSED ConnectionHandle connectSingleShot(std::function<void(Args...)> const &slot)
{
ensureImpl();

auto singleShotSlot = [slot](ConnectionHandle &handle, Args... args) {
handle.disconnect();
slot(args...);
};

return ConnectionHandle{ m_impl, m_impl->connectReflective(singleShotSlot) };
}

/**
* @brief Establishes a deferred connection between the provided evaluator and slot.
*
Expand Down
7 changes: 2 additions & 5 deletions tests/signal/tst_signal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,12 +270,9 @@ TEST_CASE("Signal connections")
Signal<int> mySignal;
int val = 5;

// Connect a reflective slot to the signal
auto handle = mySignal.connectReflective([&val](ConnectionHandle &selfHandle, int value) {
// Connect a single shot slot to the signal
auto handle = mySignal.connectSingleShot([&val](int value) {
val += value;

// Disconnect after handling the signal once
selfHandle.disconnect();
});

mySignal.emit(5); // This should trigger the slot and then disconnect it
Expand Down

0 comments on commit bf6a0f6

Please sign in to comment.