Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed by
api/Callback.h@144:ef7eb2e8f9f7, 2016-09-02 (annotated)
- Committer:
- <>
- Date:
- Fri Sep 02 15:07:44 2016 +0100
- Revision:
- 144:ef7eb2e8f9f7
This updates the lib to the mbed lib v125
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| <> | 144:ef7eb2e8f9f7 | 1 | /* mbed Microcontroller Library |
| <> | 144:ef7eb2e8f9f7 | 2 | * Copyright (c) 2006-2015 ARM Limited |
| <> | 144:ef7eb2e8f9f7 | 3 | * |
| <> | 144:ef7eb2e8f9f7 | 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| <> | 144:ef7eb2e8f9f7 | 5 | * you may not use this file except in compliance with the License. |
| <> | 144:ef7eb2e8f9f7 | 6 | * You may obtain a copy of the License at |
| <> | 144:ef7eb2e8f9f7 | 7 | * |
| <> | 144:ef7eb2e8f9f7 | 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| <> | 144:ef7eb2e8f9f7 | 9 | * |
| <> | 144:ef7eb2e8f9f7 | 10 | * Unless required by applicable law or agreed to in writing, software |
| <> | 144:ef7eb2e8f9f7 | 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| <> | 144:ef7eb2e8f9f7 | 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| <> | 144:ef7eb2e8f9f7 | 13 | * See the License for the specific language governing permissions and |
| <> | 144:ef7eb2e8f9f7 | 14 | * limitations under the License. |
| <> | 144:ef7eb2e8f9f7 | 15 | */ |
| <> | 144:ef7eb2e8f9f7 | 16 | #ifndef MBED_CALLBACK_H |
| <> | 144:ef7eb2e8f9f7 | 17 | #define MBED_CALLBACK_H |
| <> | 144:ef7eb2e8f9f7 | 18 | |
| <> | 144:ef7eb2e8f9f7 | 19 | #include <string.h> |
| <> | 144:ef7eb2e8f9f7 | 20 | #include <stdint.h> |
| <> | 144:ef7eb2e8f9f7 | 21 | |
| <> | 144:ef7eb2e8f9f7 | 22 | namespace mbed { |
| <> | 144:ef7eb2e8f9f7 | 23 | |
| <> | 144:ef7eb2e8f9f7 | 24 | |
| <> | 144:ef7eb2e8f9f7 | 25 | /** Callback class based on template specialization |
| <> | 144:ef7eb2e8f9f7 | 26 | * |
| <> | 144:ef7eb2e8f9f7 | 27 | * @Note Synchronization level: Not protected |
| <> | 144:ef7eb2e8f9f7 | 28 | */ |
| <> | 144:ef7eb2e8f9f7 | 29 | template <typename F> |
| <> | 144:ef7eb2e8f9f7 | 30 | class Callback; |
| <> | 144:ef7eb2e8f9f7 | 31 | |
| <> | 144:ef7eb2e8f9f7 | 32 | /** Templated function class |
| <> | 144:ef7eb2e8f9f7 | 33 | */ |
| <> | 144:ef7eb2e8f9f7 | 34 | template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4> |
| <> | 144:ef7eb2e8f9f7 | 35 | class Callback<R(A0, A1, A2, A3, A4)> { |
| <> | 144:ef7eb2e8f9f7 | 36 | public: |
| <> | 144:ef7eb2e8f9f7 | 37 | /** Create a Callback with a static function |
| <> | 144:ef7eb2e8f9f7 | 38 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 39 | */ |
| <> | 144:ef7eb2e8f9f7 | 40 | Callback(R (*func)(A0, A1, A2, A3, A4) = 0) { |
| <> | 144:ef7eb2e8f9f7 | 41 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 42 | } |
| <> | 144:ef7eb2e8f9f7 | 43 | |
| <> | 144:ef7eb2e8f9f7 | 44 | /** Create a Callback with a static function and bound pointer |
| <> | 144:ef7eb2e8f9f7 | 45 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 46 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 47 | */ |
| <> | 144:ef7eb2e8f9f7 | 48 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 49 | Callback(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) { |
| <> | 144:ef7eb2e8f9f7 | 50 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 51 | } |
| <> | 144:ef7eb2e8f9f7 | 52 | |
| <> | 144:ef7eb2e8f9f7 | 53 | /** Create a Callback with a member function |
| <> | 144:ef7eb2e8f9f7 | 54 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 55 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 56 | */ |
| <> | 144:ef7eb2e8f9f7 | 57 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 58 | Callback(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) { |
| <> | 144:ef7eb2e8f9f7 | 59 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 60 | } |
| <> | 144:ef7eb2e8f9f7 | 61 | |
| <> | 144:ef7eb2e8f9f7 | 62 | /** Create a Callback with another Callback |
| <> | 144:ef7eb2e8f9f7 | 63 | * @param func Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 64 | */ |
| <> | 144:ef7eb2e8f9f7 | 65 | Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 66 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 67 | } |
| <> | 144:ef7eb2e8f9f7 | 68 | |
| <> | 144:ef7eb2e8f9f7 | 69 | /** Attach a static function |
| <> | 144:ef7eb2e8f9f7 | 70 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 71 | */ |
| <> | 144:ef7eb2e8f9f7 | 72 | void attach(R (*func)(A0, A1, A2, A3, A4)) { |
| <> | 144:ef7eb2e8f9f7 | 73 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 74 | _thunk = func ? &Callback::_staticthunk : 0; |
| <> | 144:ef7eb2e8f9f7 | 75 | } |
| <> | 144:ef7eb2e8f9f7 | 76 | |
| <> | 144:ef7eb2e8f9f7 | 77 | /** Attach a static function with a bound pointer |
| <> | 144:ef7eb2e8f9f7 | 78 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 79 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 80 | */ |
| <> | 144:ef7eb2e8f9f7 | 81 | template <typename T> |
| <> | 144:ef7eb2e8f9f7 | 82 | void attach(T *obj, R (*func)(T*, A0, A1, A2, A3, A4)) { |
| <> | 144:ef7eb2e8f9f7 | 83 | _obj = (void*)obj; |
| <> | 144:ef7eb2e8f9f7 | 84 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 85 | _thunk = &Callback::_boundthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 86 | } |
| <> | 144:ef7eb2e8f9f7 | 87 | |
| <> | 144:ef7eb2e8f9f7 | 88 | /** Attach a member function |
| <> | 144:ef7eb2e8f9f7 | 89 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 90 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 91 | */ |
| <> | 144:ef7eb2e8f9f7 | 92 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 93 | void attach(T *obj, R (T::*func)(A0, A1, A2, A3, A4)) { |
| <> | 144:ef7eb2e8f9f7 | 94 | _obj = static_cast<void*>(obj); |
| <> | 144:ef7eb2e8f9f7 | 95 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 96 | _thunk = &Callback::_methodthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 97 | } |
| <> | 144:ef7eb2e8f9f7 | 98 | |
| <> | 144:ef7eb2e8f9f7 | 99 | /** Attach a Callback |
| <> | 144:ef7eb2e8f9f7 | 100 | * @param func The Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 101 | */ |
| <> | 144:ef7eb2e8f9f7 | 102 | void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 103 | _obj = func._obj; |
| <> | 144:ef7eb2e8f9f7 | 104 | memcpy(&_func, &func._func, sizeof _func); |
| <> | 144:ef7eb2e8f9f7 | 105 | _thunk = func._thunk; |
| <> | 144:ef7eb2e8f9f7 | 106 | } |
| <> | 144:ef7eb2e8f9f7 | 107 | |
| <> | 144:ef7eb2e8f9f7 | 108 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 109 | */ |
| <> | 144:ef7eb2e8f9f7 | 110 | R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { |
| <> | 144:ef7eb2e8f9f7 | 111 | if (!_thunk) { |
| <> | 144:ef7eb2e8f9f7 | 112 | return (R)0; |
| <> | 144:ef7eb2e8f9f7 | 113 | } |
| <> | 144:ef7eb2e8f9f7 | 114 | return _thunk(_obj, &_func, a0, a1, a2, a3, a4); |
| <> | 144:ef7eb2e8f9f7 | 115 | } |
| <> | 144:ef7eb2e8f9f7 | 116 | |
| <> | 144:ef7eb2e8f9f7 | 117 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 118 | */ |
| <> | 144:ef7eb2e8f9f7 | 119 | R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { |
| <> | 144:ef7eb2e8f9f7 | 120 | return call(a0, a1, a2, a3, a4); |
| <> | 144:ef7eb2e8f9f7 | 121 | } |
| <> | 144:ef7eb2e8f9f7 | 122 | |
| <> | 144:ef7eb2e8f9f7 | 123 | /** Test if function has been attached |
| <> | 144:ef7eb2e8f9f7 | 124 | */ |
| <> | 144:ef7eb2e8f9f7 | 125 | operator bool() const { |
| <> | 144:ef7eb2e8f9f7 | 126 | return _thunk; |
| <> | 144:ef7eb2e8f9f7 | 127 | } |
| <> | 144:ef7eb2e8f9f7 | 128 | |
| <> | 144:ef7eb2e8f9f7 | 129 | /** Static thunk for passing as C-style function |
| <> | 144:ef7eb2e8f9f7 | 130 | * @param func Callback to call passed as void pointer |
| <> | 144:ef7eb2e8f9f7 | 131 | */ |
| <> | 144:ef7eb2e8f9f7 | 132 | static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { |
| <> | 144:ef7eb2e8f9f7 | 133 | return static_cast<Callback<R(A0, A1, A2, A3, A4)>*>(func) |
| <> | 144:ef7eb2e8f9f7 | 134 | ->call(a0, a1, a2, a3, a4); |
| <> | 144:ef7eb2e8f9f7 | 135 | } |
| <> | 144:ef7eb2e8f9f7 | 136 | |
| <> | 144:ef7eb2e8f9f7 | 137 | private: |
| <> | 144:ef7eb2e8f9f7 | 138 | // Internal thunks for various function types |
| <> | 144:ef7eb2e8f9f7 | 139 | static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { |
| <> | 144:ef7eb2e8f9f7 | 140 | return (*reinterpret_cast<R (**)(A0, A1, A2, A3, A4)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 141 | (a0, a1, a2, a3, a4); |
| <> | 144:ef7eb2e8f9f7 | 142 | } |
| <> | 144:ef7eb2e8f9f7 | 143 | |
| <> | 144:ef7eb2e8f9f7 | 144 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 145 | static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { |
| <> | 144:ef7eb2e8f9f7 | 146 | return (*reinterpret_cast<R (**)(T*, A0, A1, A2, A3, A4)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 147 | (static_cast<T*>(obj), a0, a1, a2, a3, a4); |
| <> | 144:ef7eb2e8f9f7 | 148 | } |
| <> | 144:ef7eb2e8f9f7 | 149 | |
| <> | 144:ef7eb2e8f9f7 | 150 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 151 | static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { |
| <> | 144:ef7eb2e8f9f7 | 152 | return (static_cast<T*>(obj)->* |
| <> | 144:ef7eb2e8f9f7 | 153 | (*reinterpret_cast<R (T::**)(A0, A1, A2, A3, A4)>(func))) |
| <> | 144:ef7eb2e8f9f7 | 154 | (a0, a1, a2, a3, a4); |
| <> | 144:ef7eb2e8f9f7 | 155 | } |
| <> | 144:ef7eb2e8f9f7 | 156 | |
| <> | 144:ef7eb2e8f9f7 | 157 | // Stored as pointer to function and pointer to optional object |
| <> | 144:ef7eb2e8f9f7 | 158 | // Function pointer is stored as union of possible function types |
| <> | 144:ef7eb2e8f9f7 | 159 | // to garuntee proper size and alignment |
| <> | 144:ef7eb2e8f9f7 | 160 | struct _class; |
| <> | 144:ef7eb2e8f9f7 | 161 | union { |
| <> | 144:ef7eb2e8f9f7 | 162 | void (*_staticfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 163 | void (*_boundfunc)(_class *); |
| <> | 144:ef7eb2e8f9f7 | 164 | void (_class::*_methodfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 165 | } _func; |
| <> | 144:ef7eb2e8f9f7 | 166 | |
| <> | 144:ef7eb2e8f9f7 | 167 | void *_obj; |
| <> | 144:ef7eb2e8f9f7 | 168 | |
| <> | 144:ef7eb2e8f9f7 | 169 | // Thunk registered on attach to dispatch calls |
| <> | 144:ef7eb2e8f9f7 | 170 | R (*_thunk)(void*, void*, A0, A1, A2, A3, A4); |
| <> | 144:ef7eb2e8f9f7 | 171 | }; |
| <> | 144:ef7eb2e8f9f7 | 172 | |
| <> | 144:ef7eb2e8f9f7 | 173 | /** Templated function class |
| <> | 144:ef7eb2e8f9f7 | 174 | */ |
| <> | 144:ef7eb2e8f9f7 | 175 | template <typename R, typename A0, typename A1, typename A2, typename A3> |
| <> | 144:ef7eb2e8f9f7 | 176 | class Callback<R(A0, A1, A2, A3)> { |
| <> | 144:ef7eb2e8f9f7 | 177 | public: |
| <> | 144:ef7eb2e8f9f7 | 178 | /** Create a Callback with a static function |
| <> | 144:ef7eb2e8f9f7 | 179 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 180 | */ |
| <> | 144:ef7eb2e8f9f7 | 181 | Callback(R (*func)(A0, A1, A2, A3) = 0) { |
| <> | 144:ef7eb2e8f9f7 | 182 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 183 | } |
| <> | 144:ef7eb2e8f9f7 | 184 | |
| <> | 144:ef7eb2e8f9f7 | 185 | /** Create a Callback with a static function and bound pointer |
| <> | 144:ef7eb2e8f9f7 | 186 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 187 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 188 | */ |
| <> | 144:ef7eb2e8f9f7 | 189 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 190 | Callback(T *obj, R (*func)(T*, A0, A1, A2, A3)) { |
| <> | 144:ef7eb2e8f9f7 | 191 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 192 | } |
| <> | 144:ef7eb2e8f9f7 | 193 | |
| <> | 144:ef7eb2e8f9f7 | 194 | /** Create a Callback with a member function |
| <> | 144:ef7eb2e8f9f7 | 195 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 196 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 197 | */ |
| <> | 144:ef7eb2e8f9f7 | 198 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 199 | Callback(T *obj, R (T::*func)(A0, A1, A2, A3)) { |
| <> | 144:ef7eb2e8f9f7 | 200 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 201 | } |
| <> | 144:ef7eb2e8f9f7 | 202 | |
| <> | 144:ef7eb2e8f9f7 | 203 | /** Create a Callback with another Callback |
| <> | 144:ef7eb2e8f9f7 | 204 | * @param func Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 205 | */ |
| <> | 144:ef7eb2e8f9f7 | 206 | Callback(const Callback<R(A0, A1, A2, A3)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 207 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 208 | } |
| <> | 144:ef7eb2e8f9f7 | 209 | |
| <> | 144:ef7eb2e8f9f7 | 210 | /** Attach a static function |
| <> | 144:ef7eb2e8f9f7 | 211 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 212 | */ |
| <> | 144:ef7eb2e8f9f7 | 213 | void attach(R (*func)(A0, A1, A2, A3)) { |
| <> | 144:ef7eb2e8f9f7 | 214 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 215 | _thunk = func ? &Callback::_staticthunk : 0; |
| <> | 144:ef7eb2e8f9f7 | 216 | } |
| <> | 144:ef7eb2e8f9f7 | 217 | |
| <> | 144:ef7eb2e8f9f7 | 218 | /** Attach a static function with a bound pointer |
| <> | 144:ef7eb2e8f9f7 | 219 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 220 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 221 | */ |
| <> | 144:ef7eb2e8f9f7 | 222 | template <typename T> |
| <> | 144:ef7eb2e8f9f7 | 223 | void attach(T *obj, R (*func)(T*, A0, A1, A2, A3)) { |
| <> | 144:ef7eb2e8f9f7 | 224 | _obj = (void*)obj; |
| <> | 144:ef7eb2e8f9f7 | 225 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 226 | _thunk = &Callback::_boundthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 227 | } |
| <> | 144:ef7eb2e8f9f7 | 228 | |
| <> | 144:ef7eb2e8f9f7 | 229 | /** Attach a member function |
| <> | 144:ef7eb2e8f9f7 | 230 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 231 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 232 | */ |
| <> | 144:ef7eb2e8f9f7 | 233 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 234 | void attach(T *obj, R (T::*func)(A0, A1, A2, A3)) { |
| <> | 144:ef7eb2e8f9f7 | 235 | _obj = static_cast<void*>(obj); |
| <> | 144:ef7eb2e8f9f7 | 236 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 237 | _thunk = &Callback::_methodthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 238 | } |
| <> | 144:ef7eb2e8f9f7 | 239 | |
| <> | 144:ef7eb2e8f9f7 | 240 | /** Attach a Callback |
| <> | 144:ef7eb2e8f9f7 | 241 | * @param func The Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 242 | */ |
| <> | 144:ef7eb2e8f9f7 | 243 | void attach(const Callback<R(A0, A1, A2, A3)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 244 | _obj = func._obj; |
| <> | 144:ef7eb2e8f9f7 | 245 | memcpy(&_func, &func._func, sizeof _func); |
| <> | 144:ef7eb2e8f9f7 | 246 | _thunk = func._thunk; |
| <> | 144:ef7eb2e8f9f7 | 247 | } |
| <> | 144:ef7eb2e8f9f7 | 248 | |
| <> | 144:ef7eb2e8f9f7 | 249 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 250 | */ |
| <> | 144:ef7eb2e8f9f7 | 251 | R call(A0 a0, A1 a1, A2 a2, A3 a3) { |
| <> | 144:ef7eb2e8f9f7 | 252 | if (!_thunk) { |
| <> | 144:ef7eb2e8f9f7 | 253 | return (R)0; |
| <> | 144:ef7eb2e8f9f7 | 254 | } |
| <> | 144:ef7eb2e8f9f7 | 255 | return _thunk(_obj, &_func, a0, a1, a2, a3); |
| <> | 144:ef7eb2e8f9f7 | 256 | } |
| <> | 144:ef7eb2e8f9f7 | 257 | |
| <> | 144:ef7eb2e8f9f7 | 258 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 259 | */ |
| <> | 144:ef7eb2e8f9f7 | 260 | R operator()(A0 a0, A1 a1, A2 a2, A3 a3) { |
| <> | 144:ef7eb2e8f9f7 | 261 | return call(a0, a1, a2, a3); |
| <> | 144:ef7eb2e8f9f7 | 262 | } |
| <> | 144:ef7eb2e8f9f7 | 263 | |
| <> | 144:ef7eb2e8f9f7 | 264 | /** Test if function has been attached |
| <> | 144:ef7eb2e8f9f7 | 265 | */ |
| <> | 144:ef7eb2e8f9f7 | 266 | operator bool() const { |
| <> | 144:ef7eb2e8f9f7 | 267 | return _thunk; |
| <> | 144:ef7eb2e8f9f7 | 268 | } |
| <> | 144:ef7eb2e8f9f7 | 269 | |
| <> | 144:ef7eb2e8f9f7 | 270 | /** Static thunk for passing as C-style function |
| <> | 144:ef7eb2e8f9f7 | 271 | * @param func Callback to call passed as void pointer |
| <> | 144:ef7eb2e8f9f7 | 272 | */ |
| <> | 144:ef7eb2e8f9f7 | 273 | static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) { |
| <> | 144:ef7eb2e8f9f7 | 274 | return static_cast<Callback<R(A0, A1, A2, A3)>*>(func) |
| <> | 144:ef7eb2e8f9f7 | 275 | ->call(a0, a1, a2, a3); |
| <> | 144:ef7eb2e8f9f7 | 276 | } |
| <> | 144:ef7eb2e8f9f7 | 277 | |
| <> | 144:ef7eb2e8f9f7 | 278 | private: |
| <> | 144:ef7eb2e8f9f7 | 279 | // Internal thunks for various function types |
| <> | 144:ef7eb2e8f9f7 | 280 | static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2, A3 a3) { |
| <> | 144:ef7eb2e8f9f7 | 281 | return (*reinterpret_cast<R (**)(A0, A1, A2, A3)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 282 | (a0, a1, a2, a3); |
| <> | 144:ef7eb2e8f9f7 | 283 | } |
| <> | 144:ef7eb2e8f9f7 | 284 | |
| <> | 144:ef7eb2e8f9f7 | 285 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 286 | static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3) { |
| <> | 144:ef7eb2e8f9f7 | 287 | return (*reinterpret_cast<R (**)(T*, A0, A1, A2, A3)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 288 | (static_cast<T*>(obj), a0, a1, a2, a3); |
| <> | 144:ef7eb2e8f9f7 | 289 | } |
| <> | 144:ef7eb2e8f9f7 | 290 | |
| <> | 144:ef7eb2e8f9f7 | 291 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 292 | static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2, A3 a3) { |
| <> | 144:ef7eb2e8f9f7 | 293 | return (static_cast<T*>(obj)->* |
| <> | 144:ef7eb2e8f9f7 | 294 | (*reinterpret_cast<R (T::**)(A0, A1, A2, A3)>(func))) |
| <> | 144:ef7eb2e8f9f7 | 295 | (a0, a1, a2, a3); |
| <> | 144:ef7eb2e8f9f7 | 296 | } |
| <> | 144:ef7eb2e8f9f7 | 297 | |
| <> | 144:ef7eb2e8f9f7 | 298 | // Stored as pointer to function and pointer to optional object |
| <> | 144:ef7eb2e8f9f7 | 299 | // Function pointer is stored as union of possible function types |
| <> | 144:ef7eb2e8f9f7 | 300 | // to garuntee proper size and alignment |
| <> | 144:ef7eb2e8f9f7 | 301 | struct _class; |
| <> | 144:ef7eb2e8f9f7 | 302 | union { |
| <> | 144:ef7eb2e8f9f7 | 303 | void (*_staticfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 304 | void (*_boundfunc)(_class *); |
| <> | 144:ef7eb2e8f9f7 | 305 | void (_class::*_methodfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 306 | } _func; |
| <> | 144:ef7eb2e8f9f7 | 307 | |
| <> | 144:ef7eb2e8f9f7 | 308 | void *_obj; |
| <> | 144:ef7eb2e8f9f7 | 309 | |
| <> | 144:ef7eb2e8f9f7 | 310 | // Thunk registered on attach to dispatch calls |
| <> | 144:ef7eb2e8f9f7 | 311 | R (*_thunk)(void*, void*, A0, A1, A2, A3); |
| <> | 144:ef7eb2e8f9f7 | 312 | }; |
| <> | 144:ef7eb2e8f9f7 | 313 | |
| <> | 144:ef7eb2e8f9f7 | 314 | /** Templated function class |
| <> | 144:ef7eb2e8f9f7 | 315 | */ |
| <> | 144:ef7eb2e8f9f7 | 316 | template <typename R, typename A0, typename A1, typename A2> |
| <> | 144:ef7eb2e8f9f7 | 317 | class Callback<R(A0, A1, A2)> { |
| <> | 144:ef7eb2e8f9f7 | 318 | public: |
| <> | 144:ef7eb2e8f9f7 | 319 | /** Create a Callback with a static function |
| <> | 144:ef7eb2e8f9f7 | 320 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 321 | */ |
| <> | 144:ef7eb2e8f9f7 | 322 | Callback(R (*func)(A0, A1, A2) = 0) { |
| <> | 144:ef7eb2e8f9f7 | 323 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 324 | } |
| <> | 144:ef7eb2e8f9f7 | 325 | |
| <> | 144:ef7eb2e8f9f7 | 326 | /** Create a Callback with a static function and bound pointer |
| <> | 144:ef7eb2e8f9f7 | 327 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 328 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 329 | */ |
| <> | 144:ef7eb2e8f9f7 | 330 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 331 | Callback(T *obj, R (*func)(T*, A0, A1, A2)) { |
| <> | 144:ef7eb2e8f9f7 | 332 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 333 | } |
| <> | 144:ef7eb2e8f9f7 | 334 | |
| <> | 144:ef7eb2e8f9f7 | 335 | /** Create a Callback with a member function |
| <> | 144:ef7eb2e8f9f7 | 336 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 337 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 338 | */ |
| <> | 144:ef7eb2e8f9f7 | 339 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 340 | Callback(T *obj, R (T::*func)(A0, A1, A2)) { |
| <> | 144:ef7eb2e8f9f7 | 341 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 342 | } |
| <> | 144:ef7eb2e8f9f7 | 343 | |
| <> | 144:ef7eb2e8f9f7 | 344 | /** Create a Callback with another Callback |
| <> | 144:ef7eb2e8f9f7 | 345 | * @param func Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 346 | */ |
| <> | 144:ef7eb2e8f9f7 | 347 | Callback(const Callback<R(A0, A1, A2)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 348 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 349 | } |
| <> | 144:ef7eb2e8f9f7 | 350 | |
| <> | 144:ef7eb2e8f9f7 | 351 | /** Attach a static function |
| <> | 144:ef7eb2e8f9f7 | 352 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 353 | */ |
| <> | 144:ef7eb2e8f9f7 | 354 | void attach(R (*func)(A0, A1, A2)) { |
| <> | 144:ef7eb2e8f9f7 | 355 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 356 | _thunk = func ? &Callback::_staticthunk : 0; |
| <> | 144:ef7eb2e8f9f7 | 357 | } |
| <> | 144:ef7eb2e8f9f7 | 358 | |
| <> | 144:ef7eb2e8f9f7 | 359 | /** Attach a static function with a bound pointer |
| <> | 144:ef7eb2e8f9f7 | 360 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 361 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 362 | */ |
| <> | 144:ef7eb2e8f9f7 | 363 | template <typename T> |
| <> | 144:ef7eb2e8f9f7 | 364 | void attach(T *obj, R (*func)(T*, A0, A1, A2)) { |
| <> | 144:ef7eb2e8f9f7 | 365 | _obj = (void*)obj; |
| <> | 144:ef7eb2e8f9f7 | 366 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 367 | _thunk = &Callback::_boundthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 368 | } |
| <> | 144:ef7eb2e8f9f7 | 369 | |
| <> | 144:ef7eb2e8f9f7 | 370 | /** Attach a member function |
| <> | 144:ef7eb2e8f9f7 | 371 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 372 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 373 | */ |
| <> | 144:ef7eb2e8f9f7 | 374 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 375 | void attach(T *obj, R (T::*func)(A0, A1, A2)) { |
| <> | 144:ef7eb2e8f9f7 | 376 | _obj = static_cast<void*>(obj); |
| <> | 144:ef7eb2e8f9f7 | 377 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 378 | _thunk = &Callback::_methodthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 379 | } |
| <> | 144:ef7eb2e8f9f7 | 380 | |
| <> | 144:ef7eb2e8f9f7 | 381 | /** Attach a Callback |
| <> | 144:ef7eb2e8f9f7 | 382 | * @param func The Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 383 | */ |
| <> | 144:ef7eb2e8f9f7 | 384 | void attach(const Callback<R(A0, A1, A2)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 385 | _obj = func._obj; |
| <> | 144:ef7eb2e8f9f7 | 386 | memcpy(&_func, &func._func, sizeof _func); |
| <> | 144:ef7eb2e8f9f7 | 387 | _thunk = func._thunk; |
| <> | 144:ef7eb2e8f9f7 | 388 | } |
| <> | 144:ef7eb2e8f9f7 | 389 | |
| <> | 144:ef7eb2e8f9f7 | 390 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 391 | */ |
| <> | 144:ef7eb2e8f9f7 | 392 | R call(A0 a0, A1 a1, A2 a2) { |
| <> | 144:ef7eb2e8f9f7 | 393 | if (!_thunk) { |
| <> | 144:ef7eb2e8f9f7 | 394 | return (R)0; |
| <> | 144:ef7eb2e8f9f7 | 395 | } |
| <> | 144:ef7eb2e8f9f7 | 396 | return _thunk(_obj, &_func, a0, a1, a2); |
| <> | 144:ef7eb2e8f9f7 | 397 | } |
| <> | 144:ef7eb2e8f9f7 | 398 | |
| <> | 144:ef7eb2e8f9f7 | 399 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 400 | */ |
| <> | 144:ef7eb2e8f9f7 | 401 | R operator()(A0 a0, A1 a1, A2 a2) { |
| <> | 144:ef7eb2e8f9f7 | 402 | return call(a0, a1, a2); |
| <> | 144:ef7eb2e8f9f7 | 403 | } |
| <> | 144:ef7eb2e8f9f7 | 404 | |
| <> | 144:ef7eb2e8f9f7 | 405 | /** Test if function has been attached |
| <> | 144:ef7eb2e8f9f7 | 406 | */ |
| <> | 144:ef7eb2e8f9f7 | 407 | operator bool() const { |
| <> | 144:ef7eb2e8f9f7 | 408 | return _thunk; |
| <> | 144:ef7eb2e8f9f7 | 409 | } |
| <> | 144:ef7eb2e8f9f7 | 410 | |
| <> | 144:ef7eb2e8f9f7 | 411 | /** Static thunk for passing as C-style function |
| <> | 144:ef7eb2e8f9f7 | 412 | * @param func Callback to call passed as void pointer |
| <> | 144:ef7eb2e8f9f7 | 413 | */ |
| <> | 144:ef7eb2e8f9f7 | 414 | static R thunk(void *func, A0 a0, A1 a1, A2 a2) { |
| <> | 144:ef7eb2e8f9f7 | 415 | return static_cast<Callback<R(A0, A1, A2)>*>(func) |
| <> | 144:ef7eb2e8f9f7 | 416 | ->call(a0, a1, a2); |
| <> | 144:ef7eb2e8f9f7 | 417 | } |
| <> | 144:ef7eb2e8f9f7 | 418 | |
| <> | 144:ef7eb2e8f9f7 | 419 | private: |
| <> | 144:ef7eb2e8f9f7 | 420 | // Internal thunks for various function types |
| <> | 144:ef7eb2e8f9f7 | 421 | static R _staticthunk(void*, void *func, A0 a0, A1 a1, A2 a2) { |
| <> | 144:ef7eb2e8f9f7 | 422 | return (*reinterpret_cast<R (**)(A0, A1, A2)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 423 | (a0, a1, a2); |
| <> | 144:ef7eb2e8f9f7 | 424 | } |
| <> | 144:ef7eb2e8f9f7 | 425 | |
| <> | 144:ef7eb2e8f9f7 | 426 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 427 | static R _boundthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2) { |
| <> | 144:ef7eb2e8f9f7 | 428 | return (*reinterpret_cast<R (**)(T*, A0, A1, A2)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 429 | (static_cast<T*>(obj), a0, a1, a2); |
| <> | 144:ef7eb2e8f9f7 | 430 | } |
| <> | 144:ef7eb2e8f9f7 | 431 | |
| <> | 144:ef7eb2e8f9f7 | 432 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 433 | static R _methodthunk(void *obj, void *func, A0 a0, A1 a1, A2 a2) { |
| <> | 144:ef7eb2e8f9f7 | 434 | return (static_cast<T*>(obj)->* |
| <> | 144:ef7eb2e8f9f7 | 435 | (*reinterpret_cast<R (T::**)(A0, A1, A2)>(func))) |
| <> | 144:ef7eb2e8f9f7 | 436 | (a0, a1, a2); |
| <> | 144:ef7eb2e8f9f7 | 437 | } |
| <> | 144:ef7eb2e8f9f7 | 438 | |
| <> | 144:ef7eb2e8f9f7 | 439 | // Stored as pointer to function and pointer to optional object |
| <> | 144:ef7eb2e8f9f7 | 440 | // Function pointer is stored as union of possible function types |
| <> | 144:ef7eb2e8f9f7 | 441 | // to garuntee proper size and alignment |
| <> | 144:ef7eb2e8f9f7 | 442 | struct _class; |
| <> | 144:ef7eb2e8f9f7 | 443 | union { |
| <> | 144:ef7eb2e8f9f7 | 444 | void (*_staticfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 445 | void (*_boundfunc)(_class *); |
| <> | 144:ef7eb2e8f9f7 | 446 | void (_class::*_methodfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 447 | } _func; |
| <> | 144:ef7eb2e8f9f7 | 448 | |
| <> | 144:ef7eb2e8f9f7 | 449 | void *_obj; |
| <> | 144:ef7eb2e8f9f7 | 450 | |
| <> | 144:ef7eb2e8f9f7 | 451 | // Thunk registered on attach to dispatch calls |
| <> | 144:ef7eb2e8f9f7 | 452 | R (*_thunk)(void*, void*, A0, A1, A2); |
| <> | 144:ef7eb2e8f9f7 | 453 | }; |
| <> | 144:ef7eb2e8f9f7 | 454 | |
| <> | 144:ef7eb2e8f9f7 | 455 | /** Templated function class |
| <> | 144:ef7eb2e8f9f7 | 456 | */ |
| <> | 144:ef7eb2e8f9f7 | 457 | template <typename R, typename A0, typename A1> |
| <> | 144:ef7eb2e8f9f7 | 458 | class Callback<R(A0, A1)> { |
| <> | 144:ef7eb2e8f9f7 | 459 | public: |
| <> | 144:ef7eb2e8f9f7 | 460 | /** Create a Callback with a static function |
| <> | 144:ef7eb2e8f9f7 | 461 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 462 | */ |
| <> | 144:ef7eb2e8f9f7 | 463 | Callback(R (*func)(A0, A1) = 0) { |
| <> | 144:ef7eb2e8f9f7 | 464 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 465 | } |
| <> | 144:ef7eb2e8f9f7 | 466 | |
| <> | 144:ef7eb2e8f9f7 | 467 | /** Create a Callback with a static function and bound pointer |
| <> | 144:ef7eb2e8f9f7 | 468 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 469 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 470 | */ |
| <> | 144:ef7eb2e8f9f7 | 471 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 472 | Callback(T *obj, R (*func)(T*, A0, A1)) { |
| <> | 144:ef7eb2e8f9f7 | 473 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 474 | } |
| <> | 144:ef7eb2e8f9f7 | 475 | |
| <> | 144:ef7eb2e8f9f7 | 476 | /** Create a Callback with a member function |
| <> | 144:ef7eb2e8f9f7 | 477 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 478 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 479 | */ |
| <> | 144:ef7eb2e8f9f7 | 480 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 481 | Callback(T *obj, R (T::*func)(A0, A1)) { |
| <> | 144:ef7eb2e8f9f7 | 482 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 483 | } |
| <> | 144:ef7eb2e8f9f7 | 484 | |
| <> | 144:ef7eb2e8f9f7 | 485 | /** Create a Callback with another Callback |
| <> | 144:ef7eb2e8f9f7 | 486 | * @param func Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 487 | */ |
| <> | 144:ef7eb2e8f9f7 | 488 | Callback(const Callback<R(A0, A1)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 489 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 490 | } |
| <> | 144:ef7eb2e8f9f7 | 491 | |
| <> | 144:ef7eb2e8f9f7 | 492 | /** Attach a static function |
| <> | 144:ef7eb2e8f9f7 | 493 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 494 | */ |
| <> | 144:ef7eb2e8f9f7 | 495 | void attach(R (*func)(A0, A1)) { |
| <> | 144:ef7eb2e8f9f7 | 496 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 497 | _thunk = func ? &Callback::_staticthunk : 0; |
| <> | 144:ef7eb2e8f9f7 | 498 | } |
| <> | 144:ef7eb2e8f9f7 | 499 | |
| <> | 144:ef7eb2e8f9f7 | 500 | /** Attach a static function with a bound pointer |
| <> | 144:ef7eb2e8f9f7 | 501 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 502 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 503 | */ |
| <> | 144:ef7eb2e8f9f7 | 504 | template <typename T> |
| <> | 144:ef7eb2e8f9f7 | 505 | void attach(T *obj, R (*func)(T*, A0, A1)) { |
| <> | 144:ef7eb2e8f9f7 | 506 | _obj = (void*)obj; |
| <> | 144:ef7eb2e8f9f7 | 507 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 508 | _thunk = &Callback::_boundthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 509 | } |
| <> | 144:ef7eb2e8f9f7 | 510 | |
| <> | 144:ef7eb2e8f9f7 | 511 | /** Attach a member function |
| <> | 144:ef7eb2e8f9f7 | 512 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 513 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 514 | */ |
| <> | 144:ef7eb2e8f9f7 | 515 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 516 | void attach(T *obj, R (T::*func)(A0, A1)) { |
| <> | 144:ef7eb2e8f9f7 | 517 | _obj = static_cast<void*>(obj); |
| <> | 144:ef7eb2e8f9f7 | 518 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 519 | _thunk = &Callback::_methodthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 520 | } |
| <> | 144:ef7eb2e8f9f7 | 521 | |
| <> | 144:ef7eb2e8f9f7 | 522 | /** Attach a Callback |
| <> | 144:ef7eb2e8f9f7 | 523 | * @param func The Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 524 | */ |
| <> | 144:ef7eb2e8f9f7 | 525 | void attach(const Callback<R(A0, A1)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 526 | _obj = func._obj; |
| <> | 144:ef7eb2e8f9f7 | 527 | memcpy(&_func, &func._func, sizeof _func); |
| <> | 144:ef7eb2e8f9f7 | 528 | _thunk = func._thunk; |
| <> | 144:ef7eb2e8f9f7 | 529 | } |
| <> | 144:ef7eb2e8f9f7 | 530 | |
| <> | 144:ef7eb2e8f9f7 | 531 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 532 | */ |
| <> | 144:ef7eb2e8f9f7 | 533 | R call(A0 a0, A1 a1) { |
| <> | 144:ef7eb2e8f9f7 | 534 | if (!_thunk) { |
| <> | 144:ef7eb2e8f9f7 | 535 | return (R)0; |
| <> | 144:ef7eb2e8f9f7 | 536 | } |
| <> | 144:ef7eb2e8f9f7 | 537 | return _thunk(_obj, &_func, a0, a1); |
| <> | 144:ef7eb2e8f9f7 | 538 | } |
| <> | 144:ef7eb2e8f9f7 | 539 | |
| <> | 144:ef7eb2e8f9f7 | 540 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 541 | */ |
| <> | 144:ef7eb2e8f9f7 | 542 | R operator()(A0 a0, A1 a1) { |
| <> | 144:ef7eb2e8f9f7 | 543 | return call(a0, a1); |
| <> | 144:ef7eb2e8f9f7 | 544 | } |
| <> | 144:ef7eb2e8f9f7 | 545 | |
| <> | 144:ef7eb2e8f9f7 | 546 | /** Test if function has been attached |
| <> | 144:ef7eb2e8f9f7 | 547 | */ |
| <> | 144:ef7eb2e8f9f7 | 548 | operator bool() const { |
| <> | 144:ef7eb2e8f9f7 | 549 | return _thunk; |
| <> | 144:ef7eb2e8f9f7 | 550 | } |
| <> | 144:ef7eb2e8f9f7 | 551 | |
| <> | 144:ef7eb2e8f9f7 | 552 | /** Static thunk for passing as C-style function |
| <> | 144:ef7eb2e8f9f7 | 553 | * @param func Callback to call passed as void pointer |
| <> | 144:ef7eb2e8f9f7 | 554 | */ |
| <> | 144:ef7eb2e8f9f7 | 555 | static R thunk(void *func, A0 a0, A1 a1) { |
| <> | 144:ef7eb2e8f9f7 | 556 | return static_cast<Callback<R(A0, A1)>*>(func) |
| <> | 144:ef7eb2e8f9f7 | 557 | ->call(a0, a1); |
| <> | 144:ef7eb2e8f9f7 | 558 | } |
| <> | 144:ef7eb2e8f9f7 | 559 | |
| <> | 144:ef7eb2e8f9f7 | 560 | private: |
| <> | 144:ef7eb2e8f9f7 | 561 | // Internal thunks for various function types |
| <> | 144:ef7eb2e8f9f7 | 562 | static R _staticthunk(void*, void *func, A0 a0, A1 a1) { |
| <> | 144:ef7eb2e8f9f7 | 563 | return (*reinterpret_cast<R (**)(A0, A1)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 564 | (a0, a1); |
| <> | 144:ef7eb2e8f9f7 | 565 | } |
| <> | 144:ef7eb2e8f9f7 | 566 | |
| <> | 144:ef7eb2e8f9f7 | 567 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 568 | static R _boundthunk(void *obj, void *func, A0 a0, A1 a1) { |
| <> | 144:ef7eb2e8f9f7 | 569 | return (*reinterpret_cast<R (**)(T*, A0, A1)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 570 | (static_cast<T*>(obj), a0, a1); |
| <> | 144:ef7eb2e8f9f7 | 571 | } |
| <> | 144:ef7eb2e8f9f7 | 572 | |
| <> | 144:ef7eb2e8f9f7 | 573 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 574 | static R _methodthunk(void *obj, void *func, A0 a0, A1 a1) { |
| <> | 144:ef7eb2e8f9f7 | 575 | return (static_cast<T*>(obj)->* |
| <> | 144:ef7eb2e8f9f7 | 576 | (*reinterpret_cast<R (T::**)(A0, A1)>(func))) |
| <> | 144:ef7eb2e8f9f7 | 577 | (a0, a1); |
| <> | 144:ef7eb2e8f9f7 | 578 | } |
| <> | 144:ef7eb2e8f9f7 | 579 | |
| <> | 144:ef7eb2e8f9f7 | 580 | // Stored as pointer to function and pointer to optional object |
| <> | 144:ef7eb2e8f9f7 | 581 | // Function pointer is stored as union of possible function types |
| <> | 144:ef7eb2e8f9f7 | 582 | // to garuntee proper size and alignment |
| <> | 144:ef7eb2e8f9f7 | 583 | struct _class; |
| <> | 144:ef7eb2e8f9f7 | 584 | union { |
| <> | 144:ef7eb2e8f9f7 | 585 | void (*_staticfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 586 | void (*_boundfunc)(_class *); |
| <> | 144:ef7eb2e8f9f7 | 587 | void (_class::*_methodfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 588 | } _func; |
| <> | 144:ef7eb2e8f9f7 | 589 | |
| <> | 144:ef7eb2e8f9f7 | 590 | void *_obj; |
| <> | 144:ef7eb2e8f9f7 | 591 | |
| <> | 144:ef7eb2e8f9f7 | 592 | // Thunk registered on attach to dispatch calls |
| <> | 144:ef7eb2e8f9f7 | 593 | R (*_thunk)(void*, void*, A0, A1); |
| <> | 144:ef7eb2e8f9f7 | 594 | }; |
| <> | 144:ef7eb2e8f9f7 | 595 | |
| <> | 144:ef7eb2e8f9f7 | 596 | /** Templated function class |
| <> | 144:ef7eb2e8f9f7 | 597 | */ |
| <> | 144:ef7eb2e8f9f7 | 598 | template <typename R, typename A0> |
| <> | 144:ef7eb2e8f9f7 | 599 | class Callback<R(A0)> { |
| <> | 144:ef7eb2e8f9f7 | 600 | public: |
| <> | 144:ef7eb2e8f9f7 | 601 | /** Create a Callback with a static function |
| <> | 144:ef7eb2e8f9f7 | 602 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 603 | */ |
| <> | 144:ef7eb2e8f9f7 | 604 | Callback(R (*func)(A0) = 0) { |
| <> | 144:ef7eb2e8f9f7 | 605 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 606 | } |
| <> | 144:ef7eb2e8f9f7 | 607 | |
| <> | 144:ef7eb2e8f9f7 | 608 | /** Create a Callback with a static function and bound pointer |
| <> | 144:ef7eb2e8f9f7 | 609 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 610 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 611 | */ |
| <> | 144:ef7eb2e8f9f7 | 612 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 613 | Callback(T *obj, R (*func)(T*, A0)) { |
| <> | 144:ef7eb2e8f9f7 | 614 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 615 | } |
| <> | 144:ef7eb2e8f9f7 | 616 | |
| <> | 144:ef7eb2e8f9f7 | 617 | /** Create a Callback with a member function |
| <> | 144:ef7eb2e8f9f7 | 618 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 619 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 620 | */ |
| <> | 144:ef7eb2e8f9f7 | 621 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 622 | Callback(T *obj, R (T::*func)(A0)) { |
| <> | 144:ef7eb2e8f9f7 | 623 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 624 | } |
| <> | 144:ef7eb2e8f9f7 | 625 | |
| <> | 144:ef7eb2e8f9f7 | 626 | /** Create a Callback with another Callback |
| <> | 144:ef7eb2e8f9f7 | 627 | * @param func Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 628 | */ |
| <> | 144:ef7eb2e8f9f7 | 629 | Callback(const Callback<R(A0)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 630 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 631 | } |
| <> | 144:ef7eb2e8f9f7 | 632 | |
| <> | 144:ef7eb2e8f9f7 | 633 | /** Attach a static function |
| <> | 144:ef7eb2e8f9f7 | 634 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 635 | */ |
| <> | 144:ef7eb2e8f9f7 | 636 | void attach(R (*func)(A0)) { |
| <> | 144:ef7eb2e8f9f7 | 637 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 638 | _thunk = func ? &Callback::_staticthunk : 0; |
| <> | 144:ef7eb2e8f9f7 | 639 | } |
| <> | 144:ef7eb2e8f9f7 | 640 | |
| <> | 144:ef7eb2e8f9f7 | 641 | /** Attach a static function with a bound pointer |
| <> | 144:ef7eb2e8f9f7 | 642 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 643 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 644 | */ |
| <> | 144:ef7eb2e8f9f7 | 645 | template <typename T> |
| <> | 144:ef7eb2e8f9f7 | 646 | void attach(T *obj, R (*func)(T*, A0)) { |
| <> | 144:ef7eb2e8f9f7 | 647 | _obj = (void*)obj; |
| <> | 144:ef7eb2e8f9f7 | 648 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 649 | _thunk = &Callback::_boundthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 650 | } |
| <> | 144:ef7eb2e8f9f7 | 651 | |
| <> | 144:ef7eb2e8f9f7 | 652 | /** Attach a member function |
| <> | 144:ef7eb2e8f9f7 | 653 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 654 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 655 | */ |
| <> | 144:ef7eb2e8f9f7 | 656 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 657 | void attach(T *obj, R (T::*func)(A0)) { |
| <> | 144:ef7eb2e8f9f7 | 658 | _obj = static_cast<void*>(obj); |
| <> | 144:ef7eb2e8f9f7 | 659 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 660 | _thunk = &Callback::_methodthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 661 | } |
| <> | 144:ef7eb2e8f9f7 | 662 | |
| <> | 144:ef7eb2e8f9f7 | 663 | /** Attach a Callback |
| <> | 144:ef7eb2e8f9f7 | 664 | * @param func The Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 665 | */ |
| <> | 144:ef7eb2e8f9f7 | 666 | void attach(const Callback<R(A0)> &func) { |
| <> | 144:ef7eb2e8f9f7 | 667 | _obj = func._obj; |
| <> | 144:ef7eb2e8f9f7 | 668 | memcpy(&_func, &func._func, sizeof _func); |
| <> | 144:ef7eb2e8f9f7 | 669 | _thunk = func._thunk; |
| <> | 144:ef7eb2e8f9f7 | 670 | } |
| <> | 144:ef7eb2e8f9f7 | 671 | |
| <> | 144:ef7eb2e8f9f7 | 672 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 673 | */ |
| <> | 144:ef7eb2e8f9f7 | 674 | R call(A0 a0) { |
| <> | 144:ef7eb2e8f9f7 | 675 | if (!_thunk) { |
| <> | 144:ef7eb2e8f9f7 | 676 | return (R)0; |
| <> | 144:ef7eb2e8f9f7 | 677 | } |
| <> | 144:ef7eb2e8f9f7 | 678 | return _thunk(_obj, &_func, a0); |
| <> | 144:ef7eb2e8f9f7 | 679 | } |
| <> | 144:ef7eb2e8f9f7 | 680 | |
| <> | 144:ef7eb2e8f9f7 | 681 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 682 | */ |
| <> | 144:ef7eb2e8f9f7 | 683 | R operator()(A0 a0) { |
| <> | 144:ef7eb2e8f9f7 | 684 | return call(a0); |
| <> | 144:ef7eb2e8f9f7 | 685 | } |
| <> | 144:ef7eb2e8f9f7 | 686 | |
| <> | 144:ef7eb2e8f9f7 | 687 | /** Test if function has been attached |
| <> | 144:ef7eb2e8f9f7 | 688 | */ |
| <> | 144:ef7eb2e8f9f7 | 689 | operator bool() const { |
| <> | 144:ef7eb2e8f9f7 | 690 | return _thunk; |
| <> | 144:ef7eb2e8f9f7 | 691 | } |
| <> | 144:ef7eb2e8f9f7 | 692 | |
| <> | 144:ef7eb2e8f9f7 | 693 | /** Static thunk for passing as C-style function |
| <> | 144:ef7eb2e8f9f7 | 694 | * @param func Callback to call passed as void pointer |
| <> | 144:ef7eb2e8f9f7 | 695 | */ |
| <> | 144:ef7eb2e8f9f7 | 696 | static R thunk(void *func, A0 a0) { |
| <> | 144:ef7eb2e8f9f7 | 697 | return static_cast<Callback<R(A0)>*>(func) |
| <> | 144:ef7eb2e8f9f7 | 698 | ->call(a0); |
| <> | 144:ef7eb2e8f9f7 | 699 | } |
| <> | 144:ef7eb2e8f9f7 | 700 | |
| <> | 144:ef7eb2e8f9f7 | 701 | private: |
| <> | 144:ef7eb2e8f9f7 | 702 | // Internal thunks for various function types |
| <> | 144:ef7eb2e8f9f7 | 703 | static R _staticthunk(void*, void *func, A0 a0) { |
| <> | 144:ef7eb2e8f9f7 | 704 | return (*reinterpret_cast<R (**)(A0)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 705 | (a0); |
| <> | 144:ef7eb2e8f9f7 | 706 | } |
| <> | 144:ef7eb2e8f9f7 | 707 | |
| <> | 144:ef7eb2e8f9f7 | 708 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 709 | static R _boundthunk(void *obj, void *func, A0 a0) { |
| <> | 144:ef7eb2e8f9f7 | 710 | return (*reinterpret_cast<R (**)(T*, A0)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 711 | (static_cast<T*>(obj), a0); |
| <> | 144:ef7eb2e8f9f7 | 712 | } |
| <> | 144:ef7eb2e8f9f7 | 713 | |
| <> | 144:ef7eb2e8f9f7 | 714 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 715 | static R _methodthunk(void *obj, void *func, A0 a0) { |
| <> | 144:ef7eb2e8f9f7 | 716 | return (static_cast<T*>(obj)->* |
| <> | 144:ef7eb2e8f9f7 | 717 | (*reinterpret_cast<R (T::**)(A0)>(func))) |
| <> | 144:ef7eb2e8f9f7 | 718 | (a0); |
| <> | 144:ef7eb2e8f9f7 | 719 | } |
| <> | 144:ef7eb2e8f9f7 | 720 | |
| <> | 144:ef7eb2e8f9f7 | 721 | // Stored as pointer to function and pointer to optional object |
| <> | 144:ef7eb2e8f9f7 | 722 | // Function pointer is stored as union of possible function types |
| <> | 144:ef7eb2e8f9f7 | 723 | // to garuntee proper size and alignment |
| <> | 144:ef7eb2e8f9f7 | 724 | struct _class; |
| <> | 144:ef7eb2e8f9f7 | 725 | union { |
| <> | 144:ef7eb2e8f9f7 | 726 | void (*_staticfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 727 | void (*_boundfunc)(_class *); |
| <> | 144:ef7eb2e8f9f7 | 728 | void (_class::*_methodfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 729 | } _func; |
| <> | 144:ef7eb2e8f9f7 | 730 | |
| <> | 144:ef7eb2e8f9f7 | 731 | void *_obj; |
| <> | 144:ef7eb2e8f9f7 | 732 | |
| <> | 144:ef7eb2e8f9f7 | 733 | // Thunk registered on attach to dispatch calls |
| <> | 144:ef7eb2e8f9f7 | 734 | R (*_thunk)(void*, void*, A0); |
| <> | 144:ef7eb2e8f9f7 | 735 | }; |
| <> | 144:ef7eb2e8f9f7 | 736 | |
| <> | 144:ef7eb2e8f9f7 | 737 | /** Templated function class |
| <> | 144:ef7eb2e8f9f7 | 738 | */ |
| <> | 144:ef7eb2e8f9f7 | 739 | template <typename R> |
| <> | 144:ef7eb2e8f9f7 | 740 | class Callback<R()> { |
| <> | 144:ef7eb2e8f9f7 | 741 | public: |
| <> | 144:ef7eb2e8f9f7 | 742 | /** Create a Callback with a static function |
| <> | 144:ef7eb2e8f9f7 | 743 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 744 | */ |
| <> | 144:ef7eb2e8f9f7 | 745 | Callback(R (*func)() = 0) { |
| <> | 144:ef7eb2e8f9f7 | 746 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 747 | } |
| <> | 144:ef7eb2e8f9f7 | 748 | |
| <> | 144:ef7eb2e8f9f7 | 749 | /** Create a Callback with a static function and bound pointer |
| <> | 144:ef7eb2e8f9f7 | 750 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 751 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 752 | */ |
| <> | 144:ef7eb2e8f9f7 | 753 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 754 | Callback(T *obj, R (*func)(T*)) { |
| <> | 144:ef7eb2e8f9f7 | 755 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 756 | } |
| <> | 144:ef7eb2e8f9f7 | 757 | |
| <> | 144:ef7eb2e8f9f7 | 758 | /** Create a Callback with a member function |
| <> | 144:ef7eb2e8f9f7 | 759 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 760 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 761 | */ |
| <> | 144:ef7eb2e8f9f7 | 762 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 763 | Callback(T *obj, R (T::*func)()) { |
| <> | 144:ef7eb2e8f9f7 | 764 | attach(obj, func); |
| <> | 144:ef7eb2e8f9f7 | 765 | } |
| <> | 144:ef7eb2e8f9f7 | 766 | |
| <> | 144:ef7eb2e8f9f7 | 767 | /** Create a Callback with another Callback |
| <> | 144:ef7eb2e8f9f7 | 768 | * @param func Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 769 | */ |
| <> | 144:ef7eb2e8f9f7 | 770 | Callback(const Callback<R()> &func) { |
| <> | 144:ef7eb2e8f9f7 | 771 | attach(func); |
| <> | 144:ef7eb2e8f9f7 | 772 | } |
| <> | 144:ef7eb2e8f9f7 | 773 | |
| <> | 144:ef7eb2e8f9f7 | 774 | /** Attach a static function |
| <> | 144:ef7eb2e8f9f7 | 775 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 776 | */ |
| <> | 144:ef7eb2e8f9f7 | 777 | void attach(R (*func)()) { |
| <> | 144:ef7eb2e8f9f7 | 778 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 779 | _thunk = func ? &Callback::_staticthunk : 0; |
| <> | 144:ef7eb2e8f9f7 | 780 | } |
| <> | 144:ef7eb2e8f9f7 | 781 | |
| <> | 144:ef7eb2e8f9f7 | 782 | /** Attach a static function with a bound pointer |
| <> | 144:ef7eb2e8f9f7 | 783 | * @param obj Pointer to object to bind to function |
| <> | 144:ef7eb2e8f9f7 | 784 | * @param func Static function to attach |
| <> | 144:ef7eb2e8f9f7 | 785 | */ |
| <> | 144:ef7eb2e8f9f7 | 786 | template <typename T> |
| <> | 144:ef7eb2e8f9f7 | 787 | void attach(T *obj, R (*func)(T*)) { |
| <> | 144:ef7eb2e8f9f7 | 788 | _obj = (void*)obj; |
| <> | 144:ef7eb2e8f9f7 | 789 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 790 | _thunk = &Callback::_boundthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 791 | } |
| <> | 144:ef7eb2e8f9f7 | 792 | |
| <> | 144:ef7eb2e8f9f7 | 793 | /** Attach a member function |
| <> | 144:ef7eb2e8f9f7 | 794 | * @param obj Pointer to object to invoke member function on |
| <> | 144:ef7eb2e8f9f7 | 795 | * @param func Member function to attach |
| <> | 144:ef7eb2e8f9f7 | 796 | */ |
| <> | 144:ef7eb2e8f9f7 | 797 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 798 | void attach(T *obj, R (T::*func)()) { |
| <> | 144:ef7eb2e8f9f7 | 799 | _obj = static_cast<void*>(obj); |
| <> | 144:ef7eb2e8f9f7 | 800 | memcpy(&_func, &func, sizeof func); |
| <> | 144:ef7eb2e8f9f7 | 801 | _thunk = &Callback::_methodthunk<T>; |
| <> | 144:ef7eb2e8f9f7 | 802 | } |
| <> | 144:ef7eb2e8f9f7 | 803 | |
| <> | 144:ef7eb2e8f9f7 | 804 | /** Attach a Callback |
| <> | 144:ef7eb2e8f9f7 | 805 | * @param func The Callback to attach |
| <> | 144:ef7eb2e8f9f7 | 806 | */ |
| <> | 144:ef7eb2e8f9f7 | 807 | void attach(const Callback<R()> &func) { |
| <> | 144:ef7eb2e8f9f7 | 808 | _obj = func._obj; |
| <> | 144:ef7eb2e8f9f7 | 809 | memcpy(&_func, &func._func, sizeof _func); |
| <> | 144:ef7eb2e8f9f7 | 810 | _thunk = func._thunk; |
| <> | 144:ef7eb2e8f9f7 | 811 | } |
| <> | 144:ef7eb2e8f9f7 | 812 | |
| <> | 144:ef7eb2e8f9f7 | 813 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 814 | */ |
| <> | 144:ef7eb2e8f9f7 | 815 | R call() { |
| <> | 144:ef7eb2e8f9f7 | 816 | if (!_thunk) { |
| <> | 144:ef7eb2e8f9f7 | 817 | return (R)0; |
| <> | 144:ef7eb2e8f9f7 | 818 | } |
| <> | 144:ef7eb2e8f9f7 | 819 | return _thunk(_obj, &_func); |
| <> | 144:ef7eb2e8f9f7 | 820 | } |
| <> | 144:ef7eb2e8f9f7 | 821 | |
| <> | 144:ef7eb2e8f9f7 | 822 | /** Call the attached function |
| <> | 144:ef7eb2e8f9f7 | 823 | */ |
| <> | 144:ef7eb2e8f9f7 | 824 | R operator()() { |
| <> | 144:ef7eb2e8f9f7 | 825 | return call(); |
| <> | 144:ef7eb2e8f9f7 | 826 | } |
| <> | 144:ef7eb2e8f9f7 | 827 | |
| <> | 144:ef7eb2e8f9f7 | 828 | /** Test if function has been attached |
| <> | 144:ef7eb2e8f9f7 | 829 | */ |
| <> | 144:ef7eb2e8f9f7 | 830 | operator bool() const { |
| <> | 144:ef7eb2e8f9f7 | 831 | return _thunk; |
| <> | 144:ef7eb2e8f9f7 | 832 | } |
| <> | 144:ef7eb2e8f9f7 | 833 | |
| <> | 144:ef7eb2e8f9f7 | 834 | /** Static thunk for passing as C-style function |
| <> | 144:ef7eb2e8f9f7 | 835 | * @param func Callback to call passed as void pointer |
| <> | 144:ef7eb2e8f9f7 | 836 | */ |
| <> | 144:ef7eb2e8f9f7 | 837 | static R thunk(void *func) { |
| <> | 144:ef7eb2e8f9f7 | 838 | return static_cast<Callback<R()>*>(func) |
| <> | 144:ef7eb2e8f9f7 | 839 | ->call(); |
| <> | 144:ef7eb2e8f9f7 | 840 | } |
| <> | 144:ef7eb2e8f9f7 | 841 | |
| <> | 144:ef7eb2e8f9f7 | 842 | private: |
| <> | 144:ef7eb2e8f9f7 | 843 | // Internal thunks for various function types |
| <> | 144:ef7eb2e8f9f7 | 844 | static R _staticthunk(void*, void *func) { |
| <> | 144:ef7eb2e8f9f7 | 845 | return (*reinterpret_cast<R (**)()>(func)) |
| <> | 144:ef7eb2e8f9f7 | 846 | (); |
| <> | 144:ef7eb2e8f9f7 | 847 | } |
| <> | 144:ef7eb2e8f9f7 | 848 | |
| <> | 144:ef7eb2e8f9f7 | 849 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 850 | static R _boundthunk(void *obj, void *func) { |
| <> | 144:ef7eb2e8f9f7 | 851 | return (*reinterpret_cast<R (**)(T*)>(func)) |
| <> | 144:ef7eb2e8f9f7 | 852 | (static_cast<T*>(obj)); |
| <> | 144:ef7eb2e8f9f7 | 853 | } |
| <> | 144:ef7eb2e8f9f7 | 854 | |
| <> | 144:ef7eb2e8f9f7 | 855 | template<typename T> |
| <> | 144:ef7eb2e8f9f7 | 856 | static R _methodthunk(void *obj, void *func) { |
| <> | 144:ef7eb2e8f9f7 | 857 | return (static_cast<T*>(obj)->* |
| <> | 144:ef7eb2e8f9f7 | 858 | (*reinterpret_cast<R (T::**)()>(func))) |
| <> | 144:ef7eb2e8f9f7 | 859 | (); |
| <> | 144:ef7eb2e8f9f7 | 860 | } |
| <> | 144:ef7eb2e8f9f7 | 861 | |
| <> | 144:ef7eb2e8f9f7 | 862 | // Stored as pointer to function and pointer to optional object |
| <> | 144:ef7eb2e8f9f7 | 863 | // Function pointer is stored as union of possible function types |
| <> | 144:ef7eb2e8f9f7 | 864 | // to garuntee proper size and alignment |
| <> | 144:ef7eb2e8f9f7 | 865 | struct _class; |
| <> | 144:ef7eb2e8f9f7 | 866 | union { |
| <> | 144:ef7eb2e8f9f7 | 867 | void (*_staticfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 868 | void (*_boundfunc)(_class *); |
| <> | 144:ef7eb2e8f9f7 | 869 | void (_class::*_methodfunc)(); |
| <> | 144:ef7eb2e8f9f7 | 870 | } _func; |
| <> | 144:ef7eb2e8f9f7 | 871 | |
| <> | 144:ef7eb2e8f9f7 | 872 | void *_obj; |
| <> | 144:ef7eb2e8f9f7 | 873 | |
| <> | 144:ef7eb2e8f9f7 | 874 | // Thunk registered on attach to dispatch calls |
| <> | 144:ef7eb2e8f9f7 | 875 | R (*_thunk)(void*, void*); |
| <> | 144:ef7eb2e8f9f7 | 876 | }; |
| <> | 144:ef7eb2e8f9f7 | 877 | |
| <> | 144:ef7eb2e8f9f7 | 878 | typedef Callback<void(int)> event_callback_t; |
| <> | 144:ef7eb2e8f9f7 | 879 | |
| <> | 144:ef7eb2e8f9f7 | 880 | |
| <> | 144:ef7eb2e8f9f7 | 881 | } // namespace mbed |
| <> | 144:ef7eb2e8f9f7 | 882 | |
| <> | 144:ef7eb2e8f9f7 | 883 | #endif |