载入中...
搜索中...
未找到
Subscription.h
浏览该文件的文档.
1#pragma once
2
3#include "common/Export.h"
4
5#include <algorithm>
6#include <cstddef>
7#include <cstdint>
8#include <functional>
9#include <memory>
10#include <utility>
11#include <vector>
12
13namespace eve {
14
28public:
29 using Cancel = std::function<void()>;
30
32 Subscription() noexcept = default;
33
38 explicit Subscription(Cancel cancel);
39
40 Subscription(const Subscription &) = delete;
41 Subscription &operator=(const Subscription &) = delete;
43 Subscription(Subscription &&other) noexcept;
45 Subscription &operator=(Subscription &&other) noexcept;
47 ~Subscription();
48
50 void dispose() noexcept;
51
53 bool disposed() const noexcept { return disposed_; }
54
56 bool isDisposed() const noexcept { return disposed(); }
57
58private:
59 Cancel cancel_;
60 bool disposed_ = true;
61};
62
80template <typename... Args>
82class Observer {
83public:
84 using Callback = std::function<void(const Args &...)>;
85
87 Observer() : state_(std::make_shared<State>()) {}
88 Observer(const Observer &) = delete;
89 Observer &operator=(const Observer &) = delete;
90 Observer(Observer &&) = delete;
93 ~Observer() = default;
94
101 [[nodiscard("retain Subscription or explicitly dispose it")]] Subscription subscribe(Callback callback) {
103 if (!callback) return {};
104
105 auto entry = std::make_shared<Entry>();
106 entry->id = state_->nextId++;
107 entry->callback = std::move(callback);
108 state_->entries.push_back(entry);
109
110 const std::weak_ptr<State> weakState = state_;
112 return Subscription([weakState, entry]() noexcept {
113 entry->active = false;
114 if (const auto state = weakState.lock()) {
116 std::erase_if(state->entries,
117 [&entry](const std::shared_ptr<Entry> &candidate) { return candidate == entry; });
118 }
119 });
120 }
121
127 void notify(const Args &...args) {
128 const auto snapshot = state_->entries;
129 for (const auto &entry : snapshot) {
130 if (!entry->active || !entry->callback) continue;
131 // Copy outside any registry lock (the registry deliberately has no
132 // lock) so callback destruction/re-entrancy cannot invalidate the
133 // callable being invoked.
134 Callback callback = entry->callback;
135 if (entry->active && callback) callback(args...);
136 }
137 }
138
148 template <typename FailureHandler>
150 [[nodiscard]] std::size_t notifyChecked(FailureHandler &&onFailure, const Args &...args) {
151 const auto snapshot = state_->entries;
152 std::size_t failures = 0;
153 for (const auto &entry : snapshot) {
154 if (!entry->active || !entry->callback) continue;
155 Callback callback = entry->callback;
156 if (!entry->active || !callback) continue;
157 try {
159 callback(args...);
160 } catch (...) {
161 ++failures;
162 std::forward<FailureHandler>(onFailure)();
163 }
164 }
165 return failures;
166 }
167
169 std::size_t size() const noexcept {
170 std::size_t count = 0;
171 for (const auto &entry : state_->entries)
172 if (entry->active) ++count;
173 return count;
174 }
175
179 std::erase_if(state_->entries, [](const std::shared_ptr<Entry> &entry) { return !entry->active; });
180 }
181
182private:
183 struct Entry {
184 std::uint64_t id = 0;
185 Callback callback;
186 bool active = true;
187 };
188
189 struct State {
190 std::uint64_t nextId = 1;
191 std::vector<std::shared_ptr<Entry>> entries;
192 };
193
194 std::shared_ptr<State> state_;
195};
196
197} // namespace eve
bool & active
std::unordered_map< std::string, QuestRuntime > entries
#define EVENGINE_API_FOUNDATION
每个链接组(link group)各自的导出宏。
Definition Export.h:106
std::uint32_t count
ViewPreparation callback
Thread-affine callback registry with mutation-safe dispatch.
Subscription subscribe(Callback callback)
Registers a callback owned by the returned Subscription.
std::size_t notifyChecked(FailureHandler &&onFailure, const Args &...args)
Notifies all snapshotted callbacks and contains unknown exceptions.
Observer(Observer &&)=delete
Observer & operator=(const Observer &)=delete
std::function< void(const Args &...)> Callback
void compactInactive()
Removes inactive entries without invoking user callbacks.
Observer()
Constructs a Observer.
std::size_t size() const noexcept
Returns the number of currently active registrations.
Observer(const Observer &)=delete
~Observer()=default
Releases Observer resources.
Observer & operator=(Observer &&)=delete
void notify(const Args &...args)
Synchronously notifies a snapshot of current registrations.
Move-only RAII token that owns one observer registration.
Subscription() noexcept=default
Creates an inactive token.
bool isDisposed() const noexcept
Compatibility spelling for disposed().
std::function< void()> Cancel
Build metadata (engine git commit, build time, third-party version).
Definition Build.cpp:16