#include<map>
#define ObjDef(class_name) \
s_ClassName = #class_name; \
v_id = this;
class CObject;
class CEvent;
class CSendEvent;
class CEventsManage;
class CObject
{
public:
std::string s_ClassName;
void * v_id;
bool Istype(std::string name);
char* GetClassName();
int GetId();
virtual void HandleEvent(CSendEvent event) = 0;
};
bool CObject::Istype(std::string name)
{
return s_ClassName == name;
}
char* CObject::GetClassName()
{
return (char*)s_ClassName.c_str();
}
int CObject::GetId()
{
return (int)v_id;
}
class CEvent
{
public:
bool isAll; //是否广播
int id; //事件ID
CEvent()
{
id = -1;
isAll = false;
}
~CEvent()
{
}
};
class CSendEvent :public CEvent
{
public:
CSendEvent()
{
arg = 0;
send_obj = 0;
}
~CSendEvent()
{
if (isAll && arg)
{
delete arg;
}
}
CObject *send_obj;
void *arg; //参数
virtual bool IsSend(CObject * obj){ return true; }
};
class CEventsManage
{
public:
static CEventsManage EventsManage;
std::map<int, std::multimap<CObject *, CObject *>> map;
//virtual void RegisterEvent(int event_id, CObject *obj, void * arg = 0, bool isAll = false);
void SendEvent(CSendEvent event); //event需要自行释放内存
void AddListener(CEvent event, CObject *obj);
void RemoveListener(CEvent event, CObject *obj);
};
CEventsManage CEventsManage::EventsManage;
void CEventsManage::SendEvent(CSendEvent event)
{
std::map<int, std::multimap<CObject *, CObject *>>::iterator it;
std::multimap<CObject *, CObject *>::iterator muil_it;
it = map.find(event.id); //找到对应ID MMAP;
if (it == map.end())
{
return ;
}
muil_it = it->second.begin();
if (muil_it == it->second.end()) //没有元素
{
return;
}
//遍历发送事件
for (; muil_it != it->second.end(); ++muil_it)
{
if (event.IsSend((muil_it->second))) //判断是否是事件自己需要发送的Obj
{
(muil_it->second)->HandleEvent(event); //发送事件处理消息
if (!event.isAll) //是否广播
{
break;
}
}
}
}
void CEventsManage::AddListener(CEvent event, CObject *obj)
{
std::map<int, std::multimap<CObject *, CObject *>>::iterator it;
it = map.find(event.id); //找到对应ID MMAP;
if (it == map.end())
{
std::multimap<CObject *, CObject *> * newmap;
newmap = new std::multimap<CObject *, CObject *>();
it = map.insert(std::pair<int, std::multimap<CObject *, CObject *>>(event.id, *newmap)).first;
}
it->second.insert(std::pair<CObject *, CObject *>(obj, obj));
}
void CEventsManage::RemoveListener(CEvent event, CObject *obj)
{
std::map<int, std::multimap<CObject *, CObject *>>::iterator it;
it = map.find(event.id); //找到对应ID MMAP;
if (it != map.end())
{
std::multimap<CObject *, CObject *>::iterator muil_it;
muil_it = it->second.find(obj);
if (muil_it != it->second.end())
{
it->second.erase(muil_it);
}
}
}
#include"Obj.h"
#include<stdio.h>
class A : public CObject
{
public:
A()
{
ObjDef(A)
}
virtual void HandleEvent(CSendEvent event){
std::printf("A HandleEvent\n");
};
};
class B : public CObject
{
public:
B()
{
ObjDef(B)
}
virtual void HandleEvent(CSendEvent event){
std::printf("B HandleEvent\n");
};
};
int main()
{
CEvent event1;
event1.id = 1;
A a;
CEventsManage::EventsManage.AddListener(event1, &a);
CSendEvent event2;
event2.id = 1;
CEventsManage::EventsManage.SendEvent(event2);
CEventsManage::EventsManage.RemoveListener(event1, &a);
CEventsManage::EventsManage.SendEvent(event2);
std::printf("%s %x\n",a.GetClassName(),a.GetId());
getchar();
return 0;
}