CommonLibVR
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 
6 namespace 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 
64  void RemoveEventSink(Sink* a_eventSink)
65  {
66  if (!a_eventSink) {
67  return;
68  }
69 
70  BSSpinLockGuard locker(lock);
71 
72  if (notifying) {
73  if (std::find(pendingUnregisters.begin(), pendingUnregisters.end(), a_eventSink) == pendingUnregisters.end()) {
74  pendingUnregisters.push_back(a_eventSink);
75  }
76  } else {
77  auto it = std::find(sinks.begin(), sinks.end(), a_eventSink);
78  if (it != sinks.end()) {
79  sinks.erase(it);
80  }
81  }
82 
83  auto it = std::find(pendingRegisters.begin(), pendingRegisters.end(), a_eventSink);
84  if (it != pendingRegisters.end()) {
85  pendingRegisters.erase(it);
86  }
87  }
88 
89  void SendEvent(const Event* a_event)
90  {
91  BSSpinLockGuard locker(lock);
92 
93  const auto wasNotifying = notifying;
94  notifying = true;
95  if (!wasNotifying && !pendingRegisters.empty()) {
96  for (auto& toAdd : pendingRegisters) {
97  if (std::find(sinks.begin(), sinks.end(), toAdd) == sinks.end()) {
98  sinks.push_back(toAdd);
99  }
100  }
101  pendingRegisters.clear();
102  }
103 
104  for (auto& sink : sinks) {
105  if (std::find(pendingUnregisters.begin(), pendingUnregisters.end(), sink) == pendingUnregisters.end()) {
106  if (sink->ProcessEvent(a_event, this) == BSEventNotifyControl::kStop) {
107  break;
108  }
109  }
110  }
111 
112  notifying = wasNotifying;
113  if (!wasNotifying && !pendingUnregisters.empty()) {
114  for (auto& toRemove : pendingUnregisters) {
115  auto it = std::find(sinks.begin(), sinks.end(), toRemove);
116  if (it != sinks.end()) {
117  sinks.erase(it);
118  }
119  }
120  pendingUnregisters.clear();
121  }
122  }
123 
124  void operator()(const Event* a_event)
125  {
126  return SendEvent(a_event);
127  }
128 
129  // members
133  mutable BSSpinLock lock; // 48
134  bool notifying; // 50
135  std::uint8_t pad51; // 51
136  std::uint16_t pad52; // 52
137  std::uint32_t pad54; // 54
138  };
139  static_assert(sizeof(BSTEventSource<void*>) == 0x58);
140 
141  template <class Event>
143  {
144  public:
145  virtual ~BSTEventSink() = default; // 00
146  virtual BSEventNotifyControl ProcessEvent(const Event* a_event, BSTEventSource<Event>* a_eventSource) = 0; // 01
147  };
148  static_assert(sizeof(BSTEventSink<void>) == 0x8);
149 }
Definition: BSAtomic.h:135
Definition: BSAtomic.h:92
Definition: BSTArray.h:378
Definition: BSTEvent.h:143
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:136
BSSpinLock lock
Definition: BSTEvent.h:133
void SendEvent(const Event *a_event)
Definition: BSTEvent.h:89
std::uint8_t pad51
Definition: BSTEvent.h:135
void RemoveEventSink(Sink *a_eventSink)
Definition: BSTEvent.h:64
void AddEventSink(Sink *a_eventSink)
Definition: BSTEvent.h:34
std::uint32_t pad54
Definition: BSTEvent.h:137
bool notifying
Definition: BSTEvent.h:134
BSTArray< Sink * > sinks
Definition: BSTEvent.h:130
BSTArray< Sink * > pendingRegisters
Definition: BSTEvent.h:131
void operator()(const Event *a_event)
Definition: BSTEvent.h:124
BSTArray< Sink * > pendingUnregisters
Definition: BSTEvent.h:132
void AddEventSink(BSTEventSink< SinkEvent > *a_sink)
Definition: BSTEvent.h:59
Definition: AbsorbEffect.h:6
BSEventNotifyControl
Definition: BSTEvent.h:12