CommonLibVR
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 args = RE::MakeFunctionArguments(std::forward<Args>(a_args)...);
91  vm->SendEvent(handle, eventName, args);
92  }
93  }
94 
95  inline void QueueEvent(Args... a_args)
96  {
97  std::tuple args(VMArg(std::forward<Args>(a_args))...);
98  auto task = GetTaskInterface();
99  assert(task);
100  if (task) {
101  task->AddTask([args, this]() mutable {
102  SendEvent_Tuple(std::move(args), index_sequence_for_tuple<decltype(args)>{});
103  });
104  }
105  }
106 
107  private:
108  template <class Tuple, std::size_t... I>
109  inline void SendEvent_Tuple(Tuple&& a_tuple, std::index_sequence<I...>)
110  {
111  SendEvent(std::get<I>(std::forward<Tuple>(a_tuple)).Unpack()...);
112  }
113  };
114 
115  template <>
117  {
118  private:
119  using super = RegistrationSetBase;
120 
121  public:
122  RegistrationSet() = delete;
123  RegistrationSet(const RegistrationSet&) = default;
125 
126  inline RegistrationSet(const std::string_view& a_eventName) :
127  super(a_eventName)
128  {}
129 
130  ~RegistrationSet() = default;
131 
134 
135  inline void SendEvent()
136  {
137  RE::BSFixedString eventName(_eventName);
138 
140  if (vm) {
141  for (auto& handle : _handles) {
142  auto args = RE::MakeFunctionArguments();
143  vm->SendEvent(handle, eventName, args);
144  }
145  }
146  }
147 
148  inline void QueueEvent()
149  {
150  auto task = GetTaskInterface();
151  assert(task);
152  task->AddTask([this]() {
153  SendEvent();
154  });
155  }
156  };
157  }
158 
159  template <class... Args>
160  using RegistrationSet = Impl::RegistrationSet<void, Args...>;
161 }
Definition: ActiveEffect.h:27
Definition: BGSBaseAlias.h:12
static VirtualMachine * GetSingleton()
Definition: TESForm.h:40
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:126
void QueueEvent()
Definition: RegistrationSet.h:148
void SendEvent()
Definition: RegistrationSet.h:135
RegistrationSet & operator=(RegistrationSet &&)=default
RegistrationSet(const RegistrationSet &)=default
RegistrationSet & operator=(const RegistrationSet &)=default
RegistrationSet(RegistrationSet &&)=default
Definition: RegistrationSet.h:57
Definition: Interfaces.h:82
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