22template<
class TReturn,
class... Types>
27template<
class TReturn,
class... Types>
30 return this->g_function(args...);
32template<
class TReturn,
class... Types>
35 return this->g_function ==
reinterpret_cast<CallbackFunction
>(ptr);
40template<
class TReturn,
class TObject,
class... Types>
46template<
class TReturn,
class TObject,
class... Types>
49 return ((this->g_object)->*(this->g_functionObj))(args...);
52template<
class TReturn,
class TObject,
class... Types>
55 return this->g_object ==
reinterpret_cast<TObject*
>(ptr);
60template<
class TReturn,
class... Types>
61template<
typename TLambda>
63 g_lambda(new TLambda(lambda))
65 this->g_executeLambda = [](
void* lambdaPtr, [[maybe_unused]] Types... arguments) {
66 if constexpr (std::is_invocable_v<TLambda, Types...>)
68 return (*
reinterpret_cast<TLambda*
>(lambdaPtr))(arguments...);
72 return (*
reinterpret_cast<TLambda*
>(lambdaPtr))();
75 this->g_deleteLambda = [](
void* lambdaPtr) {
delete reinterpret_cast<TLambda*
>(lambdaPtr); };
77template<
class TReturn,
class... Types>
78CallbackLambda<TReturn, Types...>::~CallbackLambda()
80 (*this->g_deleteLambda)(this->g_lambda);
83template<
class TReturn,
class... Types>
86 return (*this->g_executeLambda)(this->g_lambda, args...);
88template<
class TReturn,
class... Types>
96template<
class... Types>
99 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
101 for (
auto& callee: this->g_callees)
103 callee._markedForDeletion =
true;
107template<
class... Types>
110 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
115 for (
auto& callee: this->g_callees)
117 if (callee._markedForDeletion)
122 callee._f = std::move(callback);
123 callee._subscriber = subscriber;
124 callee._markedForDeletion =
false;
125 return callee._f.get();
130 this->g_callees.emplace_back(std::move(callback), subscriber);
131 return this->g_callees.back()._f.get();
133template<
class... Types>
141template<
class... Types>
142template<
typename TLambda>
149template<
class... Types>
150template<
class TObject>
152 typename fge::CallbackObjectFunctor<void, TObject, Types...>::CallbackFunctionObject func,
160template<
class... Types>
163 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
164 for (
auto& callee: this->g_callees)
166 if (callee._markedForDeletion)
171 if (callee._f->check(ptr))
174 callee._markedForDeletion =
true;
178template<
class... Types>
181 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
182 for (
auto& callee: this->g_callees)
184 if (callee._markedForDeletion)
189 if (callee._subscriber == subscriber)
191 if (this->
detachOnce(callee._subscriber) == 0)
193 callee._markedForDeletion =
true;
196 callee._markedForDeletion =
true;
200template<
class... Types>
203 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
204 for (
auto& callee: this->g_callees)
206 if (callee._markedForDeletion)
211 if (callee._f.get() == callback)
214 this->g_callees._markedForDeletion =
true;
219template<
class... Types>
222 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
224 std::size_t eraseCount = 0;
225 for (std::size_t i = 0; i < this->g_callees.size(); ++i)
227 if (this->g_callees[i]._markedForDeletion)
235 this->g_callees.erase(this->g_callees.begin() + i - eraseCount, this->g_callees.begin() + i);
240 this->g_callees[i]._f->call(std::forward<Types>(args)...);
248template<
class... Types>
251 if (
this == &handler)
256 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
258 [&handler](Types... args) { handler.call(std::forward<Types>(args)...); }),
262template<
class... Types>
265 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
266 for (
auto& callee: this->g_callees)
268 if (callee._markedForDeletion)
273 if (callee._subscriber == subscriber)
275 callee._markedForDeletion =
true;
282template<
class... Types>
283void UniqueCallbackHandler<Types...>::clear()
285 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
286 this->g_callee._f =
nullptr;
287 this->g_callee._subscriber =
nullptr;
290template<
class... Types>
294 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
296 if (subscriber != this->g_callee._subscriber)
302 this->g_callee._f = std::move(callback);
303 this->g_callee._subscriber = subscriber;
304 return this->g_callee._f.get();
306template<
class... Types>
314template<
class... Types>
315template<
typename TLambda>
322template<
class... Types>
323template<
class TObject>
325 typename fge::CallbackObjectFunctor<void, TObject, Types...>::CallbackFunctionObject func,
333template<
class... Types>
336 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
338 if (this->g_callee._f->check(ptr))
341 this->g_callee._f =
nullptr;
342 this->g_callee._subscriber =
nullptr;
345template<
class... Types>
348 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
350 if (this->g_callee._subscriber == subscriber)
353 this->g_callee._f =
nullptr;
354 this->g_callee._subscriber =
nullptr;
357template<
class... Types>
360 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
362 if (this->g_callee._f.get() == callback)
365 this->g_callee._f =
nullptr;
366 this->g_callee._subscriber =
nullptr;
370template<
class... Types>
373 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
375 if (this->g_callee._f ==
nullptr)
380 auto unique = std::move(this->g_callee._f);
381 unique->call(std::forward<Types>(args)...);
382 this->g_callee._f = std::move(unique);
390template<
class... Types>
393 std::scoped_lock<std::recursive_mutex>
const lck(this->g_mutex);
394 if (this->g_callee._subscriber == subscriber)
396 this->g_callee._f =
nullptr;
397 this->g_callee._subscriber =
nullptr;
Base class for callbacks.
Definition C_callback.hpp:37
Callback functor.
Definition C_callback.hpp:54
bool check(void *ptr) override
Check if the given pointer is the same as the one used to construct the functor.
Definition C_callback.inl:33
TReturn call(Types... args) override
Call the callback function with the given arguments.
Definition C_callback.inl:28
CallbackFunctor(CallbackFunction func)
Constructor.
Definition C_callback.inl:23
This class is used to handle callbacks in a safe way.
Definition C_callback.hpp:244
void delPtr(void *ptr)
Remove a callback from the list.
Definition C_callback.inl:161
void del(fge::CallbackBase< void, Types... > *callback)
Remove a callback from the list.
Definition C_callback.inl:201
fge::CallbackBase< void, Types... > * add(CalleePtr &&callback, fge::Subscriber *subscriber=nullptr)
Add a new callback to the list.
Definition C_callback.inl:108
fge::CallbackObjectFunctor< void, TObject, Types... > * addObjectFunctor(typename fge::CallbackObjectFunctor< void, TObject, Types... >::CallbackFunctionObject func, TObject *object, Subscriber *subscriber=nullptr)
Helper method to add a callback object functor.
Definition C_callback.inl:151
void onDetach(fge::Subscriber *subscriber) override
This method is called when a subscriber is destroyed (destructor called).
Definition C_callback.inl:263
fge::CallbackFunctor< void, Types... > * addFunctor(typename fge::CallbackFunctor< void, Types... >::CallbackFunction func, fge::Subscriber *subscriber=nullptr)
Helper method to add a callback functor.
Definition C_callback.inl:135
fge::CallbackLambda< void, Types... > * addLambda(TLambda const &lambda, fge::Subscriber *subscriber=nullptr)
Helper method to add a callback lambda.
Definition C_callback.inl:143
void call(Types... args)
Call all the callbacks with the given arguments.
Definition C_callback.inl:220
void hook(fge::CallbackHandler< Types... > &handler, fge::Subscriber *subscriber=nullptr)
Hook a callback handler to this handler.
Definition C_callback.inl:249
void delSub(fge::Subscriber *subscriber)
Remove a callback from the list.
Definition C_callback.inl:179
void clear()
Clear the list of callbacks.
Definition C_callback.inl:97
Callback lambda (with/without capture).
Definition C_callback.hpp:93
CallbackLambda(TLambda const &lambda)
Constructor.
Definition C_callback.inl:62
bool check(void *ptr) override
Always return false.
Definition C_callback.inl:89
TReturn call(Types... args) override
Call the callback function with the given arguments.
Definition C_callback.inl:84
Callback functor of a method with an object.
Definition C_callback.hpp:135
TReturn call(Types... args) override
Call the callback method with the given arguments.
Definition C_callback.inl:47
CallbackObjectFunctor(CallbackFunctionObject func, TObject *object)
Constructor.
Definition C_callback.inl:41
bool check(void *ptr) override
Check if the given object pointer is the same as the one used to construct the functor.
Definition C_callback.inl:53
This class is a useful utility to "link" multiple objects around.
Definition C_subscription.hpp:210
SubscriberCount attach(fge::Subscriber *subscriber) override
Attach a specific subscriber.
void detachAll() override
Detach all subscribers.
SubscriberCount detachOnce(fge::Subscriber *subscriber) override
Detach only once a specific subscriber.
fge::CallbackFunctor< void, Types... > * setFunctor(typename fge::CallbackFunctor< void, Types... >::CallbackFunction func, fge::Subscriber *subscriber=nullptr)
Helper method to set a callback functor.
Definition C_callback.inl:308
void delSub(fge::Subscriber *subscriber)
Remove the callback if the subscriber is the same as the one used to construct the callback.
Definition C_callback.inl:346
void delPtr(void *ptr)
Remove the callback if the function/object pointer is the same as the one used to construct the callb...
Definition C_callback.inl:334
fge::CallbackLambda< void, Types... > * setLambda(TLambda const &lambda, fge::Subscriber *subscriber=nullptr)
Helper method to set a callback lambda.
Definition C_callback.inl:316
fge::CallbackObjectFunctor< void, TObject, Types... > * setObjectFunctor(typename fge::CallbackObjectFunctor< void, TObject, Types... >::CallbackFunctionObject func, TObject *object, Subscriber *subscriber=nullptr)
Helper method to set a callback object functor.
Definition C_callback.inl:324
void call(Types... args)
Call the callback with the given arguments.
Definition C_callback.inl:371
void onDetach(fge::Subscriber *subscriber) override
This method is called when a subscriber is destroyed (destructor called).
Definition C_callback.inl:391
void del(fge::CallbackBase< Types... > *callback)
Remove the callback if the callback pointer is the same as the one used to construct the callback.
Definition C_callback.inl:358
fge::CallbackBase< void, Types... > * set(CalleePtr &&callback, fge::Subscriber *subscriber=nullptr)
Set a new callback to the handler, replacing the previous one if it exists.
Definition C_callback.inl:291
SubscriberCount detachOnce(fge::Subscriber *subscriber) override
Detach only once a specific subscriber.
static CalleePtr newFunctor(typename fge::CallbackFunctor< void, Types... >::CallbackFunction func)
Definition C_callback.hpp:192
static CalleePtr newObjectFunctor(typename fge::CallbackObjectFunctor< void, TObject, Types... >::CallbackFunctionObject func, TObject *object)
Definition C_callback.hpp:220
static CalleePtr newLambda(TLambda const &lambda)
Definition C_callback.hpp:205