SDL3pp
A slim C++ wrapper for SDL3
Loading...
Searching...
No Matches
SDL3pp_callbackWrapper.h
1#ifndef SDL3PP_CALLBACK_WRAPPER_H_
2#define SDL3PP_CALLBACK_WRAPPER_H_
3
4#include <functional>
5#include <map>
6#include <memory>
7#include <SDL3/SDL_assert.h>
8
9namespace SDL {
10
19template<class F>
21
32template<class Result, class... Args>
33struct CallbackWrapper<std::function<Result(Args...)>>
34{
36 using ValueType = std::function<Result(Args...)>;
37
39 static const ValueType& Unwrap(void* handle)
40 {
41 return *static_cast<ValueType*>(handle);
42 }
43
45 static Result Call(void* handle, Args... args)
46 {
47 auto& f = Unwrap(handle);
48 return f(args...);
49 }
50
52 static Result CallSuffixed(Args... args, void* handle)
53 {
54 auto& f = Unwrap(handle);
55 return f(args...);
56 }
57
58 CallbackWrapper() = delete;
59
66 static ValueType* Wrap(ValueType&& cb)
67 {
68 return new ValueType(std::move(cb));
69 }
70
72 static Result CallOnce(void* handle, Args... args)
73 {
74 auto f = release(handle);
75 return f(args...);
76 }
77
79 static Result CallOnceSuffixed(Args... args, void* handle)
80 {
81 auto f = release(handle);
82 return f(args...);
83 }
84
92 static ValueType release(void* handle)
93 {
94 if (handle == nullptr) return {};
95 auto ptr = static_cast<ValueType*>(handle);
96 ValueType value{std::move(*ptr)};
97 delete ptr;
98 return value;
99 }
100};
101
107template<class SELF, class R, class... PARAMS>
109{
111 R (*wrapper)(void*, PARAMS...);
112
114 void* data;
115
117 template<class F>
118 LightweightCallbackT(const F& func)
119 {
120 static_assert(sizeof(func) <= sizeof(data), "Function must fit size_t");
121 union PunAux
122 {
123 void* ptr;
124 F func;
125 };
126 wrapper = [](void* userdata, PARAMS... params) {
127 PunAux aux{.ptr = userdata};
128 return SELF::doCall(aux.func, params...);
129 };
130 PunAux aux{.func = func};
131 data = aux.ptr;
132 }
133};
134
140template<class SELF, class R, class... PARAMS>
142{
144 R (*wrapper)(PARAMS..., void*);
145
147 void* data;
148
150 template<class F>
152 {
153 static_assert(sizeof(func) <= sizeof(data), "Function must fit size_t");
154 union PunAux
155 {
156 void* ptr;
157 F func;
158 };
159 wrapper = [](PARAMS... params, void* userdata) {
160 PunAux aux{.ptr = userdata};
161 return SELF::doCall(aux.func, params...);
162 };
163 PunAux aux{.func = func};
164 data = aux.ptr;
165 }
166};
167
168template<class F>
170
177template<class R, class... PARAMS>
178struct MakeFrontCallback<R(PARAMS...)>
179 : LightweightCallbackT<MakeFrontCallback<R(PARAMS...)>, R, PARAMS...>
180{
182 template<std::invocable<PARAMS...> F>
183 MakeFrontCallback(const F& func)
184 : LightweightCallbackT<MakeFrontCallback<R(PARAMS...)>, R, PARAMS...>(func)
185 {
186 }
187
189 template<std::invocable<PARAMS...> F>
190 static R doCall(F& func, PARAMS... params)
191 {
192 return func(params...);
193 }
194};
195
196template<class F>
198
205template<class R, class... PARAMS>
206struct MakeBackCallback<R(PARAMS...)>
207 : LightweightTrailingCallbackT<MakeBackCallback<R(PARAMS...)>, R, PARAMS...>
208{
210 template<std::invocable<PARAMS...> F>
211 MakeBackCallback(const F& func)
213 R,
214 PARAMS...>(func)
215 {
216 }
217
219 template<std::invocable<PARAMS...> F>
220 static R doCall(const F& func, PARAMS... params)
221 {
222 return func(params...);
223 }
224};
225
227
228} // namespace SDL
229
230#endif /* SDL3PP_CALLBACK_WRAPPER_H_ */
Main include header for the SDL3pp library.
static Result Call(void *handle, Args... args)
Call.
Definition: SDL3pp_callbackWrapper.h:45
static Result CallOnce(void *handle, Args... args)
Call once and release.
Definition: SDL3pp_callbackWrapper.h:72
static ValueType release(void *handle)
Transfer ownership from the function and delete handle.
Definition: SDL3pp_callbackWrapper.h:92
static Result CallOnceSuffixed(Args... args, void *handle)
Call once and release with suffix handle.
Definition: SDL3pp_callbackWrapper.h:79
static ValueType * Wrap(ValueType &&cb)
Change the callback into a void* pointer.
Definition: SDL3pp_callbackWrapper.h:66
static Result CallSuffixed(Args... args, void *handle)
Call with suffix handle.
Definition: SDL3pp_callbackWrapper.h:52
static const ValueType & Unwrap(void *handle)
Return unwrapped value of handle.
Definition: SDL3pp_callbackWrapper.h:39
std::function< Result(Args...)> ValueType
The wrapped std::function type.
Definition: SDL3pp_callbackWrapper.h:36
Definition: SDL3pp_callbackWrapper.h:20
Lightweight wrapper.
Definition: SDL3pp_callbackWrapper.h:109
void * data
The wrapped data.
Definition: SDL3pp_callbackWrapper.h:114
LightweightCallbackT(const F &func)
ctor
Definition: SDL3pp_callbackWrapper.h:118
R(* wrapper)(void *, PARAMS...)
The wrapper function.
Definition: SDL3pp_callbackWrapper.h:111
Lightweight wrapper.
Definition: SDL3pp_callbackWrapper.h:142
R(* wrapper)(PARAMS..., void *)
The wrapper function.
Definition: SDL3pp_callbackWrapper.h:144
void * data
The wrapped data.
Definition: SDL3pp_callbackWrapper.h:147
LightweightTrailingCallbackT(const F &func)
ctor
Definition: SDL3pp_callbackWrapper.h:151
MakeBackCallback(const F &func)
ctor
Definition: SDL3pp_callbackWrapper.h:211
Definition: SDL3pp_callbackWrapper.h:197
MakeFrontCallback(const F &func)
ctor
Definition: SDL3pp_callbackWrapper.h:183
Definition: SDL3pp_callbackWrapper.h:169