设计需求:
游戏结束后,通知需要监听“游戏结束”消息的对象发送通知。
开发unity3d中我们知道c#有默认的delegate实现委托event的事件,很简单,前面的我的文章有做一个较为详细的介绍委托,以及此模式的一些优点。
送上传送门回忆下: http://blog.csdn.net/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)();