Molybden API
Loading...
Searching...
No Matches
event_impl.hpp
1// Copyright (c) 2000-2023 TeamDev Ltd. 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 {
15namespace internal {
16
17template <typename T>
18class EventImpl : SubscriptionObserver {
19 public:
20 ~EventImpl() override;
21
22 using Signature = void(const T& e);
23
24 std::shared_ptr<Subscription> operator+=(std::function<Signature> observer);
25
26 void notify(const T& args);
27
28 void reset();
29
30 private:
31 void onCanceled(int32_t id) override;
32
33 std::vector<std::shared_ptr<internal::SubscriptionImpl<T>>> subscriptions();
34
35 std::mutex subscriptions_mutex_;
36 std::unordered_map<int32_t, std::shared_ptr<internal::SubscriptionImpl<T>>>
37 subscriptions_;
38};
39
40template <typename T>
41std::vector<std::shared_ptr<internal::SubscriptionImpl<T>>>
42EventImpl<T>::subscriptions() {
43 std::vector<std::shared_ptr<internal::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 std::lock_guard<std::mutex> guard(subscriptions_mutex_);
53 for (auto subscription : subscriptions()) {
54 subscription->setObserver(nullptr);
55 }
56}
57
58template <typename T>
59std::shared_ptr<Subscription> EventImpl<T>::operator+=(
60 std::function<Signature> observer) {
61 static std::atomic<int32_t> next_id(0);
62 int32_t id = ++next_id;
63 auto subscription = std::make_shared<internal::SubscriptionImpl<T>>(id,
64 observer);
65 subscription->setObserver(this);
66 {
67 std::lock_guard<std::mutex> guard(subscriptions_mutex_);
68 subscriptions_.emplace(id, subscription);
69 }
70 return subscription;
71}
72
73template <typename T>
74void EventImpl<T>::notify(const T& args) {
75 std::lock_guard<std::mutex> guard(subscriptions_mutex_);
76 for (auto subscription : subscriptions()) {
77 subscription->notify(args);
78 }
79}
80
81template <typename T>
82void EventImpl<T>::reset() {
83 std::lock_guard<std::mutex> guard(subscriptions_mutex_);
84 subscriptions_.clear();
85}
86
87template <typename T>
88void EventImpl<T>::onCanceled(int32_t id) {
89 std::lock_guard<std::mutex> guard(subscriptions_mutex_);
90 subscriptions_.erase(id);
91}
92
93} // namespace internal
94} // namespace molybden
95
96#endif // MOLYBDEN_EVENT_IMPL_HPP