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  void Clear();
38  bool Save(SerializationInterface* a_intfc, std::uint32_t a_type, std::uint32_t a_version);
39  bool Save(SerializationInterface* a_intfc);
40  bool Load(SerializationInterface* a_intfc);
41 
42  protected:
43  using Lock = std::recursive_mutex;
44  using Locker = std::lock_guard<Lock>;
45 
46  bool Register(const void* a_object, RE::VMTypeID a_typeID);
47  bool Unregister(const void* a_object, RE::VMTypeID a_typeID);
48 
49  std::set<RE::VMHandle> _handles;
51  mutable Lock _lock;
52  };
53 
54  template <class Enable, class... Args>
56 
57  template <class... Args>
59  std::enable_if_t<
60  std::conjunction_v<
61  RE::BSScript::is_return_convertible<Args>...>>,
62  Args...> :
63  public RegistrationSetBase
64  {
65  private:
66  using super = RegistrationSetBase;
67 
68  public:
69  RegistrationSet() = delete;
70  RegistrationSet(const RegistrationSet&) = default;
72 
73  inline RegistrationSet(const std::string_view& a_eventName) :
74  super(a_eventName)
75  {}
76 
77  ~RegistrationSet() = default;
78 
81 
82  inline void SendEvent(Args... a_args)
83  {
84  RE::BSFixedString eventName(_eventName);
85 
87  for (auto& handle : _handles) {
88  auto args = RE::MakeFunctionArguments(std::forward<Args>(a_args)...);
89  vm->SendEvent(handle, eventName, args);
90  }
91  }
92 
93  inline void QueueEvent(Args... a_args)
94  {
95  std::tuple args(VMArg(std::forward<Args>(a_args))...);
96  auto task = GetTaskInterface();
97  assert(task);
98  if (task) {
99  task->AddTask([args, this]() mutable {
100  SendEvent_Tuple(std::move(args), index_sequence_for_tuple<decltype(args)>{});
101  });
102  }
103  }
104 
105  private:
106  template <class Tuple, std::size_t... I>
107  inline void SendEvent_Tuple(Tuple&& a_tuple, std::index_sequence<I...>)
108  {
109  SendEvent(std::get<I>(std::forward<Tuple>(a_tuple)).Unpack()...);
110  }
111  };
112 
113  template <>
115  {
116  private:
117  using super = RegistrationSetBase;
118 
119  public:
120  RegistrationSet() = delete;
121  RegistrationSet(const RegistrationSet&) = default;
123 
124  inline RegistrationSet(const std::string_view& a_eventName) :
125  super(a_eventName)
126  {}
127 
128  ~RegistrationSet() = default;
129 
132 
133  inline void SendEvent()
134  {
135  RE::BSFixedString eventName(_eventName);
136 
138  if (vm) {
139  for (auto& handle : _handles) {
140  auto args = RE::MakeFunctionArguments();
141  vm->SendEvent(handle, eventName, args);
142  }
143  }
144  }
145 
146  inline void QueueEvent()
147  {
148  auto task = GetTaskInterface();
149  assert(task);
150  task->AddTask([this]() {
151  SendEvent();
152  });
153  }
154  };
155  }
156 
157  template <class... Args>
158  using RegistrationSet = Impl::RegistrationSet<void, Args...>;
159 }
Definition: ActiveEffect.h:22
Definition: BGSBaseAlias.h:12
static VirtualMachine * GetSingleton()
Definition: TESForm.h:34
Definition: RegistrationSet.h:20
std::string _eventName
Definition: RegistrationSet.h:50
bool Register(const RE::ActiveEffect *a_effect)
RegistrationSetBase(const std::string_view &a_eventName)
bool Unregister(const RE::ActiveEffect *a_effect)
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:44
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:49
Lock _lock
Definition: RegistrationSet.h:51
bool Unregister(const void *a_object, RE::VMTypeID a_typeID)
std::recursive_mutex Lock
Definition: RegistrationSet.h:43
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:124
void QueueEvent()
Definition: RegistrationSet.h:146
void SendEvent()
Definition: RegistrationSet.h:133
RegistrationSet & operator=(RegistrationSet &&)=default
RegistrationSet(const RegistrationSet &)=default
RegistrationSet & operator=(const RegistrationSet &)=default
RegistrationSet(RegistrationSet &&)=default
Definition: RegistrationSet.h:55
Definition: Interfaces.h:71
std::uint32_t VMTypeID
Definition: BSCoreTypes.h:9
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: NiBinaryStream.h:94
Definition: RegistrationTraits.h:40