Skip to content

Commit

Permalink
Merge branch 'main' into update-copyright-1.0-to-main
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonMatthesKDAB committed Jan 12, 2024
2 parents d78e517 + 62de012 commit d49dfc7
Show file tree
Hide file tree
Showing 16 changed files with 977 additions and 186 deletions.
58 changes: 58 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
#
# SPDX-License-Identifier: MIT

name: CI

on: [push, pull_request]

jobs:
build:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: true
matrix:
os:
- ubuntu-22.04
#- ubuntu-20.04
- windows-2022
#- windows-2019
- macos-12
#- macos-11
build_type:
- Debug
- Release

steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Create build directory
run: mkdir build

- name: Install ninja-build tool
uses: turtlesec-no/get-ninja@main

- name: Make sure MSVC is found when Ninja generator is in use
uses: ilammy/msvc-dev-cmd@v1

- name: Configure project
run: >
cmake -S . -B ./build -G Ninja
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DKDBindings_TESTS=${{ matrix.build_type == 'Debug' }}
-DKDBindings_EXAMPLES=${{ matrix.build_type == 'Debug' }}
-DKDBindings_DOCS=${{ matrix.build_type == 'Debug' && runner.os == 'Linux' }}
- name: Build Project
run: cmake --build ./build

- name: Run tests
if: ${{ matrix.build_type == 'Debug' }}
run: ctest --test-dir ./build -C ${{ matrix.build_type }} --output-on-failure

- name: Read tests log when it fails
uses: andstor/file-reader-action@v1
if: ${{ failure() && matrix.build_type == 'Debug' }}
with:
path: "./build/Testing/Temporary/LastTest.log"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ imgui.ini

.vscode/*
build/*
build-*
serenity_metatype.*
output.json

Expand Down
6 changes: 1 addition & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ cmake_minimum_required(VERSION 3.12) # for `project(... HOMEPAGE_URL ...)`
project(KDBindings
DESCRIPTION "Bindings, from the comfort and speed of C++ and without Qt"
LANGUAGES CXX
VERSION 1.0.1
VERSION 1.0.95
HOMEPAGE_URL "https://github.com/KDAB/KDBindings"
)

Expand Down Expand Up @@ -94,10 +94,6 @@ endif()

if(${PROJECT_NAME}_DOCS)
add_subdirectory(docs) # needs to go last, in case there are build source files
else()
add_custom_target(docs
COMMAND ${CMAKE_COMMAND} -E echo "Sorry, there is no docs target since KDBindings_DOCS=OFF."
"Re-run cmake with the -DKDBindings_DOCS=ON option if you want to generate the documentation.")
endif()

if(${PROJECT_NAME}_IS_ROOT_PROJECT)
Expand Down
17 changes: 17 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"version": 2,
"configurePresets": [
{
"name": "dev",
"displayName": "dev",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build-dev",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS" : "ON",
"KDBindings_TESTS" : "ON",
"KDBindings_EXAMPLES" : "ON"
}
}
]
}
3 changes: 3 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
* v1.1.0 (unreleased)
- Feature: Add ScopedConnection for RAII-style connection management (#31)

* v1.0.1
- Property: Make moved Signal private (#24 & #26) - BREAKING!
- Documentation: Small fixes & updates
Expand Down
16 changes: 16 additions & 0 deletions examples/08-managing-connections/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# This file is part of KDBindings.
#
# SPDX-FileCopyrightText: 2021-2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
# Author: Leon Matthes <[email protected]>
#
# SPDX-License-Identifier: MIT
#
# Contact KDAB at <[email protected]> for commercial licensing options.
#

project(08-managing-connections VERSION 0.1 LANGUAGES CXX)

add_executable(${PROJECT_NAME}
main.cpp
)
target_link_libraries(${PROJECT_NAME} KDAB::KDBindings)
56 changes: 56 additions & 0 deletions examples/08-managing-connections/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
This file is part of KDBindings.
SPDX-FileCopyrightText: 2021-2023 Klarälvdalens Datakonsult AB, a KDAB Group company <[email protected]>
Author: Leon Matthes <[email protected]>
SPDX-License-Identifier: MIT
Contact KDAB at <[email protected]> for commercial licensing options.
*/

#include <ios>
#include <kdbindings/signal.h>

#include <iostream>
#include <string>

using namespace KDBindings;

void displayLabelled(const std::string &label, int value)
{
std::cout << label << ": " << value << std::endl;
}

int main()
{
Signal<int> signal;

{
// A ScopedConnection will disconnect the connection once it goes out of scope.
// It is especially useful if you're connecting to a member function.
// Storing a ScopedConnection in the object that contains the slot ensures the connection
// is disconnected when the object is destructed.
// This ensures that there are no dangling connections.
ScopedConnection guard = signal.connect(displayLabelled, "Guard is connected");

signal.emit(1);
} // The connection is disconnected here

signal.emit(2);

ConnectionHandle handle = signal.connect(displayLabelled, "Connection is not blocked");

signal.emit(3);
{
// A ConnectionBlocker will block a connection for the duration of its scope.
// This is a good way to avoid endless-recursion, or to suppress updates for a short time.
ConnectionBlocker blocker(handle); // The connection is blocked here

signal.emit(4);
} // The connection is un-blocked here

signal.emit(5);

return 0;
}
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ add_subdirectory(04-simple-property)
add_subdirectory(05-property-bindings)
add_subdirectory(06-lazy-property-bindings)
add_subdirectory(07-advanced-connections)
add_subdirectory(08-managing-connections)
2 changes: 2 additions & 0 deletions src/kdbindings/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ set(HEADERS
property.h
property_updater.h
signal.h
connection_evaluator.h
connection_handle.h
utils.h
)

Expand Down
96 changes: 96 additions & 0 deletions src/kdbindings/connection_evaluator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
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 <mutex>

#include <kdbindings/connection_handle.h>

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.
*
* @see Signal::connectDeferred()
*/
class ConnectionEvaluator
{

public:
/** ConnectionEvaluators are default constructible */
ConnectionEvaluator() = default;

/** 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
// by the Signal, so moving them would lead to a dangling reference.
ConnectionEvaluator(ConnectionEvaluator &&other) noexcept = delete;

ConnectionEvaluator &operator=(ConnectionEvaluator &&other) noexcept = delete;

/**
* @brief Evaluate the deferred connections.
*
* This function is responsible for evaluating and executing deferred connections.
* This function is thread safe.
*/
void evaluateDeferredConnections()
{
std::lock_guard<std::mutex> lock(m_slotInvocationMutex);

for (auto &pair : m_deferredSlotInvocations) {
pair.second();
}
m_deferredSlotInvocations.clear();
}

private:
template<typename...>
friend class Signal;

void enqueueSlotInvocation(const ConnectionHandle &handle, const std::function<void()> &slotInvocation)
{
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_slotInvocationMutex);

auto handleMatches = [&handle](const auto &invocationPair) {
return invocationPair.first == handle;
};

// Remove all invocations that match the handle
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_deferredSlotInvocations;
std::mutex m_slotInvocationMutex;
};
} // namespace KDBindings
Loading

0 comments on commit d49dfc7

Please sign in to comment.