| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- /************************************************************************************
- Filename : OVR_Delegates.h
- Content : C++ Delegates
- Created : June 15, 2014
- Authors : Chris Taylor
- Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
- Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
- you may not use the Oculus VR Rift SDK except in compliance with the License,
- which is provided at the time of installation or download, or which
- otherwise accompanies this software in either electronic or hard copy form.
- You may obtain a copy of the License at
- http://www.oculusvr.com/licenses/LICENSE-3.2
- Unless required by applicable law or agreed to in writing, the Oculus VR SDK
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- ************************************************************************************/
- /*
- Based on The Impossibly Fast C++ Delegates by Sergey Ryazanov from
- http://www.codeproject.com/KB/cpp/ImpossiblyFastCppDelegate.aspx (2005)
- */
- /*
- Usage:
- Declare a delegate with a void (int) signature, also known as a
- function that returns void and has one parameter that is an int:
- typedef Delegate1<void, int> MyDelegate;
- MyDelegate d;
- Point the delegate to a member function:
- d.SetMember<A, &A::TestFunctionA>(&a);
- d = MyDelegate::FromMember<A, &A::TestFunctionA>(&a);
- Point the delegate to a const member function:
- d.SetConstMember<C, &C::TestFunctionA>(&c);
- d = MyDelegate::FromConstMember<C, &C::TestFunctionA>(&c);
- Point the delegate to a free function:
- d.SetFree<&FreeFunctionX>();
- d = MyDelegate::FromFree<&FreeFunctionX>();
- Invoke the function via the delegate (works for all 3 cases):
- d(1000);
- By default the delegates are uninitialized.
- To clear an array of delegates quickly just zero the memory.
- This implementation is nicer than FastDelegates in my opinion
- because it is simple and easy to read. It is a little slower
- for virtual functions, but the size of the delegate is small,
- and it will only get better as compilers improve.
- */
- #ifndef OVR_Delegates_h
- #define OVR_Delegates_h
- #include "OVR_Types.h"
- namespace OVR {
- template <class ret_type>
- class Delegate0
- {
- typedef ret_type (*StubPointer)(void *);
- typedef Delegate0<ret_type> this_type;
- void *_object;
- StubPointer _stub;
- inline Delegate0(void *object, StubPointer stub)
- {
- _object = object;
- _stub = stub;
- }
- // Stubs
- template <ret_type (*F)()>
- static inline ret_type FreeStub(void * /*object*/)
- {
- return (F)();
- }
- template <class T, ret_type (T::*F)()>
- static inline ret_type MemberStub(void *object)
- {
- T *p = static_cast<T*>(object);
- return (p->*F)();
- }
- template <class T, ret_type (T::*F)() const>
- static inline ret_type ConstMemberStub(void *object)
- {
- T *p = static_cast<T*>(object);
- return (p->*F)();
- }
- public:
- inline Delegate0() : _object(0), _stub(0){}
- // Function invocation
- inline ret_type operator()() const
- {
- return (*_stub)(_object);
- }
- // Use stub pointer as a validity flag and equality checker
- inline bool operator==(const this_type &rhs) const
- {
- return _object == rhs._object && _stub == rhs._stub;
- }
- inline bool operator!=(const this_type &rhs) const
- {
- return _object != rhs._object || _stub != rhs._stub;
- }
- inline bool IsValid() const
- {
- return _stub != 0;
- }
- inline bool operator!() const
- {
- return _stub == 0;
- }
- inline void Invalidate()
- {
- _stub = 0;
- }
- // Delegate creation from a function
- template <ret_type (*F)()>
- static inline this_type FromFree()
- {
- return this_type(0, &FreeStub<F>);
- }
- template <class T, ret_type (T::*F)()>
- static inline this_type FromMember(T *object)
- {
- return this_type(object, &MemberStub<T, F>);
- }
- template <class T, ret_type (T::*F)() const>
- static inline this_type FromConstMember(T const *object)
- {
- return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>);
- }
- // In-place assignment to a different function
- template <ret_type (*F)()>
- inline void SetFree()
- {
- *this = FromFree<F>();
- }
- template <class T, ret_type (T::*F)()>
- inline void SetMember(T *object)
- {
- *this = FromMember<T, F>(object);
- }
- template <class T, ret_type (T::*F)() const>
- inline void SetConstMember(T const *object)
- {
- *this = FromConstMember<T, F>(object);
- }
- };
- template <class ret_type, class arg1_type>
- class Delegate1
- {
- typedef ret_type (*StubPointer)(void *, arg1_type);
- typedef Delegate1<ret_type, arg1_type> this_type;
- void *_object;
- StubPointer _stub;
- inline Delegate1(void *object, StubPointer stub)
- {
- _object = object;
- _stub = stub;
- }
- // Stubs
- template <ret_type (*F)(arg1_type)>
- static inline ret_type FreeStub(void * /*object*/, arg1_type a1)
- {
- return (F)(a1);
- }
- template <class T, ret_type (T::*F)(arg1_type)>
- static inline ret_type MemberStub(void *object, arg1_type a1)
- {
- T *p = static_cast<T*>(object);
- return (p->*F)(a1);
- }
- template <class T, ret_type (T::*F)(arg1_type) const>
- static inline ret_type ConstMemberStub(void *object, arg1_type a1)
- {
- T *p = static_cast<T*>(object);
- return (p->*F)(a1);
- }
- public:
- inline Delegate1() : _object(0), _stub(0){}
- // Function invocation
- inline ret_type operator()(arg1_type a1) const
- {
- return (*_stub)(_object, a1);
- }
- // Use stub pointer as a validity flag and equality checker
- inline bool operator==(const this_type &rhs) const
- {
- return _object == rhs._object && _stub == rhs._stub;
- }
- inline bool operator!=(const this_type &rhs) const
- {
- return _object != rhs._object || _stub != rhs._stub;
- }
- inline bool IsValid() const
- {
- return _stub != 0;
- }
- inline bool operator!() const
- {
- return _stub == 0;
- }
- inline void Invalidate()
- {
- _stub = 0;
- }
- // Delegate creation from a function
- template <ret_type (*F)(arg1_type)>
- static inline this_type FromFree()
- {
- return this_type(0, &FreeStub<F>);
- }
- template <class T, ret_type (T::*F)(arg1_type)>
- static inline this_type FromMember(T *object)
- {
- return this_type(object, &MemberStub<T, F>);
- }
- template <class T, ret_type (T::*F)(arg1_type) const>
- static inline this_type FromConstMember(T const *object)
- {
- return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>);
- }
- // In-place assignment to a different function
- template <ret_type (*F)(arg1_type)>
- inline void SetFree()
- {
- *this = FromFree<F>();
- }
- template <class T, ret_type (T::*F)(arg1_type)>
- inline void SetMember(T *object)
- {
- *this = FromMember<T, F>(object);
- }
- template <class T, ret_type (T::*F)(arg1_type) const>
- inline void SetConstMember(T const *object)
- {
- *this = FromConstMember<T, F>(object);
- }
- };
- template <class ret_type, class arg1_type, class arg2_type>
- class Delegate2
- {
- typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type);
- typedef Delegate2<ret_type, arg1_type, arg2_type> this_type;
- void *_object;
- StubPointer _stub;
- inline Delegate2(void *object, StubPointer stub)
- {
- _object = object;
- _stub = stub;
- }
- // Stubs
- template <ret_type (*F)(arg1_type, arg2_type)>
- static inline ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2)
- {
- return (F)(a1, a2);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type)>
- static inline ret_type MemberStub(void *object, arg1_type a1, arg2_type a2)
- {
- T *p = static_cast<T*>(object);
- return (p->*F)(a1, a2);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type) const>
- static inline ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2)
- {
- T *p = static_cast<T*>(object);
- return (p->*F)(a1, a2);
- }
- public:
- inline Delegate2() : _object(0), _stub(0){}
- // Function invocation
- inline ret_type operator()(arg1_type a1, arg2_type a2) const
- {
- return (*_stub)(_object, a1, a2);
- }
- // Use stub pointer as a validity flag and equality checker
- inline bool operator==(const this_type &rhs) const
- {
- return _object == rhs._object && _stub == rhs._stub;
- }
- inline bool operator!=(const this_type &rhs) const
- {
- return _object != rhs._object || _stub != rhs._stub;
- }
- inline bool IsValid() const
- {
- return _stub != 0;
- }
- inline bool operator!() const
- {
- return _stub == 0;
- }
- inline void Invalidate()
- {
- _stub = 0;
- }
- // Delegate creation from a function
- template <ret_type (*F)(arg1_type, arg2_type)>
- static inline this_type FromFree()
- {
- return this_type(0, &FreeStub<F>);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type)>
- static inline this_type FromMember(T *object)
- {
- return this_type(object, &MemberStub<T, F>);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type) const>
- static inline this_type FromConstMember(T const *object)
- {
- return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>);
- }
- // In-place assignment to a different function
- template <ret_type (*F)(arg1_type, arg2_type)>
- inline void SetFree()
- {
- *this = FromFree<F>();
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type)>
- inline void SetMember(T *object)
- {
- *this = FromMember<T, F>(object);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type) const>
- inline void SetConstMember(T const *object)
- {
- *this = FromConstMember<T, F>(object);
- }
- };
- template <class ret_type, class arg1_type, class arg2_type, class arg3_type>
- class Delegate3
- {
- typedef ret_type (*StubPointer)(void *, arg1_type, arg2_type, arg3_type);
- typedef Delegate3<ret_type, arg1_type, arg2_type, arg3_type> this_type;
- void *_object;
- StubPointer _stub;
- inline Delegate3(void *object, StubPointer stub)
- {
- _object = object;
- _stub = stub;
- }
- // Stubs
- template <ret_type (*F)(arg1_type, arg2_type, arg3_type)>
- static inline ret_type FreeStub(void * /*object*/, arg1_type a1, arg2_type a2, arg3_type a3)
- {
- return (F)(a1, a2, a3);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)>
- static inline ret_type MemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3)
- {
- T *p = static_cast<T*>(object);
- return (p->*F)(a1, a2, a3);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const>
- static inline ret_type ConstMemberStub(void *object, arg1_type a1, arg2_type a2, arg3_type a3)
- {
- T *p = static_cast<T*>(object);
- return (p->*F)(a1, a2, a3);
- }
- public:
- inline Delegate3() : _object(0), _stub(0){}
- // Function invocation
- inline ret_type operator()(arg1_type a1, arg2_type a2, arg3_type a3) const
- {
- return (*_stub)(_object, a1, a2, a3);
- }
- // Use stub pointer as a validity flag and equality checker
- inline bool operator==(const this_type &rhs) const
- {
- return _object == rhs._object && _stub == rhs._stub;
- }
- inline bool operator!=(const this_type &rhs) const
- {
- return _object != rhs._object || _stub != rhs._stub;
- }
- inline bool IsValid() const
- {
- return _stub != 0;
- }
- inline bool operator!() const
- {
- return _stub == 0;
- }
- inline void Invalidate()
- {
- _stub = 0;
- }
- // Delegate creation from a function
- template <ret_type (*F)(arg1_type, arg2_type, arg3_type)>
- static inline this_type FromFree()
- {
- return this_type(0, &FreeStub<F>);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)>
- static inline this_type FromMember(T *object)
- {
- return this_type(object, &MemberStub<T, F>);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const>
- static inline this_type FromConstMember(T const *object)
- {
- return this_type(const_cast<T*>( object ), &ConstMemberStub<T, F>);
- }
- // In-place assignment to a different function
- template <ret_type (*F)(arg1_type, arg2_type, arg3_type)>
- inline void SetFree()
- {
- *this = FromFree<F>();
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type)>
- inline void SetMember(T *object)
- {
- *this = FromMember<T, F>(object);
- }
- template <class T, ret_type (T::*F)(arg1_type, arg2_type, arg3_type) const>
- inline void SetConstMember(T const *object)
- {
- *this = FromConstMember<T, F>(object);
- }
- };
- // Add more here if needed, but keep in mind that a short, simple interface
- // is rewarded by making the delegates faster...
- } // namespace OVR
- #endif // OVR_Delegates_h
|