cocos2d-x自定义回调实现

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自定义回调实现

上一篇:lucene 查询时输入的关键字中包含的词必须出现才被查询出来实现


下一篇:ASCII转十六进制小工具