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


这个里面做的事情很简单

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

并有一个存储事件数据的结构体  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:

	// 事件发生的时候被调用, 如果事件被成功处理则返回 true
	virtual bool OnEvent(SEvent event) = 0;
};



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

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

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



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

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

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

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

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

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

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

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

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




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

Irrlicht 源码学习笔记 【IEventReceiver.h】_第1张图片


你可能感兴趣的:(Irrlicht)