trunk/src/lib/util/delegate.h
r250337 | r250338 | |
90 | 90 | // types of delegates supported |
91 | 91 | #define DELEGATE_TYPE_COMPATIBLE 0 |
92 | 92 | #define DELEGATE_TYPE_INTERNAL 1 |
| 93 | #define DELEGATE_TYPE_MSVC 2 |
93 | 94 | |
94 | 95 | // select which one we will be using |
95 | 96 | #if defined(__GNUC__) |
r250337 | r250338 | |
110 | 111 | #define MEMBER_ABI |
111 | 112 | #define HAS_DIFFERENT_ABI 0 |
112 | 113 | #endif |
| 114 | #elif defined(_MSC_VER) && defined (PTR64) |
| 115 | #define MEMBER_ABI |
| 116 | #define HAS_DIFFERENT_ABI 0 |
| 117 | #define USE_DELEGATE_TYPE DELEGATE_TYPE_MSVC |
113 | 118 | #else |
114 | 119 | #define USE_DELEGATE_TYPE DELEGATE_TYPE_COMPATIBLE |
115 | 120 | #endif |
r250337 | r250338 | |
541 | 546 | int m_this_delta; // delta to apply to the 'this' pointer |
542 | 547 | }; |
543 | 548 | |
| 549 | #elif (USE_DELEGATE_TYPE == DELEGATE_TYPE_MSVC) |
| 550 | |
| 551 | // ======================> delegate_mfp |
| 552 | const int SINGLE_MEMFUNCPTR_SIZE = sizeof(void (delegate_generic_class::*)()); |
| 553 | |
| 554 | // struct describing the contents of a member function pointer |
| 555 | class delegate_mfp |
| 556 | { |
| 557 | public: |
| 558 | // default constructor |
| 559 | delegate_mfp() |
| 560 | : m_function(0) { } |
| 561 | |
| 562 | // copy constructor |
| 563 | delegate_mfp(const delegate_mfp &src) |
| 564 | : m_function(src.m_function) { } |
| 565 | |
| 566 | // construct from any member function pointer |
| 567 | template<typename _MemberFunctionType, class _MemberFunctionClass, typename _ReturnType, typename _StaticFunctionType> |
| 568 | delegate_mfp(_MemberFunctionType mfp, _MemberFunctionClass *, _ReturnType *, _StaticFunctionType) |
| 569 | { |
| 570 | //assert(sizeof(mfp) == 12 || sizeof(mfp) == 16); |
| 571 | m_size = sizeof(mfp); |
| 572 | *reinterpret_cast<_MemberFunctionType *>(this) = mfp; |
| 573 | } |
| 574 | |
| 575 | // comparison helpers |
| 576 | bool operator==(const delegate_mfp &rhs) const { return (m_function == rhs.m_function); } |
| 577 | bool isnull() const { return (m_function == 0); } |
| 578 | |
| 579 | // getters |
| 580 | delegate_generic_class *real_object(delegate_generic_class *original) const { return original; } |
| 581 | |
| 582 | // binding helper |
| 583 | template<typename _FunctionType> |
| 584 | void update_after_bind(_FunctionType &funcptr, delegate_generic_class *&object) |
| 585 | { |
| 586 | funcptr = reinterpret_cast<_FunctionType>(m_function); |
| 587 | if (m_size == SINGLE_MEMFUNCPTR_SIZE + sizeof(int)) |
| 588 | object = reinterpret_cast<delegate_generic_class *>(reinterpret_cast<UINT8 *>(object) + m_this_delta); |
| 589 | } |
| 590 | |
| 591 | private: |
| 592 | // extract the generic function and adjust the object pointer |
| 593 | delegate_generic_function convert_to_generic(delegate_generic_class *&object) const; |
| 594 | |
| 595 | // actual state |
| 596 | FPTR m_function; // first item can be one of two things: |
| 597 | // if even, it's a pointer to the function |
| 598 | // if odd, it's the byte offset into the vtable |
| 599 | int m_this_delta; // delta to apply to the 'this' pointer |
| 600 | |
| 601 | int m_dummy1; |
| 602 | int m_dummy2; |
| 603 | |
| 604 | int m_size; |
| 605 | }; |
| 606 | |
544 | 607 | #endif |
545 | 608 | |
546 | 609 | |