事件委托处理机制实现了在两个没有联系的对象之间建立一种事件收发机制,事件发送方和事件监听方互相不必知道对方的任何细节,避免对象之间的依赖,降低系统耦合性。
直接上代码:
Event.h
#pragma once
#include <map>
using std::map;
#ifdef DLL_EXPORT
#define DLL_API _declspec(dllexport)
#else
#define DLL_API _declspec(dllimport)
#endif
enum EventType
{
EVENT_USER
};
#define EVENT_CALLBACK(classname , function) new EventCallBack<classname>(function)
class DLL_API IEvent
{
public:
IEvent(int type);
virtual ~IEvent(void) = 0;
virtual int getType();
private:
int m_EventType;
};
class DLL_API IEventCallBack
{
public:
IEventCallBack(){}
virtual ~IEventCallBack(){}
virtual void call(void* reveiver,IEvent& value) = 0;
};
template<class T>
class DLL_API EventCallBack:public IEventCallBack
{
private:
//一个指向静态成员函数的指针
typedef void (T::*Callback)(IEvent& event);
const Callback m_pMethod;
public:
EventCallBack(const Callback funct):m_pMethod(funct){}
virtual ~EventCallBack(){}
virtual void call(void* reveiver,IEvent& value)
{
T* obj = (T*)(reveiver);
if(obj)
{
(obj->*m_pMethod)(value);
}
}
};
class DLL_API EventManager
{
public:
EventManager();
~EventManager();
static EventManager* getSingleton();
struct connect_data
{
IEventCallBack* callback;
void* sender;
void* receiver;
};
void sendEvent(IEvent& event,void* sender);
void connectEvent(int eventType,void* sender,void* receiver,IEventCallBack* callback);
void disconnectEvent(int eventType,void* receiver);
private:
static EventManager* m_pThis;
typedef map<void*,connect_data> EventListener;
typedef map<int,EventListener> EventMap;
EventMap m_EvntMap;
};
Event.cpp
#include "IEvent.h"
IEvent::IEvent(int type)
{
m_EventType = type;
}
IEvent::~IEvent(void)
{
}
int IEvent::getType()
{
return m_EventType;
}
//
EventManager* EventManager::m_pThis = NULL;
EventManager::EventManager()
{
m_EvntMap.clear();
m_pThis = this;
}
EventManager::~EventManager()
{
EventMap::iterator it = m_EvntMap.begin();
while(it != m_EvntMap.end())
{
EventListener::iterator lisIt = it->second.begin();
while(lisIt != it->second.end())
{
if (lisIt->second.callback)
{
delete lisIt->second.callback;
lisIt->second.callback = NULL;
}
lisIt++;
}
it++;
}
m_pThis = NULL;
}
EventManager* EventManager::getSingleton()
{
if(m_pThis == NULL)
m_pThis = new EventManager;
return m_pThis;
}
void EventManager::sendEvent(IEvent& event,void* sender)
{
int type = event.getType();
EventMap::iterator it = m_EvntMap.find(type);
if (it != m_EvntMap.end())
{
EventListener::iterator lit_end = it->second.end();
for(EventListener::iterator lit = it->second.begin();lit != lit_end;lit++)
{
if(lit->second.receiver && (lit->second.sender == NULL || sender == lit->second.sender))
{
lit->second.callback->call(lit->second.receiver,event);
}
}
}
}
void EventManager::connectEvent(int eventType,void* sender,void* receiver,IEventCallBack* callback)
{
connect_data data;
data.callback = callback;
data.sender = sender;
data.receiver = receiver;
EventMap::iterator it = m_EvntMap.find(eventType);
if(it == m_EvntMap.end())
{
EventListener listmap;
listmap.insert(EventListener::value_type(receiver,data));
m_EvntMap.insert(EventMap::value_type(eventType, listmap));
}
else
{
if(it->second.find(receiver) == it->second.end())
{
it->second.insert(EventListener::value_type(receiver, data));
return;
}
}
}
void EventManager::disconnectEvent(int eventType,void* receiver)
{
EventMap::iterator it = m_EvntMap.find(eventType);
if(it != m_EvntMap.end())
{
EventListener::iterator lit = it->second.find(receiver);
if(lit != it->second.end())
{
if(lit->second.callback)
{
delete lit->second.callback;
}
it->second.erase(lit);
return;
}
}
}