设计目的:为了减少类之间的耦合
特性:
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); } } } }