CommonLibSSE (powerof3)
Loading...
Searching...
No Matches
BSTEvent.h
Go to the documentation of this file.
1#pragma once
2
3#include "RE/B/BSAtomic.h"
4#include "RE/B/BSTArray.h"
5
6namespace RE
7{
8 template <class T>
9 class BSTEventSink;
10
12 {
13 kContinue = 0,
14 kStop = 1
15 };
16
17 template <class Event>
19 {
20 public:
22
24 sinks(),
27 lock(),
28 notifying(false),
29 pad51(0),
30 pad52(0),
31 pad54(0)
32 {}
33
34 void AddEventSink(Sink* a_eventSink)
35 {
36 if (!a_eventSink) {
37 return;
38 }
39
40 BSSpinLockGuard locker(lock);
41
42 if (notifying) {
43 if (std::find(pendingRegisters.begin(), pendingRegisters.end(), a_eventSink) == pendingRegisters.end()) {
44 pendingRegisters.push_back(a_eventSink);
45 }
46 } else {
47 if (std::find(sinks.begin(), sinks.end(), a_eventSink) == sinks.end()) {
48 sinks.push_back(a_eventSink);
49 }
50 }
51
52 auto it = std::find(pendingUnregisters.begin(), pendingUnregisters.end(), a_eventSink);
53 if (it != pendingUnregisters.end()) {
54 pendingUnregisters.erase(it);
55 }
56 }
57
58 template <class SinkEvent>
60 {
61 AddEventSink(a_sink);
62 }
63
76 void PrependEventSink(Sink* a_eventSink)
77 {
78 if (!a_eventSink) {
79 return;
80 }
81
82 BSSpinLockGuard locker(lock);
83
84 if (notifying) {
85 if (std::find(pendingRegisters.begin(), pendingRegisters.end(), a_eventSink) == pendingRegisters.end()) {
86 pendingRegisters.push_front(a_eventSink);
87 }
88 } else {
89 if (std::find(sinks.begin(), sinks.end(), a_eventSink) == sinks.end()) {
90 sinks.push_front(a_eventSink);
91 }
92 }
93
94 auto it = std::find(pendingUnregisters.begin(), pendingUnregisters.end(), a_eventSink);
95 if (it != pendingUnregisters.end()) {
96 pendingUnregisters.erase(it);
97 }
98 }
99
100 template <class SinkEvent>
102 {
103 PrependEventSink(a_sink);
104 }
105
106 void RemoveEventSink(Sink* a_eventSink)
107 {
108 if (!a_eventSink) {
109 return;
110 }
111
112 BSSpinLockGuard locker(lock);
113
114 if (notifying) {
115 if (std::find(pendingUnregisters.begin(), pendingUnregisters.end(), a_eventSink) == pendingUnregisters.end()) {
116 pendingUnregisters.push_back(a_eventSink);
117 }
118 } else {
119 auto it = std::find(sinks.begin(), sinks.end(), a_eventSink);
120 if (it != sinks.end()) {
121 sinks.erase(it);
122 }
123 }
124
125 auto it = std::find(pendingRegisters.begin(), pendingRegisters.end(), a_eventSink);
126 if (it != pendingRegisters.end()) {
127 pendingRegisters.erase(it);
128 }
129 }
130
131 void SendEvent(const Event* a_event)
132 {
133 BSSpinLockGuard locker(lock);
134
135 const auto wasNotifying = notifying;
136 notifying = true;
137 if (!wasNotifying && !pendingRegisters.empty()) {
138 for (auto& toAdd : pendingRegisters) {
139 if (std::find(sinks.begin(), sinks.end(), toAdd) == sinks.end()) {
140 sinks.push_back(toAdd);
141 }
142 }
143 pendingRegisters.clear();
144 }
145
146 for (auto& sink : sinks) {
147 if (std::find(pendingUnregisters.begin(), pendingUnregisters.end(), sink) == pendingUnregisters.end()) {
148 if (sink->ProcessEvent(a_event, this) == BSEventNotifyControl::kStop) {
149 break;
150 }
151 }
152 }
153
154 notifying = wasNotifying;
155 if (!wasNotifying && !pendingUnregisters.empty()) {
156 for (auto& toRemove : pendingUnregisters) {
157 auto it = std::find(sinks.begin(), sinks.end(), toRemove);
158 if (it != sinks.end()) {
159 sinks.erase(it);
160 }
161 }
162 pendingUnregisters.clear();
163 }
164 }
165
166 void operator()(const Event* a_event)
167 {
168 return SendEvent(a_event);
169 }
170
171 // members
175 mutable BSSpinLock lock; // 48
176 bool notifying; // 50
177 std::uint8_t pad51; // 51
178 std::uint16_t pad52; // 52
179 std::uint32_t pad54; // 54
180 };
181 static_assert(sizeof(BSTEventSource<void*>) == 0x58);
182
183 template <class Event>
185 {
186 public:
187 virtual ~BSTEventSink() = default; // 00
188 virtual BSEventNotifyControl ProcessEvent(const Event* a_event, BSTEventSource<Event>* a_eventSource) = 0; // 01
189 };
190 static_assert(sizeof(BSTEventSink<void>) == 0x8);
191}
Definition BSAtomic.h:135
Definition BSAtomic.h:92
Definition BSTArray.h:378
Definition BSTEvent.h:185
virtual ~BSTEventSink()=default
virtual BSEventNotifyControl ProcessEvent(const Event *a_event, BSTEventSource< Event > *a_eventSource)=0
Definition BSTEvent.h:19
BSTEventSource()
Definition BSTEvent.h:23
std::uint16_t pad52
Definition BSTEvent.h:178
BSSpinLock lock
Definition BSTEvent.h:175
void PrependEventSink(BSTEventSink< SinkEvent > *a_sink)
Definition BSTEvent.h:101
void PrependEventSink(Sink *a_eventSink)
Definition BSTEvent.h:76
void SendEvent(const Event *a_event)
Definition BSTEvent.h:131
std::uint8_t pad51
Definition BSTEvent.h:177
void RemoveEventSink(Sink *a_eventSink)
Definition BSTEvent.h:106
void AddEventSink(Sink *a_eventSink)
Definition BSTEvent.h:34
std::uint32_t pad54
Definition BSTEvent.h:179
bool notifying
Definition BSTEvent.h:176
BSTArray< Sink * > sinks
Definition BSTEvent.h:172
BSTArray< Sink * > pendingRegisters
Definition BSTEvent.h:173
void operator()(const Event *a_event)
Definition BSTEvent.h:166
BSTArray< Sink * > pendingUnregisters
Definition BSTEvent.h:174
void AddEventSink(BSTEventSink< SinkEvent > *a_sink)
Definition BSTEvent.h:59
Definition AbsorbEffect.h:6
BSEventNotifyControl
Definition BSTEvent.h:12