简单的事件回调机制

来源:互联网 发布:达梦数据库有限公司 编辑:程序博客网 时间:2024/06/11 17:35
简单的事件回调机制
用途:
以回调的形式处理事件,比如:处理按钮点解事件,处理登陆事件等

思路:
1、回调函数形式 std::function<void(Event* e)>
2、回调函数存储 std::unorder_map<std::string, std::function<void(Event* e)>
3、由EventDispatch统一管理所有的回调函数,并负责转发事件
4、所有事件派生自Event类,具体事件处理函数可以这样写:
void DoEvnet2(Event_2* e) {}
注册事件时:
[](Event* e) { Event_2* te = static_caset<Event_2*>(e); DoEvnet2(te);}

定义各种事件参数

#ifndef __EVENT_H__#define __EVENT_H__class Event{public:int a;};class Event1 : public Event{public:int b;};#endif


负责存储事件,并转发事件

#ifndef __EVENT_SYSTEM1_H__#define __EVENT_SYSTEM1_H__#include <string>#include <unordered_map>#include <functional>#include <list>#include "Event.h"using namespace std;class EventDispatch{public: typedef function < void(Event*)> cb;void registEvent(string id, cb _cb);void dispatch(string id, Event* e);protected:unordered_map<string, list<cb>> map_cb;};#endif


#include <algorithm>#include "../include/eventSystem1.h"void EventDispatch::registEvent(string id, cb _cb){auto& list = map_cb[id];list.push_back(_cb);}void EventDispatch::dispatch(string id, Event* e){auto _cb = map_cb.find(id);if (map_cb.end() != _cb){for_each(_cb->second.begin(), _cb->second.end(), [e](const cb& _cb) { _cb(e); });}}

测试代码:
#include "eventSystem1.h"#include <iostream>void onCb(Event* e){cout << "this is onCb " << e->a << endl;}void onCb2(Event1* e){cout << "this is onCb2" << e->b << endl;}static const string event1 = "EVENT1";static const string event2 = "EVENT2";int _tmain(int argc, _TCHAR* argv[]){EventDispatch dispatch;dispatch.registEvent(event1, onCb);dispatch.registEvent(event2, [](Event* e){Event1* e1 = static_cast<Event1*>(e);onCb2(e1);});Event e;Event1 e1;e.a = 1;e1.b = 20;dispatch.dispatch(event1, &e);dispatch.dispatch(event2, &e1);return 0;}

缺点:
1、无法实现撤销监听
2、当被监听对象析构后,无法及时撤销监听
3、无法监听统一类型的不同对象,如:无法分别监听两个按钮的点击事件,因为无法识别是哪一个按钮发出的事件。

0 0