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