您的位置:首页 > 移动开发 > Cocos引擎

一个简单观察者模式的实现 cocos2dx

2012-08-22 15:50 344 查看
头文件

// 王智泉 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);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐