一个简单观察者模式的实现 cocos2dx
2012-08-22 15:50
344 查看
头文件
CPP
// 王智泉 2012/06/11 #ifndef __myNotification__H__ #define __myNotification__H__ #include "CCPlatformMacros.h" #include <vector> #include <map> #include <string> // 回调 class myNotification; class myCallbackBase { public: myCallbackBase(){} virtual bool operator()(const myNotification& notification) = 0; }; template<typename T> class myMemberCallback : public myCallbackBase { public: typedef bool(T::*CallBackFun)(const myNotification&); myMemberCallback(CallBackFun func, T* target) : _function(func) , _target(target){} virtual bool operator()(const myNotification& notification) { return (_target->*_function)(notification); } private: CallBackFun _function; T* _target; }; // 观察者 class CC_DLL myObserver { public: myObserver():_target(NULL) , _callback(NULL), _count(NULL){} template<typename T> myObserver(T* target, bool (T::*function)(const myNotification&)) : _callback(new myMemberCallback<T>(function, target)) , _count(new int(1)) , _target(target) { } myObserver(const myObserver& other) { this->_count = other._count; this->_callback = other._callback; this->_target = other._target; (*this->_count)++; } virtual ~myObserver() { if (_count) { if (--*_count == 0) { if (_callback) { delete _callback; _callback = NULL; } delete _count; _count = NULL; } } } virtual bool operator()(const myNotification& notification) { return (*_callback)(notification); } virtual bool operator()(myObserver* other) { return _target == other->_target; } virtual myObserver& operator=(const myObserver& other) { if (_count) { if (--*_count == 0) { if (_callback) { delete _callback; _callback = NULL; } delete _count; _count = NULL; } } this->_count = other._count; this->_callback = other._callback; this->_target = other._target; (*this->_count)++; return *this; } const void* getTarget() const { return _target; } private: int* _count; // 引用次数 myCallbackBase* _callback; void* _target; }; // 观察者查找器 class myObjserverFinder { public: myObjserverFinder(void* target) :_target(target){} ~myObjserverFinder() { } bool operator()(const myObserver & obs) { return _target == obs.getTarget(); } private: void* _target; }; // 事件参数 class CC_DLL myNotification { public: myNotification(void* sender, void* arg):_sender(sender), _arg(arg) {} void* _sender; void* _arg; std::map<std::string, void*> _userDatas; }; // 事件中心 class CC_DLL myNotificationCenter { public: virtual ~myNotificationCenter(); static myNotificationCenter* defaultNotification() { static myNotificationCenter instance; return &instance; } // 添加观察者 void addObserver( const char* eventName, const myObserver& observer); // 删除观察者 void removeObserver(const char* eventName, void* target); // 发送消息 void postNotification(const char* eventName, const myNotification& notification); private: typedef std::vector<myObserver> ObserverList; typedef std::map<std::string, ObserverList*> EventList; EventList _eventList; }; #endif
CPP
// 王智泉 2012/06/11 #include "myNotification.h" #include "ccMacros.h" #include <algorithm> using namespace cocos2d; // ================================================================================================= myNotificationCenter::~myNotificationCenter() { for (EventList::iterator epos = _eventList.begin(); epos != _eventList.end(); ++epos) { ObserverList* observers = epos->second; delete observers; } _eventList.clear(); } // ================================================================================================= void myNotificationCenter::addObserver( const char* eventName, const myObserver& observer) { CCAssert(NULL != eventName, "add observer error1"); ObserverList* observerList = NULL; EventList::iterator ePos = _eventList.find(eventName); if (ePos != _eventList.end()) { observerList = ePos->second; } else { observerList = new ObserverList; _eventList[eventName] = observerList; } observerList->push_back(observer); } // ================================================================================================ void myNotificationCenter::removeObserver(const char* eventName, void* target) { EventList::iterator ePos = _eventList.find(eventName); if (ePos != _eventList.end()) { ObserverList* observers = ePos->second; std::remove_if(observers->begin(), observers->end(), myObjserverFinder(target)); if (observers->size() == 0) { delete observers; _eventList.erase(ePos); } } } // ================================================================================================ void myNotificationCenter::postNotification(const char* eventName, const myNotification& notification) { EventList::iterator epos = _eventList.find(eventName); if (epos != _eventList.end()) { ObserverList* observers = epos->second; for (ObserverList::iterator opos = observers->begin(); opos != observers->end(); ++opos) { (*opos)(notification); } } }
相关文章推荐
- 一个简单观察者模式的实现 cocos2dx
- 一个类实现Android观察者模式(最简单实用的观察者模式)
- 介绍一个款可以在javascript对象上实现观察者模式的类库-Watch.js
- 自实现观察者模式(发布/订阅模式)的一个隐藏bug
- 使用Python语言写一个简单的KMP模式匹配算法实现
- 你知道的,javascript语言的执行环境是"单线程模式",这种模式的好处是实现起来比较简单,执行环境相对单纯;坏处是只要有一个任务耗时很长,后面的任务都必须排队等着,会拖延整个程序的执行,因此很多时候需要进行“异步模式”,请列举js异步编程的方法。
- 复合控件,editor控件,观察者的一些简单运用,实现一个类似对话框的控件
- C++ 使用模版范式写一个单例模式的类--简单实现单例模式
- 一个用简单的JavaScript及Css实现的模式层
- 设计模式之二:观察者模式(简单实现(气象站模拟流程))
- 简单的实现一个类似于Cocos2dx的游戏框架——导演、场景、层、精灵(已填坑5%)
- PHP观察者模式原理与简单实现方法示例
- javamail实现发送邮件并简单实现观察者模式
- 观察者模式的简单实现与讨论
- 使用VS2013 实现一个简单的单例模式singleton
- 简单消息处理的实现--观察者模式应用
- 用JSP+Servlet+JavaBean模式实现一个简单的登录网页设计(JSP+Tomcat+MySQL)
- 用C#中的委托和事件简单实现观察者模式
- 使用EF6和MVC5实现一个简单的选课系统--使用EF6异步编程模式和存储过程(9/12)
- 复合控件,editor控件,观察者的一些简单运用,实现一个类似对话框的控件(转的胖胖的)