设计目的:为了减少类之间的耦合
特性:
0.使用ccobject的引用计数,在调用时不用担心内存释放问题
1.不用继承任何额外的接口或类,只要是cocos2dx内置类的子类都可以使用该机制
使用约束:
0.在注册时会将对象的引用计数加一,反注册时引用计数减一。
1.虽然任意ccobject的子类都可以使用,但是为了自动内存管理,最好在ccnode的子类中使用
1.1 在onEnter时注册事件
1.2 在onExit时反注册
小提示
0.一个事件最好只有一个分发对象,如果出现多个对象分发同一个事件,说明可能代码中有重复的功能。
1.一个函数最好只注册一个事件,以保证函数功能的单一
代码
头文件
//
// EventController.h
// LinkBubble3
//
// Created by user on 13-5-1.
//
//
#ifndef __LinkBubble3__EventController__
#define __LinkBubble3__EventController__
#include "cocos2d.h"
#include <map>
#include <list>
class AppDelegate;
#define EVENT_NAME_SPACE namespace EVENT {
EVENT_NAME_SPACE
enum type{
LIFECHANGE= 0,
};
//事件回调
typedef void (cocos2d::CCObject::*SEL_EVENT_CALL)(int,int);
#define eventfunc_selector(_SELECTOR) (EVENT::SEL_EVENT_CALL)(&_SELECTOR)
class EventController :public cocos2d::CCObject {
class EventWraper
{
private:
cocos2d::CCObject* obj;
SEL_EVENT_CALL callBack;
public:
EventWraper(cocos2d::CCObject* o =NULL,SEL_EVENT_CALL c=NULL)
:obj(o),callBack(c)
{
CC_SAFE_RETAIN(obj);
}
~EventWraper(){CC_SAFE_RELEASE_NULL(obj);}
EventWraper(const EventWraper& r)
{
obj=r.obj;
callBack= r.callBack;
CC_SAFE_RETAIN(obj);
}
const EventWraper& operator =(const EventWraper& r)
{
if(this == &r){return *this;}
CC_SAFE_RELEASE_NULL(obj);
obj=r.obj;
callBack= r.callBack;
CC_SAFE_RETAIN(obj);
return *this;
}
bool operator ==(const EventWraper& r)const
{
return obj == r.obj && callBack == r.callBack;
}
void Call(int param1,int param2)
{
if(obj != NULL)
{
(obj->*callBack)(param1,param2);
}
}
};
typedef std::list<EventWraper> EventList;
typedef std::map<type, EventList> TypeToEventListMap;
TypeToEventListMap m_mapEventObjs;
EventController(const EventController&) = delete;
const EventController& operator =(const EventController&)=delete;
EventController(){}
friend class AppDelegate;
public:
void Register(type t,cocos2d::CCObject* pObj,SEL_EVENT_CALL callBack);
void UnRegister(type t,cocos2d::CCObject* pObj,SEL_EVENT_CALL callBack);
void Dispatch(type t,int param1=0,int param2=0);
};
EventController* GetController();
#define REG_EVENT(type,Class,Func) EVENT::GetController()->Register(type, this, eventfunc_selector(Class::Func))
#define UNREG_EVENT(type,Class,Func) EVENT::GetController()->UnRegister(type, this, eventfunc_selector(Class::Func))
}
#endif /* defined(__LinkBubble3__EventController__) */
cpp
//
// EventController.cpp
// LinkBubble3
//
// Created by user on 13-5-1.
//
//
#include "EventController.h"
#include "AppDelegate.h"
EVENT_NAME_SPACE
EventController* GetController()
{return &AppDelegate::Instance()->eventController;}
void EventController::Register(EVENT::type t, cocos2d::CCObject *pObj, SEL_EVENT_CALL callBack)
{
auto iterEvent = m_mapEventObjs.find(t);
if (iterEvent == m_mapEventObjs.end()) {
iterEvent = m_mapEventObjs.insert(std::make_pair(t, EventList())).first;
}
EventWraper wraper(pObj,callBack);
EventList& list = iterEvent->second;
if (std::find(list.begin(), list.end(), wraper) == list.end()) {
list.push_back(wraper);
}
}
void EventController::UnRegister(EVENT::type t, cocos2d::CCObject *pObj, SEL_EVENT_CALL callBack)
{
auto iterEvent = m_mapEventObjs.find(t);
if (iterEvent == m_mapEventObjs.end()) {
return;
}
EventWraper wraper(pObj,callBack);
EventList& list = iterEvent->second;
list.remove(wraper);
}
void EventController::Dispatch(type t,int param1,int param2)
{
for (auto iterEvent = m_mapEventObjs.begin(); iterEvent != m_mapEventObjs.end(); ++iterEvent) {
EventList& objList = iterEvent->second;
for (auto itCall = objList.begin(); itCall != objList.end(); ++itCall) {
itCall->Call(param1, param2);
}
}
}
}