13 #include <wpi/Compiler.h>
14 #include <wpi/UidVector.h>
15 #include <wpi/spinlock.h>
17 #include "mockdata/NotifyListener.h"
25 using RawFunctor = void (*)();
31 void Cancel(int32_t uid) {
32 std::scoped_lock lock(m_mutex);
33 if (m_callbacks) m_callbacks->erase(uid - 1);
37 std::scoped_lock lock(m_mutex);
44 int32_t DoRegister(RawFunctor callback,
void* param) {
46 if (callback ==
nullptr)
return -1;
47 if (!m_callbacks) m_callbacks = std::make_unique<CallbackVector>();
48 return m_callbacks->emplace_back(param, callback) + 1;
51 LLVM_ATTRIBUTE_ALWAYS_INLINE
void DoReset() {
52 if (m_callbacks) m_callbacks->clear();
56 std::unique_ptr<CallbackVector> m_callbacks;
67 template <
typename CallbackFunction, const
char* (*GetName)()>
70 int32_t Register(CallbackFunction callback,
void* param) {
71 std::scoped_lock lock(m_mutex);
72 return DoRegister(reinterpret_cast<RawFunctor>(callback), param);
75 template <
typename... U>
76 void Invoke(U&&... u)
const {
77 #ifdef _MSC_VER // work around VS2019 16.4.0 bug
78 std::scoped_lock<wpi::recursive_spinlock> lock(m_mutex);
80 std::scoped_lock lock(m_mutex);
83 const char* name = GetName();
84 for (
auto&& cb : *m_callbacks)
85 reinterpret_cast<CallbackFunction>(cb.callback)(name, cb.param,
86 std::forward<U>(u)...);
90 template <
typename... U>
91 LLVM_ATTRIBUTE_ALWAYS_INLINE
void operator()(U&&... u)
const {
92 return Invoke(std::forward<U>(u)...);
101 #define HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(NAME) \
102 static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr const char* \
103 Get##NAME##Name() { \
121 #define HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI(TYPE, NS, CAPINAME, DATA, \
123 int32_t NS##_Register##CAPINAME##Callback(int32_t index, TYPE callback, \
125 return DATA[index].LOWERNAME.Register(callback, param); \
128 void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t uid) { \
129 DATA[index].LOWERNAME.Cancel(uid); \
145 #define HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI_NOINDEX(TYPE, NS, CAPINAME, DATA, \
147 int32_t NS##_Register##CAPINAME##Callback(TYPE callback, void* param) { \
148 return DATA->LOWERNAME.Register(callback, param); \
151 void NS##_Cancel##CAPINAME##Callback(int32_t uid) { \
152 DATA->LOWERNAME.Cancel(uid); \