ovr_sdk
diff LibOVR/Src/Kernel/OVR_Delegates.h @ 0:1b39a1b46319
initial 0.4.4
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 14 Jan 2015 06:51:16 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/LibOVR/Src/Kernel/OVR_Delegates.h Wed Jan 14 06:51:16 2015 +0200 1.3 @@ -0,0 +1,541 @@ 1.4 +/************************************************************************************ 1.5 + 1.6 +Filename : OVR_Delegates.h 1.7 +Content : C++ Delegates 1.8 +Created : June 15, 2014 1.9 +Authors : Chris Taylor 1.10 + 1.11 +Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. 1.12 + 1.13 +Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); 1.14 +you may not use the Oculus VR Rift SDK except in compliance with the License, 1.15 +which is provided at the time of installation or download, or which 1.16 +otherwise accompanies this software in either electronic or hard copy form. 1.17 + 1.18 +You may obtain a copy of the License at 1.19 + 1.20 +http://www.oculusvr.com/licenses/LICENSE-3.2 1.21 + 1.22 +Unless required by applicable law or agreed to in writing, the Oculus VR SDK 1.23 +distributed under the License is distributed on an "AS IS" BASIS, 1.24 +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1.25 +See the License for the specific language governing permissions and 1.26 +limitations under the License. 1.27 + 1.28 +************************************************************************************/ 1.29 + 1.30 +/* 1.31 + Based on The Impossibly Fast C++ Delegates by Sergey Ryazanov from 1.32 + http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx (2005) 1.33 +*/ 1.34 + 1.35 +/* 1.36 + Usage: 1.37 + 1.38 + Declare a delegate with a void (int) signature, also known as a 1.39 + function that returns void and has one parameter that is an int: 1.40 + typedef Delegate1<void, int> MyDelegate; 1.41 + MyDelegate d; 1.42 + 1.43 + Point the delegate to a member function: 1.44 + d.SetMember<A, &A::TestFunctionA>(&a); 1.45 + d = MyDelegate::FromMember<A, &A::TestFunctionA>(&a); 1.46 + 1.47 + Point the delegate to a const member function: 1.48 + d.SetConstMember<C, &C::TestFunctionA>(&c); 1.49 + d = MyDelegate::FromConstMember<C, &C::TestFunctionA>(&c); 1.50 + 1.51 + Point the delegate to a free function: 1.52 + d.SetFree<&FreeFunctionX>(); 1.53 + d = MyDelegate::FromFree<&FreeFunctionX>(); 1.54 + 1.55 + Invoke the function via the delegate (works for all 3 cases): 1.56 + d(1000); 1.57 + 1.58 + By default the delegates are uninitialized. 1.59 + To clear an array of delegates quickly just zero the memory. 1.60 + 1.61 + This implementation is nicer than FastDelegates in my opinion 1.62 + because it is simple and easy to read. It is a little slower 1.63 + for virtual functions, but the size of the delegate is small, 1.64 + and it will only get better as compilers improve. 1.65 +*/ 1.66 + 1.67 +#ifndef OVR_Delegates_h 1.68 +#define OVR_Delegates_h 1.69 + 1.70 +#include "OVR_Types.h" 1.71 + 1.72 +namespace OVR { 1.73 + 1.74 + 1.75 +template <class ret_type> 1.76 +class Delegate0 1.77 +{ 1.78 + typedef ret_type (*StubPointer)(void *); 1.79 + typedef Delegate0<ret_type> this_type; 1.80 + 1.81 + void *_object; 1.82 + StubPointer _stub; 1.83 + 1.84 + OVR_FORCE_INLINE Delegate0(void *object, StubPointer stub) 1.85 + { 1.86 + _object = object; 1.87 + _stub = stub; 1.88 + } 1.89 + 1.90 + // Stubs 1.91 + 1.92 + template <ret_type (*F)()> 1.93 + static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/) 1.94 + { 1.95 + return (F)(); 1.96 + } 1.97 + 1.98 + template <class T, ret_type (T::*F)()> 1.99 + static OVR_FORCE_INLINE ret_type MemberStub(void *object) 1.100 + { 1.101 + T *p = static_cast<T*>(object); 1.102 + return (p->*F)(); 1.103 + } 1.104 + 1.105 + template <class T, ret_type (T::*F)() const> 1.106 + static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object) 1.107 + { 1.108 + T *p = static_cast<T*>(object); 1.109 + return (p->*F)(); 1.110 + } 1.111 + 1.112 +public: 1.113 + OVR_FORCE_INLINE Delegate0() : _object(0), _stub(0){} 1.114 + 1.115 + // Function invocation 1.116 + 1.117 + OVR_FORCE_INLINE ret_type operator()() const 1.118 + { 1.119 + return (*_stub)(_object); 1.120 + } 1.121 + 1.122 + // Use stub pointer as a validity flag and equality checker 1.123 + 1.124 + OVR_FORCE_INLINE bool operator==(const this_type &rhs) const 1.125 + { 1.126 + return _object == rhs._object && _stub == rhs._stub; 1.127 + } 1.128 + 1.129 + OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const 1.130 + { 1.131 + return _object != rhs._object || _stub != rhs._stub; 1.132 + } 1.133 + 1.134 + OVR_FORCE_INLINE bool IsValid() const 1.135 + { 1.136 + return _stub != 0; 1.137 + } 1.138 + 1.139 + OVR_FORCE_INLINE bool operator!() const 1.140 + { 1.141 + return _stub == 0; 1.142 + } 1.143 + 1.144 + OVR_FORCE_INLINE void Invalidate() 1.145 + { 1.146 + _stub = 0; 1.147 + } 1.148 + 1.149 + // Delegate creation from a function 1.150 + 1.151 + template <ret_type (*F)()> 1.152 + static OVR_FORCE_INLINE this_type FromFree() 1.153 + { 1.154 + return this_type(0, &FreeStub<F>); 1.155 + } 1.156 + 1.157 + template <class T, ret_type (T::*F)()> 1.158 + static OVR_FORCE_INLINE this_type FromMember(T *object) 1.159 + { 1.160 + return this_type(object, &MemberStub<T, F>); 1.161 + } 1.162 + 1.163 + template <class T, ret_type (T::*F)() const> 1.164 + static OVR_FORCE_INLINE this_type FromConstMember(T const *object) 1.165 + { 1.166 + return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>); 1.167 + } 1.168 + 1.169 + // In-place assignment to a different function 1.170 + 1.171 + template <ret_type (*F)()> 1.172 + OVR_FORCE_INLINE void SetFree() 1.173 + { 1.174 + *this = FromFree<F>(); 1.175 + } 1.176 + 1.177 + template <class T, ret_type (T::*F)()> 1.178 + OVR_FORCE_INLINE void SetMember(T *object) 1.179 + { 1.180 + *this = FromMember<T, F>(object); 1.181 + } 1.182 + 1.183 + template <class T, ret_type (T::*F)() const> 1.184 + OVR_FORCE_INLINE void SetConstMember(T const *object) 1.185 + { 1.186 + *this = FromConstMember<T, F>(object); 1.187 + } 1.188 +}; 1.189 + 1.190 + 1.191 +template <class ret_type, class arg1_type> 1.192 +class Delegate1 1.193 +{ 1.194 + typedef ret_type (*StubPointer)(void *, arg1_type); 1.195 + typedef Delegate1<ret_type, arg1_type> this_type; 1.196 + 1.197 + void *_object; 1.198 + StubPointer _stub; 1.199 + 1.200 + OVR_FORCE_INLINE Delegate1(void *object, StubPointer stub) 1.201 + { 1.202 + _object = object; 1.203 + _stub = stub; 1.204 + } 1.205 + 1.206 + // Stubs 1.207 + 1.208 + template <ret_type (*F)(arg1_type)> 1.209 + static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1) 1.210 + { 1.211 + return (F)(a1); 1.212 + } 1.213 + 1.214 + template <class T, ret_type (T::*F)(arg1_type)> 1.215 + static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1) 1.216 + { 1.217 + T *p = static_cast<T*>(object); 1.218 + return (p->*F)(a1); 1.219 + } 1.220 + 1.221 + template <class T, ret_type (T::*F)(arg1_type) const> 1.222 + static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1) 1.223 + { 1.224 + T *p = static_cast<T*>(object); 1.225 + return (p->*F)(a1); 1.226 + } 1.227 + 1.228 +public: 1.229 + OVR_FORCE_INLINE Delegate1() : _object(0), _stub(0){} 1.230 + 1.231 + // Function invocation 1.232 + 1.233 + OVR_FORCE_INLINE ret_type operator()(arg1_type a1) const 1.234 + { 1.235 + return (*_stub)(_object, a1); 1.236 + } 1.237 + 1.238 + // Use stub pointer as a validity flag and equality checker 1.239 + 1.240 + OVR_FORCE_INLINE bool operator==(const this_type &rhs) const 1.241 + { 1.242 + return _object == rhs._object && _stub == rhs._stub; 1.243 + } 1.244 + 1.245 + OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const 1.246 + { 1.247 + return _object != rhs._object || _stub != rhs._stub; 1.248 + } 1.249 + 1.250 + OVR_FORCE_INLINE bool IsValid() const 1.251 + { 1.252 + return _stub != 0; 1.253 + } 1.254 + 1.255 + OVR_FORCE_INLINE bool operator!() const 1.256 + { 1.257 + return _stub == 0; 1.258 + } 1.259 + 1.260 + OVR_FORCE_INLINE void Invalidate() 1.261 + { 1.262 + _stub = 0; 1.263 + } 1.264 + 1.265 + // Delegate creation from a function 1.266 + 1.267 + template <ret_type (*F)(arg1_type)> 1.268 + static OVR_FORCE_INLINE this_type FromFree() 1.269 + { 1.270 + return this_type(0, &FreeStub<F>); 1.271 + } 1.272 + 1.273 + template <class T, ret_type (T::*F)(arg1_type)> 1.274 + static OVR_FORCE_INLINE this_type FromMember(T *object) 1.275 + { 1.276 + return this_type(object, &MemberStub<T, F>); 1.277 + } 1.278 + 1.279 + template <class T, ret_type (T::*F)(arg1_type) const> 1.280 + static OVR_FORCE_INLINE this_type FromConstMember(T const *object) 1.281 + { 1.282 + return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>); 1.283 + } 1.284 + 1.285 + // In-place assignment to a different function 1.286 + 1.287 + template <ret_type (*F)(arg1_type)> 1.288 + OVR_FORCE_INLINE void SetFree() 1.289 + { 1.290 + *this = FromFree<F>(); 1.291 + } 1.292 + 1.293 + template <class T, ret_type (T::*F)(arg1_type)> 1.294 + OVR_FORCE_INLINE void SetMember(T *object) 1.295 + { 1.296 + *this = FromMember<T, F>(object); 1.297 + } 1.298 + 1.299 + template <class T, ret_type (T::*F)(arg1_type) const> 1.300 + OVR_FORCE_INLINE void SetConstMember(T const *object) 1.301 + { 1.302 + *this = FromConstMember<T, F>(object); 1.303 + } 1.304 +}; 1.305 + 1.306 + 1.307 +template <class ret_type, class arg1_type, class arg2_type> 1.308 +class Delegate2 1.309 +{ 1.310 + typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type); 1.311 + typedef Delegate2<ret_type, arg1_type, arg2_type> this_type; 1.312 + 1.313 + void *_object; 1.314 + StubPointer _stub; 1.315 + 1.316 + OVR_FORCE_INLINE Delegate2(void *object, StubPointer stub) 1.317 + { 1.318 + _object = object; 1.319 + _stub = stub; 1.320 + } 1.321 + 1.322 + // Stubs 1.323 + 1.324 + template <ret_type (*F)(arg1_type, arg2_type)> 1.325 + static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2) 1.326 + { 1.327 + return (F)(a1, a2); 1.328 + } 1.329 + 1.330 + template <class T, ret_type (T::*F)(arg1_type, arg2_type)> 1.331 + static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2) 1.332 + { 1.333 + T *p = static_cast<T*>(object); 1.334 + return (p->*F)(a1, a2); 1.335 + } 1.336 + 1.337 + template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> 1.338 + static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2) 1.339 + { 1.340 + T *p = static_cast<T*>(object); 1.341 + return (p->*F)(a1, a2); 1.342 + } 1.343 + 1.344 +public: 1.345 + OVR_FORCE_INLINE Delegate2() : _object(0), _stub(0){} 1.346 + 1.347 + // Function invocation 1.348 + 1.349 + OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2) const 1.350 + { 1.351 + return (*_stub)(_object, a1, a2); 1.352 + } 1.353 + 1.354 + // Use stub pointer as a validity flag and equality checker 1.355 + 1.356 + OVR_FORCE_INLINE bool operator==(const this_type &rhs) const 1.357 + { 1.358 + return _object == rhs._object && _stub == rhs._stub; 1.359 + } 1.360 + 1.361 + OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const 1.362 + { 1.363 + return _object != rhs._object || _stub != rhs._stub; 1.364 + } 1.365 + 1.366 + OVR_FORCE_INLINE bool IsValid() const 1.367 + { 1.368 + return _stub != 0; 1.369 + } 1.370 + 1.371 + OVR_FORCE_INLINE bool operator!() const 1.372 + { 1.373 + return _stub == 0; 1.374 + } 1.375 + 1.376 + OVR_FORCE_INLINE void Invalidate() 1.377 + { 1.378 + _stub = 0; 1.379 + } 1.380 + 1.381 + // Delegate creation from a function 1.382 + 1.383 + template <ret_type (*F)(arg1_type, arg2_type)> 1.384 + static OVR_FORCE_INLINE this_type FromFree() 1.385 + { 1.386 + return this_type(0, &FreeStub<F>); 1.387 + } 1.388 + 1.389 + template <class T, ret_type (T::*F)(arg1_type, arg2_type)> 1.390 + static OVR_FORCE_INLINE this_type FromMember(T *object) 1.391 + { 1.392 + return this_type(object, &MemberStub<T, F>); 1.393 + } 1.394 + 1.395 + template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> 1.396 + static OVR_FORCE_INLINE this_type FromConstMember(T const *object) 1.397 + { 1.398 + return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>); 1.399 + } 1.400 + 1.401 + // In-place assignment to a different function 1.402 + 1.403 + template <ret_type (*F)(arg1_type, arg2_type)> 1.404 + OVR_FORCE_INLINE void SetFree() 1.405 + { 1.406 + *this = FromFree<F>(); 1.407 + } 1.408 + 1.409 + template <class T, ret_type (T::*F)(arg1_type, arg2_type)> 1.410 + OVR_FORCE_INLINE void SetMember(T *object) 1.411 + { 1.412 + *this = FromMember<T, F>(object); 1.413 + } 1.414 + 1.415 + template <class T, ret_type (T::*F)(arg1_type, arg2_type) const> 1.416 + OVR_FORCE_INLINE void SetConstMember(T const *object) 1.417 + { 1.418 + *this = FromConstMember<T, F>(object); 1.419 + } 1.420 +}; 1.421 + 1.422 + 1.423 +template <class ret_type, class arg1_type, class arg2_type, class arg3_type> 1.424 +class Delegate3 1.425 +{ 1.426 + typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type, arg3_type); 1.427 + typedef Delegate3<ret_type, arg1_type, arg2_type, arg3_type> this_type; 1.428 + 1.429 + void *_object; 1.430 + StubPointer _stub; 1.431 + 1.432 + OVR_FORCE_INLINE Delegate3(void *object, StubPointer stub) 1.433 + { 1.434 + _object = object; 1.435 + _stub = stub; 1.436 + } 1.437 + 1.438 + // Stubs 1.439 + 1.440 + template <ret_type (*F)(arg1_type, arg2_type, arg3_type)> 1.441 + static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2, arg3_type a3) 1.442 + { 1.443 + return (F)(a1, a2, a3); 1.444 + } 1.445 + 1.446 + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> 1.447 + static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3) 1.448 + { 1.449 + T *p = static_cast<T*>(object); 1.450 + return (p->*F)(a1, a2, a3); 1.451 + } 1.452 + 1.453 + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> 1.454 + static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3) 1.455 + { 1.456 + T *p = static_cast<T*>(object); 1.457 + return (p->*F)(a1, a2, a3); 1.458 + } 1.459 + 1.460 +public: 1.461 + OVR_FORCE_INLINE Delegate3() : _object(0), _stub(0){} 1.462 + 1.463 + // Function invocation 1.464 + 1.465 + OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2, arg3_type a3) const 1.466 + { 1.467 + return (*_stub)(_object, a1, a2, a3); 1.468 + } 1.469 + 1.470 + // Use stub pointer as a validity flag and equality checker 1.471 + 1.472 + OVR_FORCE_INLINE bool operator==(const this_type &rhs) const 1.473 + { 1.474 + return _object == rhs._object && _stub == rhs._stub; 1.475 + } 1.476 + 1.477 + OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const 1.478 + { 1.479 + return _object != rhs._object || _stub != rhs._stub; 1.480 + } 1.481 + 1.482 + OVR_FORCE_INLINE bool IsValid() const 1.483 + { 1.484 + return _stub != 0; 1.485 + } 1.486 + 1.487 + OVR_FORCE_INLINE bool operator!() const 1.488 + { 1.489 + return _stub == 0; 1.490 + } 1.491 + 1.492 + OVR_FORCE_INLINE void Invalidate() 1.493 + { 1.494 + _stub = 0; 1.495 + } 1.496 + 1.497 + // Delegate creation from a function 1.498 + 1.499 + template <ret_type (*F)(arg1_type, arg2_type, arg3_type)> 1.500 + static OVR_FORCE_INLINE this_type FromFree() 1.501 + { 1.502 + return this_type(0, &FreeStub<F>); 1.503 + } 1.504 + 1.505 + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> 1.506 + static OVR_FORCE_INLINE this_type FromMember(T *object) 1.507 + { 1.508 + return this_type(object, &MemberStub<T, F>); 1.509 + } 1.510 + 1.511 + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> 1.512 + static OVR_FORCE_INLINE this_type FromConstMember(T const *object) 1.513 + { 1.514 + return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>); 1.515 + } 1.516 + 1.517 + // In-place assignment to a different function 1.518 + 1.519 + template <ret_type (*F)(arg1_type, arg2_type, arg3_type)> 1.520 + OVR_FORCE_INLINE void SetFree() 1.521 + { 1.522 + *this = FromFree<F>(); 1.523 + } 1.524 + 1.525 + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)> 1.526 + OVR_FORCE_INLINE void SetMember(T *object) 1.527 + { 1.528 + *this = FromMember<T, F>(object); 1.529 + } 1.530 + 1.531 + template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const> 1.532 + OVR_FORCE_INLINE void SetConstMember(T const *object) 1.533 + { 1.534 + *this = FromConstMember<T, F>(object); 1.535 + } 1.536 +}; 1.537 + 1.538 +// Add more here if needed, but keep in mind that a short, simple interface 1.539 +// is rewarded by making the delegates faster... 1.540 + 1.541 + 1.542 +} // namespace OVR 1.543 + 1.544 +#endif // OVR_Delegates_h