CommonLibSSE (powerof3)
RegistrationSetUnique.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "RE/A/ActiveEffect.h"
4 #include "RE/B/BGSRefAlias.h"
5 #include "RE/B/BSFixedString.h"
8 #include "RE/T/TESForm.h"
9 #include "RE/T/TypeTraits.h"
10 #include "RE/V/VirtualMachine.h"
11 
12 #include "SKSE/API.h"
14 #include "SKSE/Interfaces.h"
15 
16 namespace SKSE
17 {
18  namespace Impl
19  {
21  {
22  public:
24  RegistrationSetUniqueBase(const std::string_view& a_eventName);
28 
31 
32  bool Register(RE::TESForm* a_form);
33  bool Register(RE::BGSRefAlias* a_alias);
34  bool Register(RE::ActiveEffect* a_activeEffect);
35  bool Unregister(RE::TESForm* a_form);
36  bool Unregister(RE::BGSRefAlias* a_alias);
37  bool Unregister(RE::ActiveEffect* a_activeEffect);
38  bool Unregister(RE::VMHandle a_handle);
39  bool Unregister(RE::FormID a_uniqueID);
40  void Clear();
41  bool Save(SerializationInterface* a_intfc, std::uint32_t a_type, std::uint32_t a_version);
42  bool Save(SerializationInterface* a_intfc);
43  bool Load(SerializationInterface* a_intfc);
45 
46  protected:
47  using Lock = std::recursive_mutex;
48  using Locker = std::lock_guard<Lock>;
49 
50  bool Register(const void* a_object, RE::FormID a_formID, RE::VMTypeID a_typeID);
51  bool Unregister(const void* a_object, RE::FormID a_formID, RE::VMTypeID a_typeID);
52 
53  std::map<RE::FormID, std::set<RE::VMHandle>> _regs;
55  mutable Lock _lock;
56  };
57 
58  template <class Enable, class... Args>
60 
61  template <class... Args>
63  std::enable_if_t<
64  std::conjunction_v<
65  RE::BSScript::is_return_convertible<Args>...>>,
66  Args...> :
68  {
69  private:
71 
72  public:
76 
77  inline RegistrationSetUnique(const std::string_view& a_eventName) :
78  super(a_eventName)
79  {
80  }
81 
83 
86 
87  inline void SendEvent(RE::TESObjectREFR* a_target, Args... a_args)
88  {
89  RE::BSFixedString eventName(_eventName);
90 
92  const auto targetID = a_target->GetFormID();
93  if (const auto it = _regs.find(targetID); it != _regs.end()) {
94  for (auto& handle : it->second) {
95  auto copy = std::make_tuple(a_args...);
96  std::apply([&](auto&&... a_copy) {
97  auto args = RE::MakeFunctionArguments(std::forward<Args>(a_copy)...);
98  vm->SendEvent(handle, eventName, args);
99  },
100  copy);
101  }
102  }
103  }
104  }
105 
106  inline void QueueEvent(RE::TESObjectREFR* a_target, Args... a_args)
107  {
108  std::tuple args(VMArg(std::forward<Args>(a_args))...);
109  auto task = GetTaskInterface();
110  assert(task);
111  if (task) {
112  task->AddTask([a_target, args, this]() mutable {
113  SendEvent_Tuple(a_target, std::move(args), index_sequence_for_tuple<decltype(args)>{});
114  });
115  }
116  }
117 
118  private:
119  template <class Tuple, std::size_t... I>
120  inline void SendEvent_Tuple(RE::TESObjectREFR* a_target, Tuple&& a_tuple, std::index_sequence<I...>)
121  {
122  SendEvent(a_target, std::get<I>(std::forward<Tuple>(a_tuple)).Unpack()...);
123  }
124  };
125 
126  template <>
128  {
129  private:
131 
132  public:
136 
137  inline RegistrationSetUnique(const std::string_view& a_eventName) :
138  super(a_eventName)
139  {
140  }
141 
143 
146 
147  inline void SendEvent(RE::TESObjectREFR* a_target)
148  {
149  RE::BSFixedString eventName(_eventName);
150 
152  const auto targetID = a_target->GetFormID();
153  if (const auto it = _regs.find(targetID); it != _regs.end()) {
154  for (auto& handle : it->second) {
155  auto args = RE::MakeFunctionArguments();
156  vm->SendEvent(handle, eventName, args);
157  }
158  }
159  }
160  }
161 
162  inline void QueueEvent(RE::TESObjectREFR* a_target)
163  {
164  auto task = GetTaskInterface();
165  assert(task);
166  task->AddTask([a_target, this]() {
167  SendEvent(a_target);
168  });
169  }
170  };
171  }
172 
173  template <class... Args>
175 }
Definition: ActiveEffect.h:27
Definition: BGSRefAlias.h:15
static VirtualMachine * GetSingleton()
Definition: TESForm.h:36
FormID GetFormID() const noexcept
Definition: TESForm.h:289
Definition: TESObjectREFR.h:114
Definition: RegistrationSetUnique.h:21
std::map< RE::FormID, std::set< RE::VMHandle > > _regs
Definition: RegistrationSetUnique.h:53
bool Unregister(const void *a_object, RE::FormID a_formID, RE::VMTypeID a_typeID)
std::string _eventName
Definition: RegistrationSetUnique.h:54
bool Register(RE::TESForm *a_form)
bool Unregister(RE::BGSRefAlias *a_alias)
bool Register(RE::BGSRefAlias *a_alias)
RegistrationSetUniqueBase(const RegistrationSetUniqueBase &a_rhs)
bool Unregister(RE::ActiveEffect *a_activeEffect)
Lock _lock
Definition: RegistrationSetUnique.h:55
bool Register(RE::ActiveEffect *a_activeEffect)
bool Load(SerializationInterface *a_intfc)
bool Register(const void *a_object, RE::FormID a_formID, RE::VMTypeID a_typeID)
void Revert(SerializationInterface *)
RegistrationSetUniqueBase(RegistrationSetUniqueBase &&a_rhs)
std::recursive_mutex Lock
Definition: RegistrationSetUnique.h:47
bool Unregister(RE::FormID a_uniqueID)
RegistrationSetUniqueBase(const std::string_view &a_eventName)
bool Unregister(RE::VMHandle a_handle)
bool Save(SerializationInterface *a_intfc)
RegistrationSetUniqueBase & operator=(const RegistrationSetUniqueBase &a_rhs)
RegistrationSetUniqueBase & operator=(RegistrationSetUniqueBase &&a_rhs)
std::lock_guard< Lock > Locker
Definition: RegistrationSetUnique.h:48
bool Unregister(RE::TESForm *a_form)
bool Save(SerializationInterface *a_intfc, std::uint32_t a_type, std::uint32_t a_version)
void SendEvent(RE::TESObjectREFR *a_target, Args... a_args)
Definition: RegistrationSetUnique.h:87
void QueueEvent(RE::TESObjectREFR *a_target, Args... a_args)
Definition: RegistrationSetUnique.h:106
void QueueEvent(RE::TESObjectREFR *a_target)
Definition: RegistrationSetUnique.h:162
void SendEvent(RE::TESObjectREFR *a_target)
Definition: RegistrationSetUnique.h:147
RegistrationSetUnique(const RegistrationSetUnique &)=default
RegistrationSetUnique & operator=(RegistrationSetUnique &&)=default
RegistrationSetUnique(const std::string_view &a_eventName)
Definition: RegistrationSetUnique.h:137
RegistrationSetUnique(RegistrationSetUnique &&)=default
RegistrationSetUnique & operator=(const RegistrationSetUnique &)=default
Definition: RegistrationSetUnique.h:59
Definition: Interfaces.h:82
std::uint32_t FormID
Definition: BSCoreTypes.h:5
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