设计需求:
游戏结束后,通知需要监听“游戏结束”消息的对象发送通知。
开发unity3d中我们知道c#有默认的delegate实现委托event的事件,很简单,前面的我的文章有做一个较为详细的介绍委托,以及此模式的一些优点。
送上传送门回忆下: http://blog.youkuaiyun.com/chiuan/article/details/7918833
回归正题,我们直入正题,如何实现?
OK,可以google:“成员函数指针”相信大家会从中找到很多文章有涉及其介绍和使用。
1、先定义这个成员函数指针
typedef void (CCObject::*GAMEOVER_CALLBACK)();
#define gameover_callback(_METHOD) (GAMEOVER_CALLBACK)(&_METHOD)
如上,定义一个是CCObject的返回void,传参为空的成员函数指针,命名为GAMEOVER_CALLBACK,因为指针是*,我们define一个宏处理,让输入的成员函数取其地址指针转化为函数指针。
2、定义引用成员函数指针的对象列表以及函数指针列表
CCArray* callbacksOfGameover;
std::list<GAMEOVER_CALLBACK>* listOfGameover;
这里插一句补充,因为要调用这个成员函数方法,必须通过成员对象去调用。
3、实现监听者的3个方法,注册监听者、移除监听者、通知监听者
头文件定义:
bool registerObserverGameover(CCObject* obj,GAMEOVER_CALLBACK _method);
bool removeObserverGameover(CCObject* obj);
void notifyObserverGameover();
具体实现:
#pragma mark -
#pragma mark delegate or notifycation
bool GameLayer::registerObserverGameover(CCObject* obj,GAMEOVER_CALLBACK _method){
if (callbacksOfGameover && obj) {
callbacksOfGameover->addObject(obj);
//add method into vector.
listOfGameover->push_back(_method);
CCLOG("list of gameover size = %d",listOfGameover->size());
}
else CCLOG("register observer gameover error. maybe obj == null.");
return true;
}
bool GameLayer::removeObserverGameover(CCObject* obj){
if (callbacksOfGameover && obj && listOfGameover) {
int index = callbacksOfGameover->indexOfObject(obj);
callbacksOfGameover->removeObjectAtIndex(index);
std::list<GAMEOVER_CALLBACK>::iterator iterator = listOfGameover->begin();
for (int count = 0; iterator != listOfGameover->end(); iterator++) {
count+=1;
if (index + 1 == count) {
listOfGameover->erase(iterator);
break;
}
CCLOG("iterator position = %d",count);
}
CCLOG("list of gameover size = %d",listOfGameover->size());
}
else CCLOG("remove observer gameover error. maybe obj == null.");
return true;
}
void GameLayer::notifyObserverGameover(){
std::list<GAMEOVER_CALLBACK>::iterator iterator = listOfGameover->begin();
for (int i = 0 ; iterator != listOfGameover->end() ; iterator++) {
CCObject* obj = NULL;
if(i < callbacksOfGameover->count()){
obj = callbacksOfGameover->objectAtIndex(i);
}
if (obj) {
GAMEOVER_CALLBACK pCall = (GAMEOVER_CALLBACK)*iterator;
(obj->*pCall)();
}
i++;
}
}
暂时还没发现cocos2d-x里面用什么来记录这个函数指针列表,用了list,其实也可以用vector。
然后注意一点就是如何调用对象的成员函数指针,就相当于调用这个方法一样!
GAMEOVER_CALLBACK pCall = (GAMEOVER_CALLBACK)*iterator;
(obj->*pCall)();
obj其实就是记录的某个对象,然后获取其成员函数指针pCall便可调用。其实这个很好理解,平时我们调用方法会是这样:
定义:void debug();
调用:debug();
那么把假如对象a里面的debug方法变成一个成员函数指针p调用:(a->*p)();