Skip to content

Commit a95c1ce

Browse files
committed
brenta: implemented signal manager
1 parent c8ea015 commit a95c1ce

File tree

4 files changed

+145
-2
lines changed

4 files changed

+145
-2
lines changed

TODO

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +0,0 @@
1-
- implement signals for node scripts

external/tenno-tl

include/brenta/signal_manager.hpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// SPDX-License-Identifier: MIT
2+
// Author: Giovanni Santini
3+
// Mail: giovanni.santini@proton.me
4+
// Github: @San7o
5+
6+
#pragma once
7+
8+
#include <string>
9+
#include <unordered_map>
10+
#include <utility>
11+
12+
#include <tenno/vector.hpp>
13+
14+
namespace brenta
15+
{
16+
17+
class SignalManager
18+
{
19+
public:
20+
21+
using SignalId = std::string;
22+
using Message = std::string;
23+
using ConnectionId = int;
24+
using Callback = std::function<void(Message)>;
25+
26+
struct Event;
27+
class Subscription;
28+
29+
SignalManager() = delete;
30+
~SignalManager() = delete;
31+
32+
static void emit(const Event& event);
33+
34+
static Subscription subscribe(const SignalId& id, Callback callback);
35+
static void unsubscribe(const Subscription &sub);
36+
37+
// Process all pending events
38+
static void update();
39+
40+
private:
41+
42+
static tenno::vector<Event> pending_events;
43+
static std::unordered_map<SignalId,
44+
tenno::vector<std::pair<ConnectionId,
45+
Callback>>> registry;
46+
47+
};
48+
49+
struct SignalManager::Event
50+
{
51+
SignalId id;
52+
Message message;
53+
};
54+
55+
class SignalManager::Subscription
56+
{
57+
public:
58+
59+
friend class SignalManager;
60+
61+
Subscription() = delete;
62+
~Subscription();
63+
64+
private:
65+
66+
Subscription(SignalId signal_id, ConnectionId connection_id)
67+
: signal_id(signal_id), connection_id(connection_id) {}
68+
69+
SignalId signal_id;
70+
ConnectionId connection_id;
71+
};
72+
73+
74+
} // namespace brenta

src/signal_manager.cpp

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// SPDX-License-Identifier: MIT
2+
// Author: Giovanni Santini
3+
// Mail: giovanni.santini@proton.me
4+
// Github: @San7o
5+
6+
#include <brenta/signal_manager.hpp>
7+
8+
using namespace brenta;
9+
10+
//
11+
// Static storage
12+
//
13+
14+
tenno::vector<SignalManager::Event> SignalManager::pending_events;
15+
std::unordered_map<SignalManager::SignalId,
16+
tenno::vector<std::pair<SignalManager::ConnectionId,
17+
SignalManager::Callback>>>
18+
SignalManager::registry;
19+
20+
//
21+
// Member functions
22+
//
23+
24+
void SignalManager::emit(const SignalManager::Event &event)
25+
{
26+
SignalManager::pending_events.push_back(event);
27+
}
28+
29+
SignalManager::Subscription
30+
SignalManager::subscribe(const SignalManager::SignalId &id,
31+
SignalManager::Callback callback)
32+
{
33+
static ConnectionId connection_id = 0;
34+
connection_id++;
35+
36+
SignalManager::registry[id].push_back(std::make_tuple(connection_id, callback));
37+
return Subscription(id, connection_id);
38+
}
39+
40+
void SignalManager::unsubscribe(const SignalManager::Subscription &sub)
41+
{
42+
auto& entries = SignalManager::registry[sub.signal_id];
43+
for (auto it = entries.begin(); it != entries.end(); ++it)
44+
{
45+
if (std::get<0>(*it) == sub.connection_id)
46+
{
47+
entries.erase(it);
48+
break;
49+
}
50+
}
51+
}
52+
53+
void SignalManager::update()
54+
{
55+
for (auto& event : SignalManager::pending_events)
56+
{
57+
if (!SignalManager::registry.contains(event.id)) continue;
58+
59+
for (auto& [_, callback] : SignalManager::registry[event.id])
60+
{
61+
callback(event.message);
62+
}
63+
}
64+
}
65+
66+
SignalManager::Subscription::~Subscription()
67+
{
68+
if (this->connection_id == 0) return;
69+
SignalManager::unsubscribe(*this);
70+
}

0 commit comments

Comments
 (0)