Irrlicht 源码学习笔记 【IEventReceiver.h】

来源:互联网 发布:手机版淘宝盗图技巧 编辑:程序博客网 时间:2024/06/07 12:44


这个里面做的事情很简单

使用枚举对游戏中事件进行了分类

并有一个存储事件数据的结构体  AND  一个处理事件的接口


【Irrlicht 中枚举体和结构体的命名规范】

枚举类型命名以 'E' 打头,表示 Enum

枚举中每一个元素以 ‘E’ + 枚举体名下划线分割的每个单词首字母拼接 打头

比如枚举体 EEVENT_TYPE 中每一个元素都以 EET 开头


结构体类型命名以 'S' 打头, 表示 Struct

这些也是非常常用的命名规范

(但是 联合体union 好像没有遵循类似的规则)



【EEVENT_TYPE】

枚举了 Irrlicht 中的事件类型

Irrlicht 中事件分三种 : GUI事件 AND 鼠标输入事件 AND  键盘输入事件

enum EEVENT_TYPE{EET_GUI_EVENT = 0, // GUI 事件EET_MOUSE_INPUT_EVENT, // 鼠标输入事件EET_KEY_INPUT_EVENT // 键盘输入事件};




【EMOUSE_INPUT_EVENT】

进一步枚举了鼠标输入事件中更具体的事件类型

这里枚举了七个最常用的鼠标事件类型

分别对应 "左键", "右键", "中键" 的 "按下", "抬起" 事件   AND   鼠标移动事件

enum EMOUSE_INPUT_EVENT{EMIE_LMOUSE_PRESSED_DOWN = 0, // 左键按下EMIE_RMOUSE_PRESSED_DOWN, // 右键按下EMIE_MMOUSE_PRESSED_DOWN, // 中键按下EMIE_LMOUSE_LEFT_UP, // 中键抬起EMIE_RMOUSE_LEFT_UP, // 右键按下EMIE_MMOUSE_LEFT_UP, // 右键抬起EMIE_MOUSE_MOVED // 鼠标移动};



【EGUI_EVENT_TYPE】

枚举了GUI系统中用到的一些事件

具体的事件类型我已经在下面代码中添加好了注释

enum EGUI_EVENT_TYPE{EGET_ELEMENT_KEY_FOCUS_LOST = 0, // 键盘按键焦点丢失EGET_ELEMENT_MOUSE_FOCUS_LOST, // 鼠标指针焦点丢失EGET_ELEMENT_HOVERED, // 鼠标指针悬停EGET_BUTTON_CLICKED, // 鼠标按键点击EGET_SCROLL_BAR_CHANGED, // 滚动条改变EGET_CHECKBOX_CHANGED, // 复选框状态改变EGET_LISTBOX_CHANGED,  // 列表框列表选项内容改变EGET_LISTBOX_SELECTED_AGAIN,  // 列表框中已经选中的选项被再次选中};



这三个枚举将 Irrlicht 中的事件进行了枚举

后面的事件记录结构以及事件处理接口将根据它们对事件进行解析

其实这些事件定义本身是不够全面的

但是其中囊括的大都十分常用,而且也是容易扩充的,所以也足够了




【SEvent】

记录事件数据的结构体

因为具体的事件分为三类且是独立出现不会重合的

所以用 联合体并分别定义了记录三种事件信息的结构,可以减小存储空间


使用一个EEVENT_TYPE 记录事件类型

可以根据 EVENT_TYPE 判断要以union中的哪一个结构解析数据

struct SEvent{EEVENT_TYPE EventType;union{struct // GUI事件数据{gui::IGUIElement* Caller; // 发送该事件的控件gui::EGUI_EVENT_TYPE EventType; // 事件的类型} GUIEvent;struct // 鼠标输入数据{s32 X, Y; // 鼠标在事件发生时的坐标EMOUSE_INPUT_EVENT Event; // 鼠标事件的类型} MouseInput;struct // 键盘输入数据{s32 Key; // 发生该事件的按键bool PressedDown; // 只有按下和非按下两个状态, true - 按下事件, false - 抬起事件} KeyInput;};};



【IEventReceiver】

接口以 ‘I’ 开头, 但是 C++ 标准关键字里没有 interface (接口)

所以使用一个 IEventReceiver 基类, 里面只有一个用来处理事件的纯虚函数

子类继承自 IEventReceiver 并实现 OnEvent 来处理事件

class IEventReceiver{public:// 事件发生的时候被调用, 如果事件被成功处理则返回 truevirtual bool OnEvent(SEvent event) = 0;};



这些就是 IEventReceiver 中对事件的定义以及记录和处理的方法

个人觉得 Irrlicht 中对文件的划分还是阔以的

(所有相关的内容放在一个文件里对读的人来说也是一种爱 ヘ(_ _ヘ)  )



//////////////////////////////////////////  废话 buff 开始  ////////////////////////////////////////// 

我自己刚开始做小游戏的时候根本没有对事件进行这么清晰的定义

更多的时候只是做一个全局的消息分发者,然后发送消息,调用函数

但是后来渐渐发现,有一些事情处理起来的时候不禁叫人 "头皮发麻" 后 "呵呵一笑"

比如 使用消息分发队列来控制消息合并等行为

比如 有一个事件需要改变参数

比如 要增加或者删除一个事件类型

所以对事件系统进行良好的定义是很有必要的

//////////////////////////////////////////  废话 buff 结束  ////////////////////////////////////////// 




今天失恋了,发一张不开心的图片 (づ╥﹏╥)づ