From 93d113a8b660c8f10a18d80a4836707e59b0fc2b Mon Sep 17 00:00:00 2001 From: Giulio Eulisse <10544+ktf@users.noreply.github.com> Date: Mon, 6 Jan 2025 16:42:53 +0100 Subject: [PATCH] Out of line some methods of EventManager --- fairmq/CMakeLists.txt | 1 + fairmq/EventManager.cxx | 19 ++++++ fairmq/EventManager.h | 125 +++++++++++++++++++++++----------------- fairmq/Properties.h | 4 +- 4 files changed, 95 insertions(+), 54 deletions(-) create mode 100644 fairmq/EventManager.cxx diff --git a/fairmq/CMakeLists.txt b/fairmq/CMakeLists.txt index c6790f3e..a2a44f50 100644 --- a/fairmq/CMakeLists.txt +++ b/fairmq/CMakeLists.txt @@ -119,6 +119,7 @@ if(BUILD_FAIRMQ) Channel.cxx Device.cxx DeviceRunner.cxx + EventManager.cxx JSONParser.cxx MemoryResources.cxx Plugin.cxx diff --git a/fairmq/EventManager.cxx b/fairmq/EventManager.cxx new file mode 100644 index 00000000..b9151a29 --- /dev/null +++ b/fairmq/EventManager.cxx @@ -0,0 +1,19 @@ +/******************************************************************************** + * Copyright (C) 2014-2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * * + * This software is distributed under the terms of the * + * GNU Lesser General Public Licence (LGPL) version 3, * + * copied verbatim in the file "LICENSE" * + ********************************************************************************/ +#include "EventManager.h" + +#include + +template std::shared_ptr< + fair::mq::EventManager::Signal> + fair::mq::EventManager::GetSignal( + const std::pair& key) const; + +template void fair::mq::EventManager::Subscribe( + const std::string& subscriber, + std::function); diff --git a/fairmq/EventManager.h b/fairmq/EventManager.h index bb119d95..b76137fd 100644 --- a/fairmq/EventManager.h +++ b/fairmq/EventManager.h @@ -1,5 +1,5 @@ /******************************************************************************** - * Copyright (C) 2014-2017 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * + * Copyright (C) 2014-2025 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH * * * * This software is distributed under the terms of the * * GNU Lesser General Public Licence (LGPL) version 3, * @@ -9,20 +9,18 @@ #ifndef FAIR_MQ_EVENTMANAGER_H #define FAIR_MQ_EVENTMANAGER_H +#include +#include +#include +#include #include #include #include #include #include #include -#include -#include -#include -#include - -namespace fair::mq -{ +namespace fair::mq { // Inherit from this base event type to create custom event types template @@ -54,36 +52,19 @@ class EventManager // template // using Callback = std::function; - template + template using Signal = boost::signals2::signal; - template - auto Subscribe(const std::string& subscriber, std::function callback) -> void - { - const std::type_index event_type_index{typeid(E)}; - const std::type_index callback_type_index{typeid(std::function)}; - const auto signalsKey = std::make_pair(event_type_index, callback_type_index); - const auto connectionsKey = std::make_pair(subscriber, signalsKey); + template + auto Subscribe(const std::string& subscriber, + std::function callback) -> void; - const auto connection = GetSignal(signalsKey)->connect(callback); - - { - std::lock_guard lock{fMutex}; - - if (fConnections.find(connectionsKey) != fConnections.end()) - { - fConnections.at(connectionsKey).disconnect(); - fConnections.erase(connectionsKey); - } - fConnections.insert({connectionsKey, connection}); - } - } - - template + template auto Unsubscribe(const std::string& subscriber) -> void { const std::type_index event_type_index{typeid(E)}; - const std::type_index callback_type_index{typeid(std::function)}; + const std::type_index callback_type_index{ + typeid(std::function)}; const auto signalsKey = std::make_pair(event_type_index, callback_type_index); const auto connectionsKey = std::make_pair(subscriber, signalsKey); @@ -93,48 +74,88 @@ class EventManager fConnections.erase(connectionsKey); } - template + template auto Emit(typename E::KeyType key, Args... args) const -> void { const std::type_index event_type_index{typeid(E)}; - const std::type_index callback_type_index{typeid(std::function)}; + const std::type_index callback_type_index{ + typeid(std::function)}; const auto signalsKey = std::make_pair(event_type_index, callback_type_index); (*GetSignal(signalsKey))(key, std::forward(args)...); } private: - using SignalsKey = std::pair; - // event , callback + using SignalsKey = std::pair; + // event , callback using SignalsValue = boost::any; - using SignalsMap = std::unordered_map>; + using SignalsMap = std::unordered_map>; mutable SignalsMap fSignals; - using ConnectionsKey = std::pair; - // subscriber , event/callback + using ConnectionsKey = std::pair; + // subscriber , event/callback using ConnectionsValue = boost::signals2::connection; - using ConnectionsMap = std::unordered_map>; + using ConnectionsMap = + std::unordered_map>; ConnectionsMap fConnections; mutable std::mutex fMutex; - template - auto GetSignal(const SignalsKey& key) const -> std::shared_ptr> + template + auto GetSignal(const SignalsKey& key) const -> std::shared_ptr>; +}; /* class EventManager */ + +struct PropertyChangeAsString : Event +{}; + +template +auto EventManager::GetSignal(const SignalsKey& key) const -> std::shared_ptr> +{ + std::lock_guard lock{fMutex}; + + if (fSignals.find(key) == fSignals.end()) { + // wrapper is needed because boost::signals2::signal is neither copyable nor movable + // and I don't know how else to insert it into the map + auto signal = std::make_shared>(); + fSignals.insert(std::make_pair(key, signal)); + } + + return boost::any_cast>>(fSignals.at(key)); +} + +template +auto EventManager::Subscribe(const std::string& subscriber, + std::function callback) -> void +{ + const std::type_index event_type_index{typeid(E)}; + const std::type_index callback_type_index{ + typeid(std::function)}; + const auto signalsKey = std::make_pair(event_type_index, callback_type_index); + const auto connectionsKey = std::make_pair(subscriber, signalsKey); + + const auto connection = GetSignal(signalsKey)->connect(callback); + { std::lock_guard lock{fMutex}; - if (fSignals.find(key) == fSignals.end()) - { - // wrapper is needed because boost::signals2::signal is neither copyable nor movable - // and I don't know how else to insert it into the map - auto signal = std::make_shared>(); - fSignals.insert(std::make_pair(key, signal)); + if (fConnections.find(connectionsKey) != fConnections.end()) { + fConnections.at(connectionsKey).disconnect(); + fConnections.erase(connectionsKey); } - - return boost::any_cast>>(fSignals.at(key)); + fConnections.insert({connectionsKey, connection}); } -}; /* class EventManager */ +} -} // namespace fair::mq +extern template std::shared_ptr< + fair::mq::EventManager::Signal> + fair::mq::EventManager::GetSignal( + const std::pair& key) const; + +extern template void + fair::mq::EventManager::Subscribe( + const std::string& subscriber, + std::function); + +} // namespace fair::mq #endif /* FAIR_MQ_EVENTMANAGER_H */ diff --git a/fairmq/Properties.h b/fairmq/Properties.h index 24b00329..ed826984 100644 --- a/fairmq/Properties.h +++ b/fairmq/Properties.h @@ -28,8 +28,8 @@ namespace fair::mq using Property = boost::any; using Properties = std::map; -struct PropertyChange : Event {}; -struct PropertyChangeAsString : Event {}; +struct PropertyChange : Event +{}; class PropertyHelper {