Molybden API
Loading...
Searching...
No Matches
event_impl.hpp
1// Copyright (c) 2000-2024 TeamDev. All rights reserved.
2// TeamDev PROPRIETARY and CONFIDENTIAL.
3// Use is subject to license terms.
4
5#ifndef MOLYBDEN_EVENT_IMPL_HPP
6#define MOLYBDEN_EVENT_IMPL_HPP
7
8#include <memory>
9#include <mutex>
10#include <unordered_map>
11
12#include "molybden/base/internal/subscription_impl.hpp"
13
14namespace molybden::internal {
15
16template <typename T>
17class EventImpl : SubscriptionObserver {
18 public:
19 ~EventImpl() override;
20
21 using Signature = void(const T& e);
22
23 std::shared_ptr<Subscription> operator+=(std::function<Signature> observer);
24
25 void notify(const T& args);
26
27 void reset();
28
29 private:
30 void onCanceled(int32_t id) override;
31
32 std::vector<std::shared_ptr<SubscriptionImpl<T>>> subscriptions();
33
34 std::recursive_mutex subscriptions_mutex_;
35 std::unordered_map<int32_t, std::shared_ptr<SubscriptionImpl<T>>>
36 subscriptions_;
37};
38
39template <typename T>
40std::vector<std::shared_ptr<SubscriptionImpl<T>>>
41EventImpl<T>::subscriptions() {
42 std::lock_guard guard(subscriptions_mutex_);
43 std::vector<std::shared_ptr<SubscriptionImpl<T>>> subscriptions;
44 for (auto it : subscriptions_) {
45 subscriptions.push_back(it.second);
46 }
47 return subscriptions;
48}
49
50template <typename T>
51EventImpl<T>::~EventImpl() {
52 for (auto subscription : subscriptions()) {
53 subscription->setObserver(nullptr);
54 }
55}
56
57template <typename T>
58std::shared_ptr<Subscription> EventImpl<T>::operator+=(
59 std::function<Signature> observer) {
60 static std::atomic next_id(0);
61 int32_t id = ++next_id;
62 auto subscription = std::make_shared<SubscriptionImpl<T>>(id, observer);
63 subscription->setObserver(this);
64 {
65 std::lock_guard guard(subscriptions_mutex_);
66 subscriptions_.emplace(id, subscription);
67 }
68 return subscription;
69}
70
71template <typename T>
72void EventImpl<T>::notify(const T& args) {
73 std::lock_guard guard(subscriptions_mutex_);
74 for (auto subscription : subscriptions()) {
75 subscription->notify(args);
76 }
77}
78
79template <typename T>
80void EventImpl<T>::reset() {
81 std::lock_guard guard(subscriptions_mutex_);
82 subscriptions_.clear();
83}
84
85template <typename T>
86void EventImpl<T>::onCanceled(int32_t id) {
87 std::lock_guard guard(subscriptions_mutex_);
88 subscriptions_.erase(id);
89}
90} // namespace molybden::internal
91
92#endif // MOLYBDEN_EVENT_IMPL_HPP