Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Single shot connection convenience #98

Merged
merged 4 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ Thumbs.db

CMakeLists.txt.user
CMakeLists.txt.user.*
CMakeUserPresets.json
*.spv
.vs/*
imgui.ini
Expand Down
22 changes: 22 additions & 0 deletions CMakeUserPresets-example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"version": 3,
"configurePresets": [
{
"name": "msvc_x64-dev",
"displayName": "dev (msvc_x64)",
"inherits": ["dev"],
"architecture": {
"value": "x64",
"strategy": "external"
},
"toolset": {
"value": "host=x64",
"strategy": "external"
},
"cacheVariables": {
"CMAKE_C_COMPILER": "cl",
"CMAKE_CXX_COMPILER": "cl"
}
}
]
}
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) };
seanharmer marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* @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