17namespace xrt::auxiliary::util {
18template <
typename CallbackType,
typename EventType>
struct GenericCallbacks;
27 CallbackType callback;
30 bool should_remove =
false;
33 : callback(callback_), event_mask(event_mask_), userdata(userdata_)
42 return callback == other.callback && event_mask == other.event_mask &&
43 userdata == other.userdata;
53 shouldInvoke(MaskType event)
const noexcept
55 return (event_mask & event) != 0;
67 using mask_from_enum_t =
68 typename std::conditional_t<std::is_enum<T>::value, std::underlying_type<T>,
identity<T>>::type;
94 static_assert(std::is_integral<EventBitflagType>::value || std::is_enum<EventBitflagType>::value,
95 "Your event type must either be an integer or an enum");
96 using callback_t = CallbackType;
97 using event_t = EventBitflagType;
98 using mask_t = detail::mask_from_enum_t<EventBitflagType>;
101 static_assert(std::is_integral<mask_t>::value,
"Our enum to mask conversion should have produced an integer");
113 addCallback(CallbackType callback, mask_t event_mask,
void *userdata)
115 callbacks.emplace_back(callback, event_mask, userdata);
132 CallbackType callback, mask_t event_mask,
void *userdata,
unsigned int num_skip = 0,
int max_remove = -1)
134 if (max_remove == 0) {
142 for (
auto &entry : callbacks) {
143 if (entry.matches(needle)) {
149 entry.should_remove =
true;
153 if (max_remove == 0) {
160 return purgeMarkedCallbacks();
176 contains(CallbackType callback, mask_t event_mask,
void *userdata)
179 auto it = std::find(callbacks.begin(), callbacks.end(), needle);
180 return it != callbacks.end();
198 template <
typename F>
202 bool needPurge =
false;
205 for (
auto &entry : callbacks) {
206 if (entry.shouldInvoke(
static_cast<mask_t
>(event))) {
207 bool willRemove = invoker(event, entry.callback, entry.userdata);
209 entry.should_remove =
true;
216 purgeMarkedCallbacks();
222 std::vector<callback_entry_t> callbacks;
225 purgeMarkedCallbacks()
227 auto b = callbacks.begin();
228 auto e = callbacks.end();
229 auto new_end = std::remove_if(b, e, [](callback_entry_t
const &entry) {
return entry.should_remove; });
230 auto num_removed = std::distance(new_end, e);
231 callbacks.erase(new_end, e);
232 return static_cast<int>(num_removed);
A generic collection of callbacks for event types represented as a bitmask, intended to be wrapped fo...
Definition: u_generic_callbacks.hpp:91
void addCallback(CallbackType callback, mask_t event_mask, void *userdata)
Add a new callback entry with the given callback function pointer, event mask, and user data.
Definition: u_generic_callbacks.hpp:113
bool contains(CallbackType callback, mask_t event_mask, void *userdata)
See if the collection contains at least one matching callback.
Definition: u_generic_callbacks.hpp:176
int removeCallback(CallbackType callback, mask_t event_mask, void *userdata, unsigned int num_skip=0, int max_remove=-1)
Remove some number of callback entries matching the given callback function pointer,...
Definition: u_generic_callbacks.hpp:131
int invokeCallbacks(EventBitflagType event, F &&invoker)
Invokes the callbacks, by passing the ones we should run to your "invoker" to add any desired context...
Definition: u_generic_callbacks.hpp:200
Element type stored in GenericCallbacks, for internal use only.
Definition: u_generic_callbacks.hpp:26
bool matches(GenericCallbackEntry const &other) const noexcept
Do the two entries match? Used for removal "by value".
Definition: u_generic_callbacks.hpp:40
Definition: u_generic_callbacks.hpp:60