HazelEngine 学习记录 - Window Events

Window Events

本节主要是将我们在 window 中的各种操作产生的 Events dispatch之后通过 log 显示出来

我们先观察一个窗口是如何被创建出来的:

int main(int argc, char** argv) 
{
	Hazel::Log::Init();
	HZ_CORE_WARN("Initialized Log");
	int a = 5;
	HZ_INFO("Hello! Var={0}", a);
	auto app = Hazel::CreateApplication();  //调用 CreateApplication 函数
	app->Run();
	delete app;
}

CreateAplication 做了什么呢?我们转到该函数,发现在函数中创建了 SandBox 的对象,并返回了Application 类型的指针,该对象继承自 Application 类,因此可以通过该指针调用类中的方法,然后观察 Application 的结构

namespace Hazel{
	class HAZEL_API Application
	{

	public:
		Application();
		virtual ~Application();

		void Run();
		void OnEvent(Event& e);   //用于各种事件
	private:
		bool OnWindowClose(WindowCloseEvent& e);  //用于关闭窗口
		std::unique_ptr<Window> m_Window; //显示的窗口
		bool m_Running = true ; //运行状态的控制
	};
	//To be defined in Client
	Application* CreateApplication();

}

构造函数中,我们初始化了 window 并且设置了事件的 callback

		m_Window = std::unique_ptr<Window>(Window::Create());
		m_Window->SetEventCallback(BIND_EVENT_FN(OnEvent));

window::Create 函数创建了一个 GLFW 窗口,并进行了一系列初始化,具体内容可以参照上一节 windowswindow 的内容,然后调用了EventCallback 来进行事件的 dispatch,这里 BIND 宏进行了如下定义:

#define BIND_EVENT_FN(x) std::bind(&Application::x, this, std::placeholders::_1) // Returns a function object based on fn(Application::x), but with its arguments bound to args(this,_1).

然后函数 OnEvent 定义如下:

	void Application::OnEvent(Event& e)
	{
		EventDispatcher dispatcher(e);
		dispatcher.Dispatch<WindowCloseEvent>(BIND_EVENT_FN(OnWindowClose)); //控制窗口关闭
		HZ_CORE_INFO("{0}", e);   //Get Core logger
	}

这里的作用就是根据我们产生的事件 e,来进行 dispatch,从而通过 log 进行显示

在 main 函数中我们调用了 Run 函数,

void Application::Run()
	{
		while (m_Running)
		{
			glClearColor(1, 0, 1, 1);
			glClear(GL_COLOR_BUFFER_BIT);
			m_Window->OnUpdate();
		}
	}

利用 glfw 的函数对窗口进行初始化,并开始渲染窗口

这时候窗口能够正常显示了

在这里插入图片描述

之后我们需要将在窗口中进行操作产生的事件显示出来,在 windowsWindow 中添加各种 EventCallback

//Set GLFW callbacks
		glfwSetWindowSizeCallback(m_Window, [](GLFWwindow* window, int width, int height)
			{
				WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window);

				data.Width = width;    //shoud be initialized first
				data.Height = height;

				WindowResizeEvent event(width, height);  //renturn a Event instance
				data.EventCallback(event);  //translate event instance to func pointer and dispatch event

			}
		);

		glfwSetWindowCloseCallback(m_Window, [](GLFWwindow* window)
			{
				WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window);
				WindowCloseEvent event;
				data.EventCallback(event);
			}
		);

		glfwSetKeyCallback(m_Window, [](GLFWwindow* window, int key, int scancode, int action, int mods)
			{
				WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window);

				switch (action)
				{
					case GLFW_PRESS:
					{
						KeyPressedEvent event(key, 0);
						data.EventCallback(event);
						break;
					}
					case GLFW_RELEASE:
					{
						KeyRelseasedEvent event(key);
						data.EventCallback(event);
						break;
					}
					case GLFW_REPEAT:
					{
						KeyPressedEvent event(key, 1);
						data.EventCallback(event);
						break;
					}
				}
			}
		);

		glfwSetMouseButtonCallback(m_Window, [](GLFWwindow* window, int button, int action, int mods)
			{
				WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window);

				switch (action)
				{
					case GLFW_PRESS:
					{
						MouseButtonPressedEvent event(button);
						data.EventCallback(event);
						break;
					}
					case GLFW_RELEASE:
					{
						MouseButtonReleasedEvent event(button);
						data.EventCallback(event);
						break;
					}
				}
			}
		);

		glfwSetScrollCallback(m_Window, [](GLFWwindow* window, double xOffset, double yOffset)
			{
				WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window);

				MouseScrolledEvent event((float)xOffset, (float)yOffset);
				data.EventCallback(event);
			}
		);

		glfwSetCursorPosCallback(m_Window, [](GLFWwindow* window, double xPos, double yPos)
			{
				WindowData& data = *(WindowData*)glfwGetWindowUserPointer(window);

				MouseMoveEvent event((float)xPos, (float)yPos);
				data.EventCallback(event);
			}
		);

最后为了关闭窗口,我们必须在收到 WindowClose Event 之后修改 running 的状态

	bool Application::OnWindowClose(WindowCloseEvent& e)
	{
		m_Running = false;
		return true;
	}

然后再次运行窗口,在我们进行操作的时候,就可以在控制台中显示当前的事件啦

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值