trunk/src/emu/delegate.h
| r18548 | r18549 | |
| 430 | 430 | return reinterpret_cast<delegate_generic_class *>(result); |
| 431 | 431 | } |
| 432 | 432 | |
| 433 | | // internal state |
| 434 | | const char * m_name; // name string |
| 435 | | delegate_generic_class * m_object; // pointer to the post-cast object |
| 436 | | late_bind_func m_latebinder; // late binding helper |
| 437 | | delegate_generic_function m_raw_function; // raw static function pointer |
| 438 | | delegate_mfp m_raw_mfp; // raw member function pointer |
| 439 | | }; |
| 440 | | |
| 441 | | |
| 442 | | |
| 443 | | //************************************************************************** |
| 444 | | // COMPATIBLE DELEGATES |
| 445 | | //************************************************************************** |
| 446 | | |
| 447 | 433 | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 448 | | |
| 449 | | // ======================> delegate_base |
| 450 | | |
| 451 | | // general delegate class template supporting up to 4 parameters |
| 452 | | template<typename _ReturnType, typename _P1Type = _noparam, typename _P2Type = _noparam, typename _P3Type = _noparam, typename _P4Type = _noparam, typename _P5Type = _noparam> |
| 453 | | class delegate_base : public delegate_common_base |
| 454 | | { |
| 455 | | public: |
| 456 | | // define our traits |
| 457 | | template<class _FunctionClass> |
| 458 | | struct traits |
| 459 | | { |
| 460 | | typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type>::member_func_type member_func_type; |
| 461 | | typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type>::static_func_type static_func_type; |
| 462 | | typedef typename delegate_traits<_FunctionClass, _ReturnType, _P1Type, _P2Type, _P3Type, _P4Type, _P5Type>::static_ref_func_type static_ref_func_type; |
| 463 | | }; |
| 464 | | typedef typename traits<delegate_generic_class>::static_func_type generic_static_func; |
| 465 | | |
| 466 | | // generic constructor |
| 467 | | delegate_base() |
| 468 | | : m_function(NULL), |
| 469 | | m_callobject(NULL) { } |
| 470 | | |
| 471 | | // copy constructor |
| 472 | | delegate_base(const delegate_base &src) |
| 473 | | : delegate_common_base(src), |
| 474 | | m_function(src.m_function), |
| 475 | | m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object) { } |
| 476 | | |
| 477 | | // copy constructor with late bind |
| 478 | | delegate_base(const delegate_base &src, delegate_late_bind &object) |
| 479 | | : delegate_common_base(src), |
| 480 | | m_function(src.m_function), |
| 481 | | m_callobject(src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object) |
| 482 | | { |
| 483 | | late_bind(object); |
| 484 | | } |
| 485 | | |
| 486 | | // construct from member function with object pointer |
| 487 | | template<class _FunctionClass> |
| 488 | | delegate_base(typename traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) |
| 489 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, funcptr), |
| 490 | | m_function(&delegate_base::method_stub<_FunctionClass>), |
| 491 | | m_callobject(reinterpret_cast<delegate_generic_class *>(this)) |
| 492 | | { |
| 493 | | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 494 | | } |
| 495 | | |
| 496 | | // construct from static function with object pointer |
| 497 | | template<class _FunctionClass> |
| 498 | | delegate_base(typename traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) |
| 499 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 500 | | m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 501 | | m_callobject(NULL) |
| 502 | | { |
| 503 | | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 504 | | } |
| 505 | | |
| 506 | | // construct from static reference function with object pointer |
| 507 | | template<class _FunctionClass> |
| 508 | | delegate_base(typename traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) |
| 509 | | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 510 | | m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 511 | | m_callobject(NULL) |
| 512 | | { |
| 513 | | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 514 | | } |
| 515 | | |
| 516 | | // copy operator |
| 517 | | delegate_base &operator=(const delegate_base &src) |
| 518 | | { |
| 519 | | if (this != &src) |
| 520 | | { |
| 521 | | delegate_common_base::copy(src); |
| 522 | | m_callobject = src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object; |
| 523 | | m_function = src.m_function; |
| 524 | | } |
| 525 | | return *this; |
| 526 | | } |
| 527 | | |
| 528 | | // call the function |
| 529 | | _ReturnType operator()() const { return (*m_function)(m_callobject); } |
| 530 | | _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_callobject, p1); } |
| 531 | | _ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_callobject, p1, p2); } |
| 532 | | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_callobject, p1, p2, p3); } |
| 533 | | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_callobject, p1, p2, p3, p4); } |
| 534 | | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5) const { return (*m_function)(m_callobject, p1, p2, p3, p4, p5); } |
| 535 | | |
| 536 | | // late binding |
| 537 | | void late_bind(delegate_late_bind &object) { bind((*m_latebinder)(object)); } |
| 538 | | |
| 539 | | protected: |
| 540 | | // bind the actual object |
| 541 | | void bind(delegate_generic_class *object) |
| 542 | | { |
| 543 | | m_object = object; |
| 544 | | if (!is_mfp()) m_callobject = m_object; |
| 545 | | } |
| 546 | | |
| 547 | | // internal helpers |
| 548 | | bool is_mfp() const { return m_callobject == reinterpret_cast<const delegate_generic_class *>(this); } |
| 549 | | |
| 550 | 434 | // helper stub that calls the member function; we need one for each parameter count |
| 551 | | template<class _FunctionClass> |
| 435 | template<class _FunctionClass, typename _ReturnType> |
| 552 | 436 | static _ReturnType method_stub(delegate_generic_class *object) |
| 553 | 437 | { |
| 554 | 438 | typedef _ReturnType (_FunctionClass::*mfptype)(); |
| 555 | | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 439 | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 556 | 440 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 557 | 441 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(); |
| 558 | 442 | } |
| 559 | 443 | |
| 560 | | template<class _FunctionClass> |
| 444 | template<class _FunctionClass, typename _ReturnType, typename _P1Type> |
| 561 | 445 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1) |
| 562 | 446 | { |
| 563 | 447 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1); |
| 564 | | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 448 | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 565 | 449 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 566 | 450 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1); |
| 567 | 451 | } |
| 568 | 452 | |
| 569 | | template<class _FunctionClass> |
| 453 | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type> |
| 570 | 454 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2) |
| 571 | 455 | { |
| 572 | 456 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2); |
| 573 | | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 457 | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 574 | 458 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 575 | 459 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2); |
| 576 | 460 | } |
| 577 | 461 | |
| 578 | | template<class _FunctionClass> |
| 462 | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type> |
| 579 | 463 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3) |
| 580 | 464 | { |
| 581 | 465 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3); |
| 582 | | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 466 | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 583 | 467 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 584 | 468 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3); |
| 585 | 469 | } |
| 586 | 470 | |
| 587 | | template<class _FunctionClass> |
| 471 | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type> |
| 588 | 472 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) |
| 589 | 473 | { |
| 590 | 474 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4); |
| 591 | | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 475 | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 592 | 476 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 593 | 477 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3, p4); |
| 594 | 478 | } |
| 595 | 479 | |
| 596 | | template<class _FunctionClass> |
| 480 | template<class _FunctionClass, typename _ReturnType, typename _P1Type, typename _P2Type, typename _P3Type, typename _P4Type, typename _P5Type> |
| 597 | 481 | static _ReturnType method_stub(delegate_generic_class *object, _P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5) |
| 598 | 482 | { |
| 599 | 483 | typedef _ReturnType (_FunctionClass::*mfptype)(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5); |
| 600 | | delegate_base *_this = reinterpret_cast<delegate_base *>(object); |
| 484 | delegate_common_base *_this = reinterpret_cast<delegate_common_base *>(object); |
| 601 | 485 | mfptype &mfp = _this->m_raw_mfp.mfp<mfptype>(); |
| 602 | 486 | return (reinterpret_cast<_FunctionClass *>(_this->m_object)->*mfp)(p1, p2, p3, p4, p5); |
| 603 | 487 | } |
| 488 | #endif |
| 604 | 489 | |
| 605 | 490 | // internal state |
| 606 | | generic_static_func m_function; // generic static function pointer |
| 607 | | delegate_generic_class * m_callobject; // pointer to the object used for calling |
| 491 | const char * m_name; // name string |
| 492 | delegate_generic_class * m_object; // pointer to the post-cast object |
| 493 | late_bind_func m_latebinder; // late binding helper |
| 494 | delegate_generic_function m_raw_function; // raw static function pointer |
| 495 | delegate_mfp m_raw_mfp; // raw member function pointer |
| 608 | 496 | }; |
| 609 | 497 | |
| 610 | | #endif |
| 611 | 498 | |
| 612 | 499 | |
| 613 | 500 | //************************************************************************** |
| 614 | | // GCC DELEGATES |
| 501 | // TEMPLATIZED DELEGATE BASE |
| 615 | 502 | //************************************************************************** |
| 616 | 503 | |
| 617 | | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_INTERNAL) |
| 618 | | |
| 619 | 504 | // ======================> delegate_base |
| 620 | 505 | |
| 506 | // general delegate class template supporting up to 4 parameters |
| 621 | 507 | template<typename _ReturnType, typename _P1Type = _noparam, typename _P2Type = _noparam, typename _P3Type = _noparam, typename _P4Type = _noparam, typename _P5Type = _noparam> |
| 622 | 508 | class delegate_base : public delegate_common_base |
| 623 | 509 | { |
| 510 | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 511 | delegate_generic_class *copy_callobject(const delegate_base &src) { return src.is_mfp() ? reinterpret_cast<delegate_generic_class *>(this) : src.m_object; } |
| 512 | #else |
| 513 | delegate_generic_class *copy_callobject(const delegate_base &src) { return src.m_callobject; } |
| 514 | #endif |
| 515 | |
| 624 | 516 | public: |
| 625 | 517 | // define our traits |
| 626 | 518 | template<class _FunctionClass> |
| r18548 | r18549 | |
| 634 | 526 | |
| 635 | 527 | // generic constructor |
| 636 | 528 | delegate_base() |
| 637 | | : m_function(NULL) { } |
| 529 | : m_function(NULL), |
| 530 | m_callobject(NULL) { } |
| 638 | 531 | |
| 639 | 532 | // copy constructor |
| 640 | 533 | delegate_base(const delegate_base &src) |
| 641 | 534 | : delegate_common_base(src), |
| 642 | | m_function(src.m_function) { } |
| 535 | m_function(src.m_function), |
| 536 | m_callobject(copy_callobject(src)) { } |
| 643 | 537 | |
| 644 | 538 | // copy constructor with late bind |
| 645 | 539 | delegate_base(const delegate_base &src, delegate_late_bind &object) |
| 646 | 540 | : delegate_common_base(src), |
| 647 | | m_function(src.m_function) |
| 541 | m_function(src.m_function), |
| 542 | m_callobject(copy_callobject(src)) |
| 648 | 543 | { |
| 649 | 544 | late_bind(object); |
| 650 | 545 | } |
| r18548 | r18549 | |
| 653 | 548 | template<class _FunctionClass> |
| 654 | 549 | delegate_base(typename traits<_FunctionClass>::member_func_type funcptr, const char *name, _FunctionClass *object) |
| 655 | 550 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, funcptr), |
| 551 | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 552 | m_function(&delegate_base::method_stub<_FunctionClass, _ReturnType>), |
| 553 | m_callobject(reinterpret_cast<delegate_generic_class *>(this)) |
| 554 | #else |
| 656 | 555 | m_function(NULL) |
| 556 | #endif |
| 657 | 557 | { |
| 658 | 558 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 659 | 559 | } |
| r18548 | r18549 | |
| 662 | 562 | template<class _FunctionClass> |
| 663 | 563 | delegate_base(typename traits<_FunctionClass>::static_func_type funcptr, const char *name, _FunctionClass *object) |
| 664 | 564 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 665 | | m_function(reinterpret_cast<generic_static_func>(funcptr)) |
| 565 | m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 566 | m_callobject(NULL) |
| 666 | 567 | { |
| 667 | 568 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 668 | 569 | } |
| r18548 | r18549 | |
| 671 | 572 | template<class _FunctionClass> |
| 672 | 573 | delegate_base(typename traits<_FunctionClass>::static_ref_func_type funcptr, const char *name, _FunctionClass *object) |
| 673 | 574 | : delegate_common_base(name, &late_bind_helper<_FunctionClass>, reinterpret_cast<delegate_generic_function>(funcptr)), |
| 674 | | m_function(reinterpret_cast<generic_static_func>(funcptr)) |
| 575 | m_function(reinterpret_cast<generic_static_func>(funcptr)), |
| 576 | m_callobject(NULL) |
| 675 | 577 | { |
| 676 | 578 | bind(reinterpret_cast<delegate_generic_class *>(object)); |
| 677 | 579 | } |
| r18548 | r18549 | |
| 682 | 584 | if (this != &src) |
| 683 | 585 | { |
| 684 | 586 | delegate_common_base::copy(src); |
| 587 | m_callobject = copy_callobject(src); |
| 685 | 588 | m_function = src.m_function; |
| 686 | 589 | } |
| 687 | 590 | return *this; |
| 688 | 591 | } |
| 689 | 592 | |
| 690 | 593 | // call the function |
| 594 | #if (USE_DELEGATE_TYPE == DELEGATE_TYPE_COMPATIBLE) |
| 595 | _ReturnType operator()() const { return (*m_function)(m_callobject); } |
| 596 | _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_callobject, p1); } |
| 597 | _ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_callobject, p1, p2); } |
| 598 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_callobject, p1, p2, p3); } |
| 599 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_callobject, p1, p2, p3, p4); } |
| 600 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5) const { return (*m_function)(m_callobject, p1, p2, p3, p4, p5); } |
| 601 | #else |
| 691 | 602 | _ReturnType operator()() const { return (*m_function)(m_object); } |
| 692 | 603 | _ReturnType operator()(_P1Type p1) const { return (*m_function)(m_object, p1); } |
| 693 | 604 | _ReturnType operator()(_P1Type p1, _P2Type p2) const { return (*m_function)(m_object, p1, p2); } |
| 694 | 605 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3) const { return (*m_function)(m_object, p1, p2, p3); } |
| 695 | 606 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4) const { return (*m_function)(m_object, p1, p2, p3, p4); } |
| 696 | 607 | _ReturnType operator()(_P1Type p1, _P2Type p2, _P3Type p3, _P4Type p4, _P5Type p5) const { return (*m_function)(m_object, p1, p2, p3, p4, p5); } |
| 608 | #endif |
| 697 | 609 | |
| 698 | 610 | // late binding |
| 699 | 611 | void late_bind(delegate_late_bind &object) { bind((*m_latebinder)(object)); } |
| r18548 | r18549 | |
| 703 | 615 | void bind(delegate_generic_class *object) |
| 704 | 616 | { |
| 705 | 617 | m_object = object; |
| 618 | |
| 619 | // update callobject to match, unless it is pointing to ourself |
| 620 | if (m_callobject != reinterpret_cast<delegate_generic_class *>(this)) |
| 621 | m_callobject = m_object; |
| 622 | |
| 623 | #if (USE_DELEGATE_TYPE != DELEGATE_TYPE_COMPATIBLE) |
| 624 | // update the function |
| 706 | 625 | if (m_object != NULL && is_mfp()) |
| 707 | 626 | m_function = reinterpret_cast<generic_static_func>(m_raw_mfp.convert_to_generic(m_object)); |
| 627 | #endif |
| 708 | 628 | } |
| 709 | 629 | |
| 710 | 630 | // internal state |
| 711 | 631 | generic_static_func m_function; // generic static function pointer |
| 632 | delegate_generic_class * m_callobject; // pointer to the object used for calling |
| 712 | 633 | }; |
| 713 | 634 | |
| 714 | | #endif |
| 715 | 635 | |
| 716 | 636 | |
| 717 | 637 | //************************************************************************** |