cocos2d-x项目中有时碰见需要注册回调函数,然后在合适的条件触发,有些类似android的广播消息。楼主项目中遇到的是网络数据处理,下面是主要的实现思路,希望能有些帮助。
定义消息回调类MessagePushEntry,该类尽量遵循cocos2d-x的数据结构和规范,主要有回调对象,回调方法及用来遍历的链表数据结构。
class MessagePushEntry{
private:
MessagePushEntry(const char* key,CCObject *target,SEL_MsgCallFuncO selector);
public:
~MessagePushEntry();
private:
#define MAX_KEY 256
char msgKey[MAX_KEY];
CCObject *target;
SEL_MsgCallFuncO selector;
public:
UT_hash_handle hh;
};
SEL_MsgCallFuncO是自己定义的一个回调宏,接受回调数据,msgKey是注册的过滤条件。
typedef void (CCObject::*SEL_MsgCallFuncO)(void*);
#define msgcallfuncO_selector(_SELECTOR) (SEL_MsgCallFuncO)(&_SELECTOR)
下面是注册回调
addMessageCallBack(const string key,CCObject *target,SEL_MsgCallFuncO selector){
if(target==NULL)
return;
MessagePushEntry *pElement=NULL;
HASH_FIND_STR(m_messagePush,key.c_str(),pElement);
if(pElement==NULL){
target->retain();
pElement=new MessagePushEntry(key.c_str(),target,selector);
HASH_ADD_STR(m_messagePush,msgKey,pElement);
}
return;
}
由于项目关系,这里和项目有关的代码都被省掉,不过问题应该不大,主要实现完全是按cocos2d-x的书写规范实现,大家如果对引擎有了解,应该能看懂。
上面这些就是注册回调的大致实现,然后就是在适当时候去触发回调。
checkPopMsg(float dt){
MessagePushEntry *pElement=NULL;
HASH_FIND_STR(m_messagePush,onlyKey.c_str(),pElement);
if(NULL==pElement){
CCLOG("Message warn:no seletor");
return;
}
CCObject *myTarget=pElement->target;
SEL_MsgCallFuncO mySeletor=pElement->selector;
if(myTarget&& mySeletor){
(myTarget->*mySeletor)(msg);
}
HASH_DEL(m_messagePush,pElement);
pElement->target->release();
CC_SAFE_DELETE(pElement);
}
onlyKey是上面提到的消息的过滤条件,这个和注册时的key保持一致。
msg就是我们需要回调传的数据了,楼主这里传的是消息数据类,然后就等着处理回调函数吧。
有点需要注意,楼主没去做具体测试,但问题应该是存在的,注册回调后target会被retain()一次,所以如果注册了回调而没有触发应该会造成内存溢出。所以不用等回调直接退出时,需要在target的onExit()方法中去删除注册!cocos2d-x自定义回调实现
原文:http://blog.csdn.net/andy_quan/article/details/18615105