-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathAikoCallback.h
81 lines (59 loc) · 1.93 KB
/
AikoCallback.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#ifndef AikoCallback_h
#define AikoCallback_h
/* Based on "CALLBACKS IN C++ USING TEMPLATE FUNCTORS" by Rich Hickey */
/* http://www.tutok.sk/fastgl/callback.html */
namespace Aiko {
class Callback {
public:
typedef void (*Function)();
typedef void (Callback::*GenericMethodPointer)();
typedef void (*Thunk)(const Callback* callback);
Callback() { }
Callback(Thunk thunk, Function function) {
thunk_ = thunk;
function_ = function;
}
Callback(Thunk thunk, const void* object, const void* method) {
thunk_ = thunk;
object_ = object;
method_ = *static_cast<const GenericMethodPointer*>(method);
}
void operator()() const { thunk_(this); }
Thunk thunk_;
union {
Function function_;
struct {
const void* object_;
GenericMethodPointer method_;
};
};
};
/* Function Callbacks */
class FunctionCallback : public Callback {
public:
FunctionCallback(Function function) : Callback(thunk, function) { }
static void thunk(const Callback* callback) {
(*callback->function_)();
}
};
inline FunctionCallback functionCallback(void (*function)()) {
return FunctionCallback(function);
}
/* Method Callbacks */
template <class Class>
class MemberCallback : public Callback {
public:
typedef void (Class::*MethodPointer)();
MemberCallback(Class& object, const MethodPointer method) : Callback(thunk, &object, &method) { }
static void thunk(const Callback* callback) {
Class *object = (Class*)callback->object_;
MethodPointer method = *reinterpret_cast<const MethodPointer*>(&callback->method_);
(object->*method)();
}
};
template <class Class>
inline MemberCallback<Class> methodCallback(Class &object, void (Class::*method)()) {
return MemberCallback<Class>(object, method);
}
};
#endif