CommonLibSSE (powerof3)
RegistrationSet.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "RE/B/BGSBaseAlias.h"
4 #include "RE/B/BSFixedString.h"
7 #include "RE/T/TESForm.h"
8 #include "RE/T/TypeTraits.h"
9 #include "RE/V/VirtualMachine.h"
10 
11 #include "SKSE/API.h"
13 #include "SKSE/Interfaces.h"
14 
15 namespace SKSE
16 {
17  namespace Impl
18  {
20  {
21  public:
22  RegistrationSetBase() = delete;
23  RegistrationSetBase(const std::string_view& a_eventName);
27 
30 
31  bool Register(const RE::TESForm* a_form);
32  bool Register(const RE::BGSBaseAlias* a_alias);
33  bool Register(const RE::ActiveEffect* a_effect);
34  bool Unregister(const RE::TESForm* a_form);
35  bool Unregister(const RE::BGSBaseAlias* a_alias);
36  bool Unregister(const RE::ActiveEffect* a_effect);
37  bool Unregister(RE::VMHandle a_handle);
38  void Clear();
39  bool Save(SerializationInterface* a_intfc, std::uint32_t a_type, std::uint32_t a_version);
40  bool Save(SerializationInterface* a_intfc);
41  bool Load(SerializationInterface* a_intfc);
43 
44  protected:
45  using Lock = std::recursive_mutex;
46  using Locker = std::lock_guard<Lock>;
47 
48  bool Register(const void* a_object, RE::VMTypeID a_typeID);
49  bool Unregister(const void* a_object, RE::VMTypeID a_typeID);
50 
51  std::set<RE::VMHandle> _handles;
53  mutable Lock _lock;
54  };
55 
56  template <class Enable, class... Args>
58 
59  template <class... Args>
61  std::enable_if_t<
62  std::conjunction_v<
63  RE::BSScript::is_return_convertible<Args>...>>,
64  Args...> :
65  public RegistrationSetBase
66  {
67  private:
68  using super = RegistrationSetBase;
69 
70  public:
71  RegistrationSet() = delete;
72  RegistrationSet(const RegistrationSet&) = default;
74 
75  inline RegistrationSet(const std::string_view& a_eventName) :
76  super(a_eventName)
77  {}
78 
79  ~RegistrationSet() = default;
80 
83 
84  inline void SendEvent(Args... a_args)
85  {
86  RE::BSFixedString eventName(_eventName);
87 
89  for (auto& handle : _handles) {
90  auto copy = std::make_tuple(a_args...);
91  std::apply([&](auto&&... a_copy) {
92  auto args = RE::MakeFunctionArguments(std::forward<Args>(a_copy)...);
93  vm->SendEvent(handle, eventName, args);
94  },
95  copy);
96  }
97  }
98 
99  inline void QueueEvent(Args... a_args)
100  {
101  std::tuple args(VMArg(std::forward<Args>(a_args))...);
102  auto task = GetTaskInterface();
103  assert(task);
104  if (task) {
105  task->AddTask([args, this]() mutable {
106  SendEvent_Tuple(std::move(args), index_sequence_for_tuple<decltype(args)>{});
107  });
108  }
109  }
110 
111  private:
112  template <class Tuple, std::size_t... I>
113  inline void SendEvent_Tuple(Tuple&& a_tuple, std::index_sequence<I...>)
114  {
115  SendEvent(std::get<I>(std::forward<Tuple>(a_tuple)).Unpack()...);
116  }
117  };
118 
119  template <>
121  {
122  private:
123  using super = RegistrationSetBase;
124 
125  public:
126  RegistrationSet() = delete;
127  RegistrationSet(const RegistrationSet&) = default;
129 
130  inline RegistrationSet(const std::string_view& a_eventName) :
131  super(a_eventName)
132  {}
133 
134  ~RegistrationSet() = default;
135 
138 
139  inline void SendEvent()
140  {
141  RE::BSFixedString eventName(_eventName);
142 
144  if (vm) {
145  for (auto& handle : _handles) {
146  auto args = RE::MakeFunctionArguments();
147  vm->SendEvent(handle, eventName, args);
148  }
149  }
150  }
151 
152  inline void QueueEvent()
153  {
154  auto task = GetTaskInterface();
155  assert(task);
156  task->AddTask([this]() {
157  SendEvent();
158  });
159  }
160  };
161  }
162 
163  template <class... Args>
164  using RegistrationSet = Impl::RegistrationSet<void, Args...>;
165 }
Definition: ActiveEffect.h:27
Definition: BGSBaseAlias.h:12
static VirtualMachine * GetSingleton()
Definition: TESForm.h:36
Definition: RegistrationSet.h:20
std::string _eventName
Definition: RegistrationSet.h:52
bool Register(const RE::ActiveEffect *a_effect)
RegistrationSetBase(const std::string_view &a_eventName)
bool Unregister(const RE::ActiveEffect *a_effect)
void Revert(SerializationInterface *)
bool Save(SerializationInterface *a_intfc)
RegistrationSetBase & operator=(const RegistrationSetBase &a_rhs)
bool Register(const RE::BGSBaseAlias *a_alias)
std::lock_guard< Lock > Locker
Definition: RegistrationSet.h:46
bool Unregister(RE::VMHandle a_handle)
bool Register(const RE::TESForm *a_form)
bool Unregister(const RE::TESForm *a_form)
bool Register(const void *a_object, RE::VMTypeID a_typeID)
std::set< RE::VMHandle > _handles
Definition: RegistrationSet.h:51
Lock _lock
Definition: RegistrationSet.h:53
bool Unregister(const void *a_object, RE::VMTypeID a_typeID)
std::recursive_mutex Lock
Definition: RegistrationSet.h:45
bool Save(SerializationInterface *a_intfc, std::uint32_t a_type, std::uint32_t a_version)
bool Load(SerializationInterface *a_intfc)
RegistrationSetBase & operator=(RegistrationSetBase &&a_rhs)
RegistrationSetBase(const RegistrationSetBase &a_rhs)
RegistrationSetBase(RegistrationSetBase &&a_rhs)
bool Unregister(const RE::BGSBaseAlias *a_alias)
RegistrationSet(const std::string_view &a_eventName)
Definition: RegistrationSet.h:130
void QueueEvent()
Definition: RegistrationSet.h:152
void SendEvent()
Definition: RegistrationSet.h:139
RegistrationSet & operator=(RegistrationSet &&)=default
RegistrationSet(const RegistrationSet &)=default
RegistrationSet & operator=(const RegistrationSet &)=default
RegistrationSet(RegistrationSet &&)=default
Definition: RegistrationSet.h:57
Definition: Interfaces.h:82
auto make_tuple(T1 &&a_first, T2 &&a_second)
Definition: BSTTuple.h:187
std::uint32_t VMTypeID
Definition: BSCoreTypes.h:9
std::uint64_t VMHandle
Definition: BSCoreTypes.h:7
BSScript::IFunctionArguments * MakeFunctionArguments(Args &&... a_args)
Definition: FunctionArguments.h:80
VMArg(T &&) -> VMArg< T >
string(const CharT(&)[N]) -> string< CharT, N - 1 >
Definition: API.h:14
const TaskInterface * GetTaskInterface() noexcept
Definition: EffectArchetypes.h:65
Definition: RegistrationTraits.h:40