COCOS2DX中的selector机制

时间:2023-01-15 18:25:07

在Cocos2d-x中点击某个按钮要执行一个回调函数时,一般的写法是以下这样 : 

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. // add a "share" icon to exit the progress. it's an autorelease object  
  2. CCMenuItemImage *pShareItem = CCMenuItemImage::create(  
  3.                                                       "share.png",  
  4.                                                       "share.png",  
  5.                                                       this,  
  6.                                 menu_selector(HelloWorld::menuShareCallback));  

其中的HelloWorld::menuShareCallback是HelloWorld类的一个函数, 生命为 : 

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. // a selector callback to share button  
  2. void menuShareCallback(CCObject* pSender);  

这个menuShareCallback就相当与Java中Listener的回调函数, 那么Cocos2d-x的selector机制是如何实现的呢 ?

要明白selector机制, 我们首先要清楚C/C++语言中的函数指针, 函数指针其实就是指向函数的指针。 在C/C++中, 函数会以内存地址来标识, 从函数的内存地址开始执行就相当于执行该函数。那么用什么来代表函数指针的地址呢, 其实C/C++语言中的函数名就代表了函数在内存中的地址。看下面的例子 : 

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. #include <iostream>  
  2.   
  3. // 定义一个函数指针类型, <span style="font-family: Arial, Helvetica, sans-serif;">MethodPointer</span>  
  4. typedef void (*MethodPointer)(int num);  
  5.   
  6. // 普通函数  
  7. void printNum(int num)  
  8. {  
  9.     cout << "The num is : " <<num<<endl;  
  10. }  
  11.   
  12. int main(int argc, const char * argv[])  
  13. {  
  14.       
  15.     MethodPointer mp = printNum;  
  16.     mp(444);  
  17.       
  18.     return 0;  
  19. }  
在文件的上面我们定义了一个函数指针类型MethodPointer,和它对应的函数类型应该是没有返回值的,且有一个Int参数的函数, 例如上文中的void printNum(int num)函数, 在main中我们定义了一个MethodPointer指针,指向了printNum方法,然后执行mp(444);就相当于执行了printNum(444)方法。 

COCOS2DX中的selector机制


对于C++来说还有一种是成员函数指针,它与C中的函数指针类似, 只是指针指向的是某个类中的成员函数。看下面这个例子 :

头文件

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. #ifndef __MenberCallback__MemberPointer__  
  2. #define __MenberCallback__MemberPointer__  
  3.   
  4. class MemberPointer;  
  5. // 定义一个成员函数指针  
  6. typedef void (MemberPointer::*MCallback)(int num);  
  7.   
  8. #include <iostream>  
  9. class MemberPointer  
  10. {  
  11. public:  
  12.     MemberPointer();  
  13.     ~MemberPointer();  
  14.     void click(MCallback callback);  
  15.     void doSth(int code);  
  16.       
  17. } ;  
  18.   
  19. #endif /* defined(__MenberCallback__MemberPointer__) */  

cpp 

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. #include <iostream>  
  2. #include "MemberPointer.h"  
  3. using namespace std;  
  4.   
  5. MemberPointer::MemberPointer()  
  6. {  
  7.       
  8. }  
  9.   
  10. MemberPointer::~MemberPointer()  
  11. {  
  12.       
  13. }  
  14.   
  15. void MemberPointer::doSth(int code)  
  16. {  
  17.     cout<<"call back method.     "<<code<<endl;  
  18. }  
  19.   
  20. void MemberPointer::click(MCallback callback)  
  21. {  
  22.     // 执行回调, 因为在callback中传递的是自身的回调函数doStn,所以直接用this  
  23.     (this->*callback)(888);  
  24. }  

main函数  :
[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. int main(int argc, const char * argv[])  
  2. {  
  3.       
  4.     MemberPointer *mPointer = new MemberPointer();  
  5.     mPointer->click(&MemberPointer::doSth) ;  
  6.       
  7.     return 0;  
  8. }  


执行结果为 
COCOS2DX中的selector机制

可见, 在click方法中我们执行了doSth方法, 打印出了888这几个数字。


参考资料  :  成员函数指针 


最后模拟一下Cocos2d-x中按钮的selector的实现, 就直接上代码了。

CCObject.h

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. <span style="font-size:14px;">//  
  2. //  CCObject.h  
  3. //  membercallback  
  4. //  
  5. //  Created by mrsimple on 4/1/14.  
  6. //  Copyright (c) 2014 mrsimple. All rights reserved.  
  7. //  
  8.   
  9. #ifndef __membercallback__CCObject__  
  10. #define __membercallback__CCObject__  
  11.   
  12. #include <iostream>  
  13.   
  14. class CCObject  
  15. {  
  16. public:  
  17.     CCObject();  
  18.     virtual ~CCObject();  
  19. } ;  
  20.   
  21. // 定义回调函数为CCObject或者CCObject子类中的成员函数,两个参数  
  22. typedef void (CCObject::*ButtonCallback)(CCObject* pSender, int stCode);  
  23. // 定义selector  
  24. #define button_selector(_SELECTOR) (ButtonCallback)(&_SELECTOR)  
  25.   
  26. #endif /* defined(__membercallback__CCObject__) */</span><span style="font-size:18px;">  
  27. </span>  


CCObject.cpp

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. #include "CCObject.h"  
  2.   
  3. CCObject::CCObject()  
  4. {  
  5. }  
  6.   
  7. CCObject::~CCObject()  
  8. {  
  9. }  

CCButton.h

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. //  
  2. //  CCButton.h  
  3. //  membercallback  
  4. //  
  5. //  Created by mrsimple on 4/1/14.  
  6. //  Copyright (c) 2014 mrsimple. All rights reserved.  
  7. //  
  8.   
  9. #ifndef __membercallback__CCButton__  
  10. #define __membercallback__CCButton__  
  11.   
  12. #include <iostream>  
  13. #include "CCObject.h"  
  14.   
  15. class CCButton : public CCObject  
  16. {  
  17. public:  
  18.     CCButton();  
  19.     virtual ~CCButton();  
  20.     void click(CCObject* pSender);  
  21.     void setCallback(ButtonCallback callback );  
  22.       
  23. private:  
  24.     void buttonClick(CCObject* pSender, int code) ;  
  25.     ButtonCallback _buttonCallback;  
  26.     CCObject* mSender;  
  27. } ;  
  28.   
  29. #endif /* defined(__membercallback__CCButton__) */  

CCButton.cpp

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. //  
  2. //  CCButton.cpp  
  3. //  membercallback  
  4. //  
  5. //  Created by mrsimple on 4/1/14.  
  6. //  Copyright (c) 2014 mrsimple. All rights reserved.  
  7. //  
  8.   
  9. #include "CCButton.h"  
  10.   
  11. using namespace std;  
  12.   
  13. CCButton::CCButton()  
  14. :mSender(NULL)  
  15. {  
  16. }  
  17.   
  18. CCButton::~CCButton()  
  19. {  
  20.     delete mSender;  
  21. }  
  22. // 设置回调函数  
  23. void CCButton::setCallback(ButtonCallback callback)  
  24. {  
  25.     _buttonCallback = callback ;  
  26. }  
  27.   
  28. // 按钮点击操作, 执行回调  
  29. void CCButton::click(CCObject* pSender)  
  30. {  
  31.     mSender = pSender ;  
  32.     // 执行回调函数,这里执行的则是CCScene中的buttonCallback函数  
  33.     (mSender->*_buttonCallback)(mSender, 123);  
  34. }  

CCScene.h

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. //  
  2. //  CCScene.h  
  3. //  membercallback  
  4. //  
  5. //  Created by mrsimple on 4/1/14.  
  6. //  Copyright (c) 2014 mrsimple. All rights reserved.  
  7. //  
  8.   
  9. #ifndef __membercallback__CCScene__  
  10. #define __membercallback__CCScene__  
  11.   
  12. #include <iostream>  
  13.   
  14. #include <iostream>  
  15. #include "CCObject.h"  
  16. #include "CCButton.h"  
  17.   
  18. class CCScene : public CCObject  
  19. {  
  20. public:  
  21.     CCScene();  
  22.     virtual ~CCScene();  
  23.     void clickButton();  
  24. private:  
  25.     CCButton* mButton;  
  26.     void buttonCallback(CCObject* pSender, int code);  
  27. };  
  28.   
  29. #endif /* defined(__membercallback__CCScene__) */  

CCScene.cpp

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. //  
  2. //  CCScene.cpp  
  3. //  membercallback  
  4. //  
  5. //  Created by mrsimple on 4/1/14.  
  6. //  Copyright (c) 2014 mrsimple. All rights reserved.  
  7. //  
  8.   
  9. #include "CCObject.h"  
  10. #include "CCButton.h"  
  11. #include "CCScene.h"  
  12.   
  13. using namespace std;  
  14.   
  15. // 构造函数, 创建CCButton  
  16. CCScene::CCScene()  
  17. :mButton(new CCButton())  
  18. {  
  19.     // 设置回调函数  
  20.     mButton->setCallback( button_selector(CCScene::buttonCallback) ) ;  
  21. }  
  22.   
  23. CCScene::~CCScene()  
  24. {  
  25.     delete  mButton ;  
  26. }  
  27.   
  28.   
  29. // 模拟点击按钮的操作  
  30. void CCScene::clickButton()  
  31. {  
  32.     if ( mButton != NULL )  
  33.     {  
  34.         // 按钮点击  
  35.         mButton->click(this) ;  
  36.     }  
  37.       
  38. }  
  39.   
  40. // 点击按钮, 回调该函数  
  41. void CCScene::buttonCallback(CCObject *pSender, int code)  
  42. {  
  43.     cout<<"In CCScene --> callback, code = "<<code<<endl;  
  44. }  


main.cpp 使用示例 :

[cpp] view plaincopyCOCOS2DX中的selector机制COCOS2DX中的selector机制
  1. //  
  2. //  main.cpp  
  3. //  membercallback  
  4. //  
  5. //  Created by mrsimple on 4/1/14.  
  6. //  Copyright (c) 2014 mrsimple. All rights reserved.  
  7. //  
  8.   
  9. #include <iostream>  
  10. #include "CCObject.h"  
  11. #include "CCScene.h"  
  12.   
  13. int main(int argc, const char * argv[])  
  14. {  
  15.   
  16.     CCScene* sc = new CCScene();  
  17.     sc->clickButton() ;  
  18.       
  19.     return 0;  
  20. }  
首先定义了CCObject类,该类为Cocos2d-x其他引用类型的基类,并且在头文件中定义了按钮的回调函数指针。CCButton中定义了按钮的点击函数,在该点击函数中执行对应的回调函数。在CCScene场景中添加一个按钮, 并且将该按钮点击的回调函数设置为CCScene类中的buttonCallback成员函数, 然后通过CCScene类中的clickButton函数来显式触发CCButton的click函数,CCButton对象会在click函数中执行点击按钮的回调( 即 CCScene类的buttonCallback函数 ), 最后输出结果。

输出结果 

COCOS2DX中的selector机制


最后看看Cocos2d-x中的selector的实现, 直接上代码测试:

头文件  

//
// MemberPointer.h
// MenberCallback
//
// Created by mrsimple on 3/13/14.
// Copyright (c) 2014 mrsimple. All rights reserved.
//

#ifndef __MenberCallback__MemberPointer__
#define __MenberCallback__MemberPointer__

#include <iostream>

class MemberPointer;
// 定义一个成员函数指针
typedef void (MemberPointer::*MCallback)(int num);

// 定义selector
#define callback_selector(_SEL) (MCallback)(&_SEL)


class MemberPointer
{
public:
MemberPointer();
~MemberPointer();
void click(MCallback callback);
void doSth(int code);
void doSelector(int code);

} ;

#endif /* defined(__MenberCallback__MemberPointer__) */

cpp

//
// MemberPointer.cpp
// MenberCallback
//
// Created by mrsimple on 3/13/14.
// Copyright (c) 2014 mrsimple. All rights reserved.
//

#include <iostream>
#include "MemberPointer.h"
using namespace std;

MemberPointer::MemberPointer()
{

}

MemberPointer::~MemberPointer()
{

}

void MemberPointer::doSelector(int code)
{
cout<<"doSelector "<<code<<endl;
}

void MemberPointer::doSth(int code)
{
cout<<"call back method. "<<code<<endl;
}

void MemberPointer::click(MCallback callback)
{
// 执行回调, 因为在callback中传递的是自身的回调函数doStn,所以直接用this
(this->*callback)(888);
}

main

//
// main.cpp
// MenberCallback
//
// Created by mrsimple on 3/13/14.
// Copyright (c) 2014 mrsimple. All rights reserved.
//

#include <iostream>
#include "Selector.h"
#include "MemberPointer.h"

typedef void (*MP)(int stCode);


void printNum(int num)
{
cout << "The num is : " <<num<<endl;
}

int main(int argc, const char * argv[])
{

MemberPointer *mPointer = new MemberPointer();
mPointer->click(&MemberPointer::doSth) ;

// selector的使用, 注意这里和上面的区别, callback_selector (XXXXXXXX)
mPointer->click(callback_selector(MemberPointer::doSelector)) ;
return 0;
}

输出结果 

COCOS2DX中的selector机制




转载:http://blog.csdn.net/bboyfeiyu/article/details/21181503