Clio develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
TrackableSignalMap.hpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of clio: https://github.com/XRPLF/clio
4 Copyright (c) 2024, the clio developers.
5
6 Permission to use, copy, modify, and distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#pragma once
21
22#include "feed/impl/TrackableSignal.hpp"
23#include "util/Mutex.hpp"
24
25#include <boost/signals2.hpp>
26
27#include <concepts>
28#include <cstddef>
29#include <functional>
30#include <memory>
31#include <mutex>
32#include <unordered_map>
33
34namespace feed::impl {
35
36template <typename T>
37concept Hashable = requires(T a) {
38 { std::hash<T>{}(a) } -> std::convertible_to<std::size_t>;
39};
40
48template <Hashable Key, typename Session, typename... Args>
50 using ConnectionPtr = Session*;
51 using ConnectionSharedPtr = std::shared_ptr<Session>;
52
53 using SignalsMap = std::unordered_map<Key, TrackableSignal<Session, Args...>>;
54 util::Mutex<SignalsMap> signalsMap_;
55
56public:
67 bool
68 connectTrackableSlot(ConnectionSharedPtr const& trackable, Key const& key, std::function<void(Args...)> slot)
69 {
70 auto map = signalsMap_.template lock<std::scoped_lock>();
71 return map->operator[](key).connectTrackableSlot(trackable, slot);
72 }
73
81 bool
82 disconnect(ConnectionPtr trackablePtr, Key const& key)
83 {
84 auto map = signalsMap_.template lock<std::scoped_lock>();
85 if (!map->contains(key))
86 return false;
87
88 auto const disconnected = map->operator[](key).disconnect(trackablePtr);
89 // clean the map if there is no connection left.
90 if (disconnected && map->operator[](key).count() == 0)
91 map->erase(key);
92
93 return disconnected;
94 }
95
102 void
103 emit(Key const& key, Args const&... args)
104 {
105 auto map = signalsMap_.template lock<std::scoped_lock>();
106 if (map->contains(key))
107 map->operator[](key).emit(args...);
108 }
109};
110} // namespace feed::impl
Class to manage a map of key and its associative signal.
Definition TrackableSignalMap.hpp:49
void emit(Key const &key, Args const &... args)
Emit the signal with the given key and arguments.
Definition TrackableSignalMap.hpp:103
bool disconnect(ConnectionPtr trackablePtr, Key const &key)
Disconnect a slot from the key's associative signal.
Definition TrackableSignalMap.hpp:82
bool connectTrackableSlot(ConnectionSharedPtr const &trackable, Key const &key, std::function< void(Args...)> slot)
Connect a slot to the signal, the slot will be called when the signal is emitted and trackable is sti...
Definition TrackableSignalMap.hpp:68
A thread-safe class to manage a signal and its tracking connections.
Definition TrackableSignal.hpp:44
A container for data that is protected by a mutex. Inspired by Mutex in Rust.
Definition Mutex.hpp:96
Definition TrackableSignalMap.hpp:37