轻量事件总线(EventBusLite)
轻量事件总线(EventBusLite)
EventBusLite是一个简单的C++事件回调实现,通过使用(void**)来传递任意数据。
在面对复杂的通用数据处理时,我们一般都使用高级语言功能来解决问题。
EventBusLite试图简化这些,当放弃那些高级功能时,代码简洁、优雅!
EventBusLite.h
#ifndef __YY_EVENT_BUS_LITE_H__
#define __YY_EVENT_BUS_LITE_H__
/*
* Lightweight event bus
*
* history:
* 2021-06-13 yao yu created
* add class functor handler
*/
#include <map>
#include <list>
typedef void (*EventCB)(int msgid, void **pUser);
struct Observer
{
virtual void operator()(int msgid, void **pUser) = 0;
};
struct EventBusLite
{
bool attach(int msgid, EventCB callback);
bool attach(int msgid, Observer *functor);
bool detach(int msgid, EventCB callback);
bool detach(int msgid, Observer *functor);
void notify(int msgid, void **pUser);
private:
std::map<int, std::list<EventCB>> m_events_map;
std::map<int, std::list<Observer *>> m_functor_map;
};
/*
* global event bus
*/
bool ge_attach(int msgid, EventCB callback);
bool ge_detach(int msgid, EventCB callback);
bool ge_attach(int msgid, Observer *functor);
bool ge_detach(int msgid, Observer *functor);
void ge_notify(int msgid, void **pUser);
#endif //#ifndef __YY_EVENT_BUS_LITE_H__
EventBusLite.cpp
/*
* Lightweight event bus
*
* history:
* 2021-06-13 yao yu created
*/
#include "EventBusLite.h"
// global event bus define
static EventBusLite s_event_bus;
/*
* event bus implement
*/
inline bool EventBusLite::attach(int msgid, EventCB callback)
{
auto it = m_events_map.find(msgid);
if (it == m_events_map.end())
{
m_events_map[msgid] = std::list<EventCB>();
}
m_events_map[msgid].push_back(callback);
return true;
}
inline bool EventBusLite::detach(int msgid, EventCB callback)
{
auto it = m_events_map.find(msgid);
if (it != m_events_map.end())
{
it->second.remove(callback);
return true;
}
return false;
}
inline bool EventBusLite::attach(int msgid, Observer *functor)
{
auto it = m_functor_map.find(msgid);
if (it == m_functor_map.end())
{
m_functor_map[msgid] = std::list<Observer *>();
}
m_functor_map[msgid].push_back(functor);
return true;
}
inline bool EventBusLite::detach(int msgid, Observer *functor)
{
auto it = m_functor_map.find(msgid);
if (it != m_functor_map.end())
{
it->second.remove(functor);
return true;
}
return false;
}
inline void EventBusLite::notify(int msgid, void **pUser)
{
auto it = m_events_map.find(msgid);
if (it != m_events_map.end())
{
for (auto cb : it->second)
{
cb(msgid, pUser);
}
}
auto it2 = m_functor_map.find(msgid);
if (it2 != m_functor_map.end())
{
for (auto cb : it2->second)
{
(*cb)(msgid, pUser);
}
}
}
/*
* global event bus implement
*/
bool ge_attach(int msgid, EventCB callback)
{
return s_event_bus.attach(msgid, callback);
}
bool ge_detach(int msgid, EventCB callback)
{
return s_event_bus.detach(msgid, callback);
}
bool ge_attach(int msgid, Observer *functor)
{
return s_event_bus.attach(msgid, functor);
}
bool ge_detach(int msgid, Observer *functor)
{
return s_event_bus.detach(msgid, functor);
}
void ge_notify(int msgid, void **pUser)
{
return s_event_bus.notify(msgid, pUser);
}
main.cpp测试
#include <iostream>
#include "EventBusLite.h"
using namespace std;
struct Functor : public Observer
{
void operator()(int msgid, void **pUser)
{
int **data = (int **)pUser;
cout << "functor.operator() :" << msgid << " user data: " << **data << endl;
++(**data);
}
};
void handler(int msgid, void **pUser)
{
int **data = (int **)pUser;
cout << "handler :" << msgid << " user data: " << **data << endl;
**data = 20;
}
int main(int argc, char *argv[])
{
int a = 1;
int *pa = &a;
ge_attach(1, handler);
ge_notify(1, (void **)(&pa));
cout << "after " << a << endl;
ge_detach(1, handler);
a = 30;
Functor functor;
ge_attach(1, &functor);
ge_notify(1, (void **)(&pa));
cout << "after class functor " << a << endl;
return 0;
}