Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
build/
.vscode/
.vscode/
.cache/
compile_commands.json
.vimspector.json
56 changes: 25 additions & 31 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,27 @@
cmake_minimum_required(VERSION 3.24)
cmake_minimum_required(VERSION 3.30)

project(function-dispatcher VERSION 0.1.0)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD 17)

option(${PROJECT_NAME}_example "Build examples" ON)
option(${PROJECT_NAME}_benchmark "Build benchmark" ON)
option(${PROJECT_NAME}_benchmark "Build benchmark" OFF)
option(${PROJECT_NAME}_test "Build test" ON)

include(FetchContent)

# find_package(Boost
# 1.87.0
# QUIET
# COMPONENTS
# asio
# signals2
# fiber
# )
find_package(Boost 1.87.0 QUIET COMPONENTS asio signals2 fiber)

add_library(${PROJECT_NAME} INTERFACE)
target_sources(
${PROJECT_NAME}
INTERFACE FILE_SET
public_headers
TYPE
HEADERS
BASE_DIRS
include
FILES
include/${PROJECT_NAME}.hpp)

if(NOT Boost_FOUND)
set(FETCHCONTENT_QUIET OFF)
Expand All @@ -26,34 +31,23 @@ if(NOT Boost_FOUND)
GIT_PROGRESS TRUE
GIT_SHALLOW TRUE
GIT_TAG boost-1.87.0
OVERRIDE_FIND_PACKAGE
)
OVERRIDE_FIND_PACKAGE)
FetchContent_MakeAvailable(Boost)

find_package(Boost
1.87.0
REQUIRED
COMPONENTS
asio
signals2
fiber
)
find_package(Boost 1.87.0 REQUIRED COMPONENTS asio signals2 fiber)
target_link_libraries(${PROJECT_NAME} INTERFACE Boost::fiber Boost::asio
Boost::signals2)
else()
message(STATUS "Using installed Boost: ${Boost_DIR}")
endif()

add_library(${PROJECT_NAME} INTERFACE)
target_sources(${PROJECT_NAME} INTERFACE FILE_SET public_headers TYPE HEADERS
BASE_DIRS include
FILES include/${PROJECT_NAME}.hpp)

include(GNUInstallDirs)
target_include_directories(
${PROJECT_NAME} INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
target_link_libraries(${PROJECT_NAME} INTERFACE Boost::signals2 Boost::asio Boost::fiber)
${PROJECT_NAME}
INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
${Boost_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} INTERFACE Boost::fiber)

if(${PROJECT_NAME}_example)
add_subdirectory(example)
Expand Down
23 changes: 13 additions & 10 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,22 @@
include(FetchContent)

FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
FetchContent_MakeAvailable(googletest)
find_package(GTest)

if(NOT TARGET Gtest::gtest)
message(STATUS "GTest not found, downloading from github")
FetchContent_Declare(
GTest
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
FetchContent_MakeAvailable(GTest)
endif()

FetchContent_Declare(
benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG v1.9.2
)
GIT_TAG v1.9.2)
FetchContent_MakeAvailable(benchmark)

add_executable(${PROJECT_NAME}_google_benchmark benchmark.cpp)
target_link_libraries(${PROJECT_NAME}_google_benchmark PRIVATE benchmark::benchmark ${PROJECT_NAME})


target_link_libraries(${PROJECT_NAME}_google_benchmark
PRIVATE benchmark::benchmark ${PROJECT_NAME})
15 changes: 12 additions & 3 deletions example/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
set(EXAMPLES same_signature complex_type safety reference events detaching timer expect)
set(EXAMPLES
same_signature
complex_type
safety
reference
events
detaching
timer
expect
async_call)

foreach(EXAMPLE ${EXAMPLES})
add_executable(${EXAMPLE} ${EXAMPLE}.cpp)
target_link_libraries(${EXAMPLE} PUBLIC ${PROJECT_NAME})
add_executable(${EXAMPLE} ${EXAMPLE}.cpp)
target_link_libraries(${EXAMPLE} PUBLIC ${PROJECT_NAME})
endforeach()
29 changes: 29 additions & 0 deletions example/async_call.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <boost/fiber/operations.hpp>
#include <chrono>
#include <string>
#include <thread>
#include <tuple>

#include "dispatcher.hpp"

struct Message {
using args_t = std::tuple<std::string>;
using return_t = std::string;
};

struct OtherNetwork {};
struct AnotherNetwork {};

int main()
{
dispatcher::attach<Message>([](std::string message) -> std::string {
std::cout << message << std::endl;
dispatcher::sleep_for(std::chrono::milliseconds(2000));
return "World";
});
dispatcher::post<AnotherNetwork>([] {
auto value = dispatcher::async_call<Message, OtherNetwork>("Hello");
std::cout << value.get() << std::endl;
});
std::this_thread::sleep_for(std::chrono::seconds(10));
}
8 changes: 4 additions & 4 deletions example/complex_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ struct Message {
{
std::cout << "Normal constructor called" << std::endl;
}
Message(const Message &other) : message(other.message)
Message(const Message& other) : message(other.message)
{
std::cout << "Copy constructor called" << std::endl;
}
Message &operator=(const Message &other)
Message& operator=(const Message& other)
{
message = other.message;
std::cout << "Copy constructor called" << std::endl;
return *this;
}
Message(Message &&other) : message(std::move(other.message))
Message(Message&& other) : message(std::move(other.message))
{
std::cout << "Move constructor called" << std::endl;
}
Message &operator=(Message &&other)
Message& operator=(Message&& other)
{
message = std::move(other.message);
std::cout << "Move constructor called" << std::endl;
Expand Down
18 changes: 13 additions & 5 deletions example/expect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,24 @@ struct AnEvent {
using parameters_t = std::tuple<std::string>;
};

struct OtherNetwork {};

struct AnotherNetwork {};

int main()
{
dispatcher::post([] {
auto future = dispatcher::expect<AnEvent>();
auto future_2 = dispatcher::expect<AnEvent>([](auto s) { std::cout << s << std::endl; });
dispatcher::post<OtherNetwork>([] {
auto future = dispatcher::expect<AnEvent>(

[](auto s) { std::cout << "Received an event on DefaultNetwork: " << s << std::endl; });
auto future_2 = dispatcher::expect<AnEvent, AnotherNetwork>(
[](auto s) { std::cout << "Received an event on AnotherNetwork: " << s << std::endl; });
dispatcher::publish<AnEvent>("Hello world");
// Will block until event is received
future.wait();
// The subscribtion are fullfilled when the event is done
dispatcher::publish<AnEvent>("Hello world");
dispatcher::publish<AnEvent, AnotherNetwork>("Hello world for the second time");
future_2.wait();
std::cout << "All expectation done" << std::endl;
});
std::this_thread::sleep_for(std::chrono::seconds{1});
}
28 changes: 21 additions & 7 deletions example/timer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,35 @@ void printTime(std::string message, int i)
<< std::setfill('0') << std::setw(3) << now_ms.count() << std::endl;
}

bool TestWait2(int i)
{
printTime(" 2 started ", i);
dispatcher::promise<bool> hello;

auto future = hello.get_future();
future.wait_for(std::chrono::milliseconds(50));
printTime(" 2 ended ", i);
return true;
}

bool TestWait(int i)
{
printTime(" started ", i);
boost::fibers::promise<bool> hello;
printTime(" 1 started ", i);
dispatcher::promise<bool> hello;

auto future = hello.get_future();
future.wait_for(std::chrono::seconds(2));
printTime(" ended ", i);
future.wait_for(std::chrono::milliseconds(200));
printTime(" 1 ended ", i);
return true;
}

int main(int argc, char** argv)
{
dispatcher::DefaultTimer timer;
int i = 0;
timer.DoEvery(std::chrono::milliseconds(500), [&] { bool b = TestWait(i++); });
std::this_thread::sleep_for(std::chrono::seconds{6000});
}
timer.DoEvery(std::chrono::milliseconds(1000), [&] { bool b = TestWait(i++); });
dispatcher::DefaultTimer timer2;
int j = 0;
timer2.DoEvery(std::chrono::milliseconds(100), [&] { bool b = TestWait2(j++); });
std::this_thread::sleep_for(std::chrono::seconds{3});
}
Loading