CommonLibVR
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 args = RE::MakeFunctionArguments(std::forward<Args>(a_args)...);
96  vm->SendEvent(handle, eventName, args);
97  }
98  }
99  }
100  }
101 
102  inline void QueueEvent(RE::TESObjectREFR* a_target, Args... a_args)
103  {
104  std::tuple args(VMArg(std::forward<Args>(a_args))...);
105  auto task = GetTaskInterface();
106  assert(task);
107  if (task) {
108  task->AddTask([a_target, args, this]() mutable {
109  SendEvent_Tuple(a_target, std::move(args), index_sequence_for_tuple<decltype(args)>{});
110  });
111  }
112  }
113 
114  private:
115  template <class Tuple, std::size_t... I>
116  inline void SendEvent_Tuple(RE::TESObjectREFR* a_target, Tuple&& a_tuple, std::index_sequence<I...>)
117  {
118  SendEvent(a_target, std::get<I>(std::forward<Tuple>(a_tuple)).Unpack()...);
119  }
120  };
121 
122  template <>
124  {
125  private:
127 
128  public:
132 
133  inline RegistrationSetUnique(const std::string_view& a_eventName) :
134  super(a_eventName)
135  {
136  }
137 
139 
142 
143  inline void SendEvent(RE::TESObjectREFR* a_target)
144  {
145  RE::BSFixedString eventName(_eventName);
146 
148  const auto targetID = a_target->GetFormID();
149  if (const auto it = _regs.find(targetID); it != _regs.end()) {
150  for (auto& handle : it->second) {
151  auto args = RE::MakeFunctionArguments();
152  vm->SendEvent(handle, eventName, args);
153  }
154  }
155  }
156  }
157 
158  inline void QueueEvent(RE::TESObjectREFR* a_target)
159  {
160  auto task = GetTaskInterface();
161  assert(task);
162  task->AddTask([a_target, this]() {
163  SendEvent(a_target);
164  });
165  }
166  };
167  }
168 
169  template <class... Args>
171 }
Definition: ActiveEffect.h:27
Definition: BGSRefAlias.h:15
static VirtualMachine * GetSingleton()
Definition: TESForm.h:40
FormID GetFormID() const noexcept
Definition: TESForm.h:293
Definition: TESObjectREFR.h:113
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:102
void QueueEvent(RE::TESObjectREFR *a_target)
Definition: RegistrationSetUnique.h:158
void SendEvent(RE::TESObjectREFR *a_target)
Definition: RegistrationSetUnique.h:143
RegistrationSetUnique(const RegistrationSetUnique &)=default
RegistrationSetUnique & operator=(RegistrationSetUnique &&)=default
RegistrationSetUnique(const std::string_view &a_eventName)
Definition: RegistrationSetUnique.h:133
RegistrationSetUnique(RegistrationSetUnique &&)=default
RegistrationSetUnique & operator=(const RegistrationSetUnique &)=default
Definition: RegistrationSetUnique.h:59
Definition: Interfaces.h:82
std::uint32_t FormID
Definition: BSCoreTypes.h:5
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