-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Add license header to connection_evaluator.h - Use slotInvocation instead of Connection in the ConnectionEvaluator - Add warnings that deferred connections are experimental - Improved documentation for deferred connections
- Loading branch information
1 parent
0213588
commit fe953f2
Showing
4 changed files
with
39 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,16 @@ | ||
/* | ||
This file is part of KDBindings. | ||
SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]> | ||
Author: Shivam Kunwar <[email protected]> | ||
SPDX-License-Identifier: MIT | ||
Contact KDAB at <[email protected]> for commercial licensing options. | ||
*/ | ||
#pragma once | ||
|
||
#include <functional> | ||
#include <list> | ||
#include <mutex> | ||
|
||
#include <kdbindings/connection_handle.h> | ||
|
@@ -11,6 +20,8 @@ namespace KDBindings { | |
/** | ||
* @brief Manages and evaluates deferred Signal connections. | ||
* | ||
* @warning Deferred connections are experimental and may be removed or changed in the future. | ||
* | ||
* The ConnectionEvaluator class is responsible for managing and evaluating connections | ||
* to Signals. It provides mechanisms to delay and control the evaluation of connections. | ||
* It therefore allows controlling when and on which thread slots connected to a Signal are executed. | ||
|
@@ -21,16 +32,19 @@ class ConnectionEvaluator | |
{ | ||
|
||
public: | ||
/** ConnectionEvaluators are default constructible */ | ||
ConnectionEvaluator() = default; | ||
|
||
// ConnectionEvaluator is not copyable, as it is designed to manage connections, | ||
/** Connectionevaluators are not copyable */ | ||
// As it is designed to manage connections, | ||
// and copying it could lead to unexpected behavior, including duplication of connections and issues | ||
// related to connection lifetimes. Therefore, it is intentionally made non-copyable. | ||
ConnectionEvaluator(const ConnectionEvaluator &) noexcept = delete; | ||
|
||
ConnectionEvaluator &operator=(const ConnectionEvaluator &) noexcept = delete; | ||
|
||
// ConnectionEvaluators are not moveable, as they are captures by-reference | ||
/** ConnectionEvaluators are not moveable */ | ||
// As they are captures by-reference | ||
// by the Signal, so moving them would lead to a dangling reference. | ||
ConnectionEvaluator(ConnectionEvaluator &&other) noexcept = delete; | ||
|
||
|
@@ -40,43 +54,43 @@ class ConnectionEvaluator | |
* @brief Evaluate the deferred connections. | ||
* | ||
* This function is responsible for evaluating and executing deferred connections. | ||
* And this function ensures thread safety | ||
* This function is thread safe. | ||
*/ | ||
void evaluateDeferredConnections() | ||
{ | ||
std::lock_guard<std::mutex> lock(m_connectionsMutex); | ||
std::lock_guard<std::mutex> lock(m_slotInvocationMutex); | ||
|
||
for (auto &pair : m_deferredConnections) { | ||
for (auto &pair : m_deferredSlotInvocations) { | ||
pair.second(); | ||
} | ||
m_deferredConnections.clear(); | ||
m_deferredSlotInvocations.clear(); | ||
} | ||
|
||
private: | ||
template<typename...> | ||
friend class Signal; | ||
|
||
void enqueueSlotInvocation(const ConnectionHandle &handle, const std::function<void()> &connection) | ||
void enqueueSlotInvocation(const ConnectionHandle &handle, const std::function<void()> &slotInvocation) | ||
{ | ||
std::lock_guard<std::mutex> lock(m_connectionsMutex); | ||
m_deferredConnections.push_back({ handle, std::move(connection) }); | ||
std::lock_guard<std::mutex> lock(m_slotInvocationMutex); | ||
m_deferredSlotInvocations.push_back({ handle, std::move(slotInvocation) }); | ||
} | ||
|
||
void dequeueSlotInvocation(const ConnectionHandle &handle) | ||
{ | ||
std::lock_guard<std::mutex> lock(m_connectionsMutex); | ||
std::lock_guard<std::mutex> lock(m_slotInvocationMutex); | ||
|
||
auto handleMatches = [&handle](const auto &invocationPair) { | ||
return invocationPair.first == handle; | ||
}; | ||
|
||
// Remove all invocations that match the handle | ||
m_deferredConnections.erase( | ||
std::remove_if(m_deferredConnections.begin(), m_deferredConnections.end(), handleMatches), | ||
m_deferredConnections.end()); | ||
m_deferredSlotInvocations.erase( | ||
std::remove_if(m_deferredSlotInvocations.begin(), m_deferredSlotInvocations.end(), handleMatches), | ||
m_deferredSlotInvocations.end()); | ||
} | ||
|
||
std::vector<std::pair<ConnectionHandle, std::function<void()>>> m_deferredConnections; | ||
std::mutex m_connectionsMutex; | ||
std::vector<std::pair<ConnectionHandle, std::function<void()>>> m_deferredSlotInvocations; | ||
std::mutex m_slotInvocationMutex; | ||
}; | ||
} // namespace KDBindings |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters