CommonLibSSE (powerof3)
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  struct BSContainer
18  {
19  enum class ForEachResult
20  {
21  kContinue = 0,
22  kStop = 1
23  };
24  };
25 
26  template <class Event>
28  {
29  public:
31 
33  sinks(),
36  lock(),
37  notifying(false),
38  pad51(0),
39  pad52(0),
40  pad54(0)
41  {}
42 
43  void AddEventSink(Sink* a_eventSink)
44  {
45  if (!a_eventSink) {
46  return;
47  }
48 
49  BSSpinLockGuard locker(lock);
50 
51  if (notifying) {
52  if (std::find(pendingRegisters.begin(), pendingRegisters.end(), a_eventSink) == pendingRegisters.end()) {
53  pendingRegisters.push_back(a_eventSink);
54  }
55  } else {
56  if (std::find(sinks.begin(), sinks.end(), a_eventSink) == sinks.end()) {
57  sinks.push_back(a_eventSink);
58  }
59  }
60 
61  auto it = std::find(pendingUnregisters.begin(), pendingUnregisters.end(), a_eventSink);
62  if (it != pendingUnregisters.end()) {
63  pendingUnregisters.erase(it);
64  }
65  }
66 
67  void RemoveEventSink(Sink* a_eventSink)
68  {
69  if (!a_eventSink) {
70  return;
71  }
72 
73  BSSpinLockGuard locker(lock);
74 
75  if (notifying) {
76  if (std::find(pendingUnregisters.begin(), pendingUnregisters.end(), a_eventSink) == pendingUnregisters.end()) {
77  pendingUnregisters.push_back(a_eventSink);
78  }
79  } else {
80  auto it = std::find(sinks.begin(), sinks.end(), a_eventSink);
81  if (it != sinks.end()) {
82  sinks.erase(it);
83  }
84  }
85 
86  auto it = std::find(pendingRegisters.begin(), pendingRegisters.end(), a_eventSink);
87  if (it != pendingRegisters.end()) {
88  pendingRegisters.erase(it);
89  }
90  }
91 
92  void SendEvent(const Event* a_event)
93  {
94  BSSpinLockGuard locker(lock);
95 
96  const auto wasNotifying = notifying;
97  notifying = true;
98  if (!wasNotifying && !pendingRegisters.empty()) {
99  for (auto& toAdd : pendingRegisters) {
100  if (std::find(sinks.begin(), sinks.end(), toAdd) == sinks.end()) {
101  sinks.push_back(toAdd);
102  }
103  }
104  pendingRegisters.clear();
105  }
106 
107  for (auto& sink : sinks) {
108  if (std::find(pendingUnregisters.begin(), pendingUnregisters.end(), sink) == pendingUnregisters.end()) {
109  if (sink->ProcessEvent(a_event, this) == BSEventNotifyControl::kStop) {
110  break;
111  }
112  }
113  }
114 
115  notifying = wasNotifying;
116  if (!wasNotifying && !pendingUnregisters.empty()) {
117  for (auto& toRemove : pendingUnregisters) {
118  auto it = std::find(sinks.begin(), sinks.end(), toRemove);
119  if (it != sinks.end()) {
120  sinks.erase(it);
121  }
122  }
123  pendingUnregisters.clear();
124  }
125  }
126 
127  void operator()(const Event* a_event)
128  {
129  return SendEvent(a_event);
130  }
131 
132  // members
136  mutable BSSpinLock lock; // 48
137  bool notifying; // 50
138  std::uint8_t pad51; // 51
139  std::uint16_t pad52; // 52
140  std::uint32_t pad54; // 54
141  };
142  static_assert(sizeof(BSTEventSource<void*>) == 0x58);
143 
144  template <class Event>
146  {
147  public:
148  virtual ~BSTEventSink() = default; // 00
149  virtual BSEventNotifyControl ProcessEvent(const Event* a_event, BSTEventSource<Event>* a_eventSource) = 0; // 01
150  };
151  static_assert(sizeof(BSTEventSink<void>) == 0x8);
152 }
Definition: BSAtomic.h:92
Definition: BSAtomic.h:49
Definition: BSTArray.h:377
Definition: BSTEvent.h:146
virtual ~BSTEventSink()=default
virtual BSEventNotifyControl ProcessEvent(const Event *a_event, BSTEventSource< Event > *a_eventSource)=0
Definition: BSTEvent.h:28
BSTEventSource()
Definition: BSTEvent.h:32
std::uint16_t pad52
Definition: BSTEvent.h:139
BSSpinLock lock
Definition: BSTEvent.h:136
void SendEvent(const Event *a_event)
Definition: BSTEvent.h:92
std::uint8_t pad51
Definition: BSTEvent.h:138
void RemoveEventSink(Sink *a_eventSink)
Definition: BSTEvent.h:67
void AddEventSink(Sink *a_eventSink)
Definition: BSTEvent.h:43
std::uint32_t pad54
Definition: BSTEvent.h:140
bool notifying
Definition: BSTEvent.h:137
BSTArray< Sink * > sinks
Definition: BSTEvent.h:133
BSTArray< Sink * > pendingRegisters
Definition: BSTEvent.h:134
void operator()(const Event *a_event)
Definition: BSTEvent.h:127
BSTArray< Sink * > pendingUnregisters
Definition: BSTEvent.h:135
Definition: AbsorbEffect.h:6
BSEventNotifyControl
Definition: BSTEvent.h:12
Definition: BSTEvent.h:18
ForEachResult
Definition: BSTEvent.h:20