ovr_sdk

view 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 source
1 /************************************************************************************
3 Filename : OVR_Delegates.h
4 Content : C++ Delegates
5 Created : June 15, 2014
6 Authors : Chris Taylor
8 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
10 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
12 which is provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
15 You may obtain a copy of the License at
17 http://www.oculusvr.com/licenses/LICENSE-3.2
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
25 ************************************************************************************/
27 /*
28 Based on The Impossibly Fast C++ Delegates by Sergey Ryazanov from
29 http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx (2005)
30 */
32 /*
33 Usage:
35 Declare a delegate with a void (int) signature, also known as a
36 function that returns void and has one parameter that is an int:
37 typedef Delegate1<void, int> MyDelegate;
38 MyDelegate d;
40 Point the delegate to a member function:
41 d.SetMember<A, &A::TestFunctionA>(&a);
42 d = MyDelegate::FromMember<A, &A::TestFunctionA>(&a);
44 Point the delegate to a const member function:
45 d.SetConstMember<C, &C::TestFunctionA>(&c);
46 d = MyDelegate::FromConstMember<C, &C::TestFunctionA>(&c);
48 Point the delegate to a free function:
49 d.SetFree<&FreeFunctionX>();
50 d = MyDelegate::FromFree<&FreeFunctionX>();
52 Invoke the function via the delegate (works for all 3 cases):
53 d(1000);
55 By default the delegates are uninitialized.
56 To clear an array of delegates quickly just zero the memory.
58 This implementation is nicer than FastDelegates in my opinion
59 because it is simple and easy to read. It is a little slower
60 for virtual functions, but the size of the delegate is small,
61 and it will only get better as compilers improve.
62 */
64 #ifndef OVR_Delegates_h
65 #define OVR_Delegates_h
67 #include "OVR_Types.h"
69 namespace OVR {
72 template <class ret_type>
73 class Delegate0
74 {
75 typedef ret_type (*StubPointer)(void *);
76 typedef Delegate0<ret_type> this_type;
78 void *_object;
79 StubPointer _stub;
81 OVR_FORCE_INLINE Delegate0(void *object, StubPointer stub)
82 {
83 _object = object;
84 _stub = stub;
85 }
87 // Stubs
89 template <ret_type (*F)()>
90 static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/)
91 {
92 return (F)();
93 }
95 template <class T, ret_type (T::*F)()>
96 static OVR_FORCE_INLINE ret_type MemberStub(void *object)
97 {
98 T *p = static_cast<T*>(object);
99 return (p->*F)();
100 }
102 template <class T, ret_type (T::*F)() const>
103 static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object)
104 {
105 T *p = static_cast<T*>(object);
106 return (p->*F)();
107 }
109 public:
110 OVR_FORCE_INLINE Delegate0() : _object(0), _stub(0){}
112 // Function invocation
114 OVR_FORCE_INLINE ret_type operator()() const
115 {
116 return (*_stub)(_object);
117 }
119 // Use stub pointer as a validity flag and equality checker
121 OVR_FORCE_INLINE bool operator==(const this_type &rhs) const
122 {
123 return _object == rhs._object && _stub == rhs._stub;
124 }
126 OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const
127 {
128 return _object != rhs._object || _stub != rhs._stub;
129 }
131 OVR_FORCE_INLINE bool IsValid() const
132 {
133 return _stub != 0;
134 }
136 OVR_FORCE_INLINE bool operator!() const
137 {
138 return _stub == 0;
139 }
141 OVR_FORCE_INLINE void Invalidate()
142 {
143 _stub = 0;
144 }
146 // Delegate creation from a function
148 template <ret_type (*F)()>
149 static OVR_FORCE_INLINE this_type FromFree()
150 {
151 return this_type(0, &FreeStub<F>);
152 }
154 template <class T, ret_type (T::*F)()>
155 static OVR_FORCE_INLINE this_type FromMember(T *object)
156 {
157 return this_type(object, &MemberStub<T, F>);
158 }
160 template <class T, ret_type (T::*F)() const>
161 static OVR_FORCE_INLINE this_type FromConstMember(T const *object)
162 {
163 return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>);
164 }
166 // In-place assignment to a different function
168 template <ret_type (*F)()>
169 OVR_FORCE_INLINE void SetFree()
170 {
171 *this = FromFree<F>();
172 }
174 template <class T, ret_type (T::*F)()>
175 OVR_FORCE_INLINE void SetMember(T *object)
176 {
177 *this = FromMember<T, F>(object);
178 }
180 template <class T, ret_type (T::*F)() const>
181 OVR_FORCE_INLINE void SetConstMember(T const *object)
182 {
183 *this = FromConstMember<T, F>(object);
184 }
185 };
188 template <class ret_type, class arg1_type>
189 class Delegate1
190 {
191 typedef ret_type (*StubPointer)(void *, arg1_type);
192 typedef Delegate1<ret_type, arg1_type> this_type;
194 void *_object;
195 StubPointer _stub;
197 OVR_FORCE_INLINE Delegate1(void *object, StubPointer stub)
198 {
199 _object = object;
200 _stub = stub;
201 }
203 // Stubs
205 template <ret_type (*F)(arg1_type)>
206 static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1)
207 {
208 return (F)(a1);
209 }
211 template <class T, ret_type (T::*F)(arg1_type)>
212 static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1)
213 {
214 T *p = static_cast<T*>(object);
215 return (p->*F)(a1);
216 }
218 template <class T, ret_type (T::*F)(arg1_type) const>
219 static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1)
220 {
221 T *p = static_cast<T*>(object);
222 return (p->*F)(a1);
223 }
225 public:
226 OVR_FORCE_INLINE Delegate1() : _object(0), _stub(0){}
228 // Function invocation
230 OVR_FORCE_INLINE ret_type operator()(arg1_type a1) const
231 {
232 return (*_stub)(_object, a1);
233 }
235 // Use stub pointer as a validity flag and equality checker
237 OVR_FORCE_INLINE bool operator==(const this_type &rhs) const
238 {
239 return _object == rhs._object && _stub == rhs._stub;
240 }
242 OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const
243 {
244 return _object != rhs._object || _stub != rhs._stub;
245 }
247 OVR_FORCE_INLINE bool IsValid() const
248 {
249 return _stub != 0;
250 }
252 OVR_FORCE_INLINE bool operator!() const
253 {
254 return _stub == 0;
255 }
257 OVR_FORCE_INLINE void Invalidate()
258 {
259 _stub = 0;
260 }
262 // Delegate creation from a function
264 template <ret_type (*F)(arg1_type)>
265 static OVR_FORCE_INLINE this_type FromFree()
266 {
267 return this_type(0, &FreeStub<F>);
268 }
270 template <class T, ret_type (T::*F)(arg1_type)>
271 static OVR_FORCE_INLINE this_type FromMember(T *object)
272 {
273 return this_type(object, &MemberStub<T, F>);
274 }
276 template <class T, ret_type (T::*F)(arg1_type) const>
277 static OVR_FORCE_INLINE this_type FromConstMember(T const *object)
278 {
279 return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>);
280 }
282 // In-place assignment to a different function
284 template <ret_type (*F)(arg1_type)>
285 OVR_FORCE_INLINE void SetFree()
286 {
287 *this = FromFree<F>();
288 }
290 template <class T, ret_type (T::*F)(arg1_type)>
291 OVR_FORCE_INLINE void SetMember(T *object)
292 {
293 *this = FromMember<T, F>(object);
294 }
296 template <class T, ret_type (T::*F)(arg1_type) const>
297 OVR_FORCE_INLINE void SetConstMember(T const *object)
298 {
299 *this = FromConstMember<T, F>(object);
300 }
301 };
304 template <class ret_type, class arg1_type, class arg2_type>
305 class Delegate2
306 {
307 typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type);
308 typedef Delegate2<ret_type, arg1_type, arg2_type> this_type;
310 void *_object;
311 StubPointer _stub;
313 OVR_FORCE_INLINE Delegate2(void *object, StubPointer stub)
314 {
315 _object = object;
316 _stub = stub;
317 }
319 // Stubs
321 template <ret_type (*F)(arg1_type, arg2_type)>
322 static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2)
323 {
324 return (F)(a1, a2);
325 }
327 template <class T, ret_type (T::*F)(arg1_type, arg2_type)>
328 static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2)
329 {
330 T *p = static_cast<T*>(object);
331 return (p->*F)(a1, a2);
332 }
334 template <class T, ret_type (T::*F)(arg1_type, arg2_type) const>
335 static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2)
336 {
337 T *p = static_cast<T*>(object);
338 return (p->*F)(a1, a2);
339 }
341 public:
342 OVR_FORCE_INLINE Delegate2() : _object(0), _stub(0){}
344 // Function invocation
346 OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2) const
347 {
348 return (*_stub)(_object, a1, a2);
349 }
351 // Use stub pointer as a validity flag and equality checker
353 OVR_FORCE_INLINE bool operator==(const this_type &rhs) const
354 {
355 return _object == rhs._object && _stub == rhs._stub;
356 }
358 OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const
359 {
360 return _object != rhs._object || _stub != rhs._stub;
361 }
363 OVR_FORCE_INLINE bool IsValid() const
364 {
365 return _stub != 0;
366 }
368 OVR_FORCE_INLINE bool operator!() const
369 {
370 return _stub == 0;
371 }
373 OVR_FORCE_INLINE void Invalidate()
374 {
375 _stub = 0;
376 }
378 // Delegate creation from a function
380 template <ret_type (*F)(arg1_type, arg2_type)>
381 static OVR_FORCE_INLINE this_type FromFree()
382 {
383 return this_type(0, &FreeStub<F>);
384 }
386 template <class T, ret_type (T::*F)(arg1_type, arg2_type)>
387 static OVR_FORCE_INLINE this_type FromMember(T *object)
388 {
389 return this_type(object, &MemberStub<T, F>);
390 }
392 template <class T, ret_type (T::*F)(arg1_type, arg2_type) const>
393 static OVR_FORCE_INLINE this_type FromConstMember(T const *object)
394 {
395 return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>);
396 }
398 // In-place assignment to a different function
400 template <ret_type (*F)(arg1_type, arg2_type)>
401 OVR_FORCE_INLINE void SetFree()
402 {
403 *this = FromFree<F>();
404 }
406 template <class T, ret_type (T::*F)(arg1_type, arg2_type)>
407 OVR_FORCE_INLINE void SetMember(T *object)
408 {
409 *this = FromMember<T, F>(object);
410 }
412 template <class T, ret_type (T::*F)(arg1_type, arg2_type) const>
413 OVR_FORCE_INLINE void SetConstMember(T const *object)
414 {
415 *this = FromConstMember<T, F>(object);
416 }
417 };
420 template <class ret_type, class arg1_type, class arg2_type, class arg3_type>
421 class Delegate3
422 {
423 typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type, arg3_type);
424 typedef Delegate3<ret_type, arg1_type, arg2_type, arg3_type> this_type;
426 void *_object;
427 StubPointer _stub;
429 OVR_FORCE_INLINE Delegate3(void *object, StubPointer stub)
430 {
431 _object = object;
432 _stub = stub;
433 }
435 // Stubs
437 template <ret_type (*F)(arg1_type, arg2_type, arg3_type)>
438 static OVR_FORCE_INLINE ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2, arg3_type a3)
439 {
440 return (F)(a1, a2, a3);
441 }
443 template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)>
444 static OVR_FORCE_INLINE ret_type MemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3)
445 {
446 T *p = static_cast<T*>(object);
447 return (p->*F)(a1, a2, a3);
448 }
450 template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const>
451 static OVR_FORCE_INLINE ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3)
452 {
453 T *p = static_cast<T*>(object);
454 return (p->*F)(a1, a2, a3);
455 }
457 public:
458 OVR_FORCE_INLINE Delegate3() : _object(0), _stub(0){}
460 // Function invocation
462 OVR_FORCE_INLINE ret_type operator()(arg1_type a1, arg2_type a2, arg3_type a3) const
463 {
464 return (*_stub)(_object, a1, a2, a3);
465 }
467 // Use stub pointer as a validity flag and equality checker
469 OVR_FORCE_INLINE bool operator==(const this_type &rhs) const
470 {
471 return _object == rhs._object && _stub == rhs._stub;
472 }
474 OVR_FORCE_INLINE bool operator!=(const this_type &rhs) const
475 {
476 return _object != rhs._object || _stub != rhs._stub;
477 }
479 OVR_FORCE_INLINE bool IsValid() const
480 {
481 return _stub != 0;
482 }
484 OVR_FORCE_INLINE bool operator!() const
485 {
486 return _stub == 0;
487 }
489 OVR_FORCE_INLINE void Invalidate()
490 {
491 _stub = 0;
492 }
494 // Delegate creation from a function
496 template <ret_type (*F)(arg1_type, arg2_type, arg3_type)>
497 static OVR_FORCE_INLINE this_type FromFree()
498 {
499 return this_type(0, &FreeStub<F>);
500 }
502 template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)>
503 static OVR_FORCE_INLINE this_type FromMember(T *object)
504 {
505 return this_type(object, &MemberStub<T, F>);
506 }
508 template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const>
509 static OVR_FORCE_INLINE this_type FromConstMember(T const *object)
510 {
511 return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>);
512 }
514 // In-place assignment to a different function
516 template <ret_type (*F)(arg1_type, arg2_type, arg3_type)>
517 OVR_FORCE_INLINE void SetFree()
518 {
519 *this = FromFree<F>();
520 }
522 template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)>
523 OVR_FORCE_INLINE void SetMember(T *object)
524 {
525 *this = FromMember<T, F>(object);
526 }
528 template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const>
529 OVR_FORCE_INLINE void SetConstMember(T const *object)
530 {
531 *this = FromConstMember<T, F>(object);
532 }
533 };
535 // Add more here if needed, but keep in mind that a short, simple interface
536 // is rewarded by making the delegates faster...
539 } // namespace OVR
541 #endif // OVR_Delegates_h