Clio  develop
The XRP Ledger API server.
Loading...
Searching...
No Matches
TrackableSignalMap.hpp
1#pragma once
2
3#include "feed/impl/TrackableSignal.hpp"
4#include "util/Mutex.hpp"
5
6#include <boost/signals2.hpp>
7
8#include <concepts>
9#include <cstddef>
10#include <functional>
11#include <memory>
12#include <mutex>
13#include <unordered_map>
14
15namespace feed::impl {
16
17template <typename T>
18concept Hashable = requires(T a) {
19 { std::hash<T>{}(a) } -> std::convertible_to<std::size_t>;
20};
21
29template <Hashable Key, typename Session, typename... Args>
31 using ConnectionPtr = Session*;
32 using ConnectionSharedPtr = std::shared_ptr<Session>;
33 using SignalType = TrackableSignal<Session, Args...>;
34 using SignalPtr = std::shared_ptr<SignalType>;
35 using SignalsMap = std::unordered_map<Key, SignalPtr>;
36
37 util::Mutex<SignalsMap> signalsMap_;
38
39public:
52 bool
54 ConnectionSharedPtr const& trackable,
55 Key const& key,
56 std::function<void(Args...)> slot
57 )
58 {
59 auto map = signalsMap_.template lock<std::scoped_lock>();
60 auto it = map->find(key);
61 if (it == map->end()) {
62 auto signal = std::make_shared<SignalType>();
63 it = map->emplace(key, std::move(signal)).first;
64 }
65
66 return it->second->connectTrackableSlot(trackable, slot);
67 }
68
77 bool
78 disconnect(ConnectionPtr trackablePtr, Key const& key)
79 {
80 auto map = signalsMap_.template lock<std::scoped_lock>();
81 auto const it = map->find(key);
82 if (it == map->end())
83 return false;
84
85 auto const disconnected = it->second->disconnect(trackablePtr);
86 // clean the map if there is no connection left.
87 if (disconnected && it->second->count() == 0)
88 map->erase(it);
89
90 return disconnected;
91 }
92
99 void
100 emit(Key const& key, Args const&... args)
101 {
102 auto const signal = [this, &key]() -> SignalPtr {
103 auto map = signalsMap_.template lock<std::scoped_lock>();
104 auto const it = map->find(key);
105 return it == map->end() ? nullptr : it->second;
106 }();
107
108 if (signal != nullptr)
109 signal->emit(args...);
110 }
111};
112} // namespace feed::impl
Class to manage a map of key and its associative signal.
Definition TrackableSignalMap.hpp:30
void emit(Key const &key, Args const &... args)
Emit the signal with the given key and arguments.
Definition TrackableSignalMap.hpp:100
bool disconnect(ConnectionPtr trackablePtr, Key const &key)
Disconnect a slot from the key's associative signal.
Definition TrackableSignalMap.hpp:78
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:53
A thread-safe class to manage a signal and its tracking connections.
Definition TrackableSignal.hpp:26
A container for data that is protected by a mutex. Inspired by Mutex in Rust.
Definition Mutex.hpp:82
Definition TrackableSignalMap.hpp:18