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 private:
29 void onCanceled(int32_t id) override;
30
31 std::vector<std::shared_ptr<internal::SubscriptionImpl<T>>> subscriptions();
32
33 std::mutex subscriptions_mutex_;
34 std::unordered_map<int32_t, std::shared_ptr<internal::SubscriptionImpl<T>>>
35 subscriptions_;
36};
37
38template <typename T>
39std::vector<std::shared_ptr<internal::SubscriptionImpl<T>>>
40EventImpl<T>::subscriptions() {
41 std::vector<std::shared_ptr<internal::SubscriptionImpl<T>>> subscriptions;
42 for (auto it : subscriptions_) {
43 subscriptions.push_back(it.second);
44 }
45 return subscriptions;
46}
47
48template <typename T>
49EventImpl<T>::~EventImpl() {
50 std::lock_guard<std::mutex> guard(subscriptions_mutex_);
51 for (auto subscription : subscriptions()) {
52 subscription->setObserver(nullptr);
53 }
54}
55
56template <typename T>
57std::shared_ptr<Subscription> EventImpl<T>::operator+=(
58 std::function<Signature> observer) {
59 static std::atomic<int32_t> next_id(0);
60 int32_t id = ++next_id;
61 auto subscription = std::make_shared<internal::SubscriptionImpl<T>>(id,
62 observer);
63 subscription->setObserver(this);
64 {
65 std::lock_guard<std::mutex> 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<std::mutex> guard(subscriptions_mutex_);
74 for (auto subscription : subscriptions()) {
75 subscription->notify(args);
76 }
77}
78
79template <typename T>
80void EventImpl<T>::onCanceled(int32_t id) {
81 std::lock_guard<std::mutex> guard(subscriptions_mutex_);
82 subscriptions_.erase(id);
83}
84
85} // namespace internal
86} // namespace molybden
87
88#endif // MOLYBDEN_EVENT_IMPL_HPP