轻量事件总线(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;
}
posted @ 2021-06-13 10:11  一花一世界,一叶一乾坤  阅读(487)  评论(0编辑  收藏  举报