WPILibC++ 2025.2.1
Loading...
Searching...
No Matches
SimCallbackRegistry.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <memory>
8#include <utility>
9
10#include <wpi/Compiler.h>
11#include <wpi/UidVector.h>
12#include <wpi/spinlock.h>
13
15
16namespace hal {
17
18namespace impl {
19
21 public:
22 using RawFunctor = void (*)();
23
24 protected:
26
27 public:
28 void Cancel(int32_t uid) {
29 std::scoped_lock lock(m_mutex);
30 if (m_callbacks && uid > 0) {
31 m_callbacks->erase(uid - 1);
32 }
33 }
34
35 void Reset() {
36 std::scoped_lock lock(m_mutex);
37 DoReset();
38 }
39
41
42 protected:
43 int32_t DoRegister(RawFunctor callback, void* param) {
44 // Must return -1 on a null callback for error handling
45 if (callback == nullptr) {
46 return -1;
47 }
48 if (!m_callbacks) {
49 m_callbacks = std::make_unique<CallbackVector>();
50 }
51 return m_callbacks->emplace_back(param, callback) + 1;
52 }
53
55 if (m_callbacks) {
56 m_callbacks->clear();
57 }
58 }
59
61 std::unique_ptr<CallbackVector> m_callbacks;
62};
63
64} // namespace impl
65
66/**
67 * Simulation callback registry. Provides callback functionality.
68 *
69 * @tparam CallbackFunction callback function type (e.g. HAL_BufferCallback)
70 * @tparam GetName function that returns a const char* for the name
71 */
72template <typename CallbackFunction, const char* (*GetName)()>
74 public:
75 int32_t Register(CallbackFunction callback, void* param) {
76 std::scoped_lock lock(m_mutex);
77 return DoRegister(reinterpret_cast<RawFunctor>(callback), param);
78 }
79
80 template <typename... U>
81 void Invoke(U&&... u) const {
82 std::scoped_lock lock(m_mutex);
83 if (m_callbacks) {
84 const char* name = GetName();
85 for (auto&& cb : *m_callbacks) {
86 reinterpret_cast<CallbackFunction>(cb.callback)(name, cb.param,
87 std::forward<U>(u)...);
88 }
89 }
90 }
91
92 template <typename... U>
94 return Invoke(std::forward<U>(u)...);
95 }
96};
97
98/**
99 * Define a name functor for use with SimCallbackRegistry.
100 * This creates a function named GetNAMEName() that returns "NAME".
101 * @param NAME the name to return
102 */
103#define HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(NAME) \
104 static LLVM_ATTRIBUTE_ALWAYS_INLINE constexpr const char* \
105 Get##NAME##Name() { \
106 return #NAME; \
107 }
108
109/**
110 * Define a standard C API for SimCallbackRegistry.
111 *
112 * Functions defined:
113 * - int32 NS_RegisterCAPINAMECallback(
114 * int32_t index, TYPE callback, void* param)
115 * - void NS_CancelCAPINAMECallback(int32_t index, int32_t uid)
116 *
117 * @param TYPE the underlying callback type (e.g. HAL_BufferCallback)
118 * @param NS the "namespace" (e.g. HALSIM)
119 * @param CAPINAME the C API name (usually first letter capitalized)
120 * @param DATA the backing data array
121 * @param LOWERNAME the lowercase name of the backing data registry
122 */
123#define HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI(TYPE, NS, CAPINAME, DATA, \
124 LOWERNAME) \
125 int32_t NS##_Register##CAPINAME##Callback(int32_t index, TYPE callback, \
126 void* param) { \
127 return DATA[index].LOWERNAME.Register(callback, param); \
128 } \
129 \
130 void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t uid) { \
131 DATA[index].LOWERNAME.Cancel(uid); \
132 }
133
134/**
135 * Define a standard C API for SimCallbackRegistry (no index variant).
136 *
137 * Functions defined:
138 * - int32 NS_RegisterCAPINAMECallback(TYPE callback, void* param)
139 * - void NS_CancelCAPINAMECallback(int32_t uid)
140 *
141 * @param TYPE the underlying callback type (e.g. HAL_BufferCallback)
142 * @param NS the "namespace" (e.g. HALSIM)
143 * @param CAPINAME the C API name (usually first letter capitalized)
144 * @param DATA the backing data pointer
145 * @param LOWERNAME the lowercase name of the backing data registry
146 */
147#define HAL_SIMCALLBACKREGISTRY_DEFINE_CAPI_NOINDEX(TYPE, NS, CAPINAME, DATA, \
148 LOWERNAME) \
149 int32_t NS##_Register##CAPINAME##Callback(TYPE callback, void* param) { \
150 return DATA->LOWERNAME.Register(callback, param); \
151 } \
152 \
153 void NS##_Cancel##CAPINAME##Callback(int32_t uid) { \
154 DATA->LOWERNAME.Cancel(uid); \
155 }
156
157/**
158 * Define a stub standard C API for SimCallbackRegistry.
159 *
160 * Functions defined:
161 * - int32 NS_RegisterCAPINAMECallback(
162 * int32_t index, TYPE callback, void* param)
163 * - void NS_CancelCAPINAMECallback(int32_t index, int32_t uid)
164 *
165 * @param TYPE the underlying callback type (e.g. HAL_BufferCallback)
166 * @param NS the "namespace" (e.g. HALSIM)
167 * @param CAPINAME the C API name (usually first letter capitalized)
168 */
169#define HAL_SIMCALLBACKREGISTRY_STUB_CAPI(TYPE, NS, CAPINAME) \
170 int32_t NS##_Register##CAPINAME##Callback(int32_t index, TYPE callback, \
171 void* param) { \
172 return 0; \
173 } \
174 \
175 void NS##_Cancel##CAPINAME##Callback(int32_t index, int32_t uid) {}
176
177/**
178 * Define a stub standard C API for SimCallbackRegistry (no index variant).
179 *
180 * Functions defined:
181 * - int32 NS_RegisterCAPINAMECallback(TYPE callback, void* param)
182 * - void NS_CancelCAPINAMECallback(int32_t uid)
183 *
184 * @param TYPE the underlying callback type (e.g. HAL_BufferCallback)
185 * @param NS the "namespace" (e.g. HALSIM)
186 * @param CAPINAME the C API name (usually first letter capitalized)
187 */
188#define HAL_SIMCALLBACKREGISTRY_STUB_CAPI_NOINDEX(TYPE, NS, CAPINAME) \
189 int32_t NS##_Register##CAPINAME##Callback(TYPE callback, void* param) { \
190 return 0; \
191 } \
192 \
193 void NS##_Cancel##CAPINAME##Callback(int32_t uid) {}
194
195} // namespace hal
#define LLVM_ATTRIBUTE_ALWAYS_INLINE
LLVM_ATTRIBUTE_ALWAYS_INLINE - On compilers where we have a directive to do so, mark a method "always...
Definition Compiler.h:277
Simulation callback registry.
Definition SimCallbackRegistry.h:73
void Invoke(U &&... u) const
Definition SimCallbackRegistry.h:81
LLVM_ATTRIBUTE_ALWAYS_INLINE void operator()(U &&... u) const
Definition SimCallbackRegistry.h:93
int32_t Register(CallbackFunction callback, void *param)
Definition SimCallbackRegistry.h:75
Definition SimCallbackRegistry.h:20
void Cancel(int32_t uid)
Definition SimCallbackRegistry.h:28
wpi::recursive_spinlock & GetMutex()
Definition SimCallbackRegistry.h:40
LLVM_ATTRIBUTE_ALWAYS_INLINE void DoReset()
Definition SimCallbackRegistry.h:54
wpi::recursive_spinlock m_mutex
Definition SimCallbackRegistry.h:60
void(*)() RawFunctor
Definition SimCallbackRegistry.h:22
int32_t DoRegister(RawFunctor callback, void *param)
Definition SimCallbackRegistry.h:43
void Reset()
Definition SimCallbackRegistry.h:35
std::unique_ptr< CallbackVector > m_callbacks
Definition SimCallbackRegistry.h:61
Vector which provides an integrated freelist for removal and reuse of individual elements.
Definition UidVector.h:73
A recursive spinlock mutex.
Definition spinlock.h:46
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition InterruptManager.h:13