TheCherno——Engine(五)
事件系统计划Application中可以了解Window的所有信息在Application的构造函数中就可以创建一个Window类Window中监测事件的发生若事件发生有相应的回调函数响应在回调函数中会根据相应的事件信息创建相应的事件类例如鼠标点击事件发生那么创建一个鼠标点击事件类类中应有鼠标点击的位置和点击的鼠标键这些数据回调函数中还会将这个事件类作为Application中OnEvent函数的参数这样就可以将事件传回到Application而Window可以不对Application有所认识。这里先完成事件系统其实就是事件抽象类和它一系列的基类。在DTClass下建立Events文件夹DTClass-src-DTClass-Events其中Event.h#pragma once #include DTClass/Core.h #include string #include functional namespace DTC { ///////////////////////////////////////////////////////////////////////// //事件类型 //enum class具有强作用域枚举值需要使用作用域运算符来访问。如EventType::WindowClose enum class EventType { None 0, WindowClose, WindowResize, WindowFocus, WindowLostFocus, WindowMoved,//窗口事件 AppTick, AppUpdate, AppRender, KeyPressed, KeyReleased, KeyTyped, //键盘事件 MouseButtonPressed, MouseButtonReleased, MouseMoved, MouseScrolled //鼠标事件 }; ///////////////////////////////////////////////////////////////////////// //事件分类 enum EventCategory { None 0, EventCategoryApplication BIT(0), EventCategoryInput BIT(1), EventCategoryKeyboard BIT(2), EventCategoryMouse BIT(3), EventCategoryMouseButton BIT(4) }; ///////////////////////////////////////////////////////////////////////// // 宏定义 //##type 是一个预处理器操作符用于将 type 转换为 EventType 枚举中的相应值。 //#type 是一个字符串化操作符它将 type 变成字符串 //事件基类的改写~ #define EVENT_CLASS_TYPE(type) static EventType GetStaticType(){return EventType::##type; }\ virtual EventType GetEventType() const override {return GetStaticType();}\ virtual const char* GetName() const override {return #type;} #define EVENT_CLASS_CATEGORY(category) virtual int GetCategoryFlags() const override {return category; } ///////////////////////////////////////////////////////////////////////// //事件基类 class Event { public: virtual EventType GetEventType() const 0;//获得该事件的具体类型 virtual const char* GetName() const 0;//获得事件的名称 virtual int GetCategoryFlags() const 0;//获得该事件的类别 virtual std::string ToString() const { return GetName(); }//ToString方法返回事件名 inline bool IsInCategory(EventCategory category) //判断该事件是否是category类 { return GetCategoryFlags() category; } public: bool m_Handled false;//事件是否被处理 }; ///////////////////////////////////////////////////////////////////////// // 事件拦截器 class EventDispatcher { template typename T using EventFn std::functionbool(T);//EventFn:接收一个T类型的参数并返回一个 bool 类型的结果 public: EventDispatcher(Event event) :m_Event(event) { } template typename T bool Dispatch(EventFnT func) { if (m_Event.GetEventType() T::GetStaticType()) { m_Event.m_Handled func(*(T*)m_Event); //事件处理 return true; } return false; } private: Event m_Event; }; ///////////////////////////////////////////////////////////////////////// //方便日志输出 inline std::ostream operator(std::ostream os, const Event e) { return os e.ToString(); } }MouseEvent.h#pragma once #include Event.h #include sstream namespace DTC { //鼠标事件鼠标移动 class DTC_API MouseMovedEvent : public Event { public: MouseMovedEvent(float x, float y) : m_MouseX(x), m_MouseY(y) {} inline float GetX() const { return m_MouseX; } inline float GetY() const { return m_MouseY; } std::string ToString() const override { std::stringstream ss; ss 鼠标移动事件: m_MouseX , m_MouseY; return ss.str(); } EVENT_CLASS_TYPE(MouseMoved) EVENT_CLASS_CATEGORY(EventCategoryMouse | EventCategoryInput) //类别鼠标事件和输入事件 private: float m_MouseX, m_MouseY; }; //////////////////////////////////////////////////////////////////////// //鼠标事件鼠标滚轮滚动 class DTC_API MouseScrolledEvent : public Event { public: MouseScrolledEvent(float xOffset, float yOffset) :m_XOffset(xOffset), m_YOffset(yOffset) {} inline float GetXOffset() const { return m_XOffset; } inline float GetYOffset() const { return m_YOffset; } std::string ToString() const override { std::stringstream ss; ss 鼠标滚动事件: GetXOffset() , GetYOffset(); return ss.str(); } EVENT_CLASS_TYPE(MouseScrolled) EVENT_CLASS_CATEGORY(EventCategoryMouse | EventCategoryInput) //类别鼠标事件和输入事件 private: float m_XOffset, m_YOffset; }; //////////////////////////////////////////////////////////////////////// //基类只包括一个鼠标键信息 class DTC_API MouseButtonEvent : public Event { public: inline int GetMouseButton() const { return m_Button; } //返回键值 EVENT_CLASS_CATEGORY(EventCategoryMouse | EventCategoryInput)//类别鼠标事件和输入事件 protected: MouseButtonEvent(int button) :m_Button(button) {} int m_Button; }; //////////////////////////////////////////////////////////////////////// //鼠标事件某鼠标键被按下 class DTC_API MouseButtonPressedEvent : public MouseButtonEvent { public: MouseButtonPressedEvent(int button) : MouseButtonEvent(button) {} std::string ToString() const override { std::stringstream ss; ss 鼠标键按下事件: m_Button; return ss.str(); } EVENT_CLASS_TYPE(MouseButtonPressed) }; //////////////////////////////////////////////////////////////////////// //鼠标事件某鼠标键被释放 class DTC_API MouseButtonReleasedEvent : public MouseButtonEvent { public: MouseButtonReleasedEvent(int button) : MouseButtonEvent(button) {} std::string ToString() const override { std::stringstream ss; ss 鼠标键释放事件: m_Button; return ss.str(); } EVENT_CLASS_TYPE(MouseButtonReleased) }; }KeyEvent.h#pragma once #include Event.h #include sstream namespace DTC { //KeyEvent 键盘事件 继承自Event //也是基类只包括一个按键信息 class DTC_API KeyEvent : public Event { public: inline int GetKeyCode() const { return m_KeyCode; } //返回键值 EVENT_CLASS_CATEGORY(EventCategoryKeyboard | EventCategoryInput) //类别键盘事件和输入事件 protected: //protected只能由它的派生类创建 KeyEvent(int keycode) : m_KeyCode(keycode) {} //构造函数 int m_KeyCode; //键盘事件的键码 }; //////////////////////////////////////////////////////////////////////// //键盘事件键被按下 class DTC_API KeyPressedEvent : public KeyEvent { public: KeyPressedEvent(int keycode, int repeatCount) :KeyEvent(keycode), m_RepeatCount(repeatCount) {} inline int GetRepeatCount() const { return m_RepeatCount; } std::string ToString() const override { std::stringstream ss; ss 键盘按下事件: m_KeyCode ( m_RepeatCount 次重复); return ss.str(); } EVENT_CLASS_TYPE(KeyPressed) private: int m_RepeatCount; //重复次数 }; //////////////////////////////////////////////////////////////////////// //键盘事件键被释放 class DTC_API KeyReleasedEvent : public KeyEvent { public: KeyReleasedEvent(int keycode) : KeyEvent(keycode) {} std::string ToString() const override { std::stringstream ss; ss 键盘释放事件: m_KeyCode; return ss.str(); } EVENT_CLASS_TYPE(KeyReleased) }; //////////////////////////////////////////////////////////////////////// class DTC_API KeyTypedEvent :public KeyEvent { public: KeyTypedEvent(int keycode) :KeyEvent(keycode) { } std::string ToString()const override { std::stringstream ss; ss 键盘类型事件 m_KeyCode; return ss.str(); } EVENT_CLASS_TYPE(KeyTyped) }; }ApplicationEvent.h#pragma once #include Event.h #include sstream namespace DTC { //窗口事件窗口大小改变 class DTC_API WindowResizeEvent : public Event { public: WindowResizeEvent(unsigned int width, unsigned int height) :m_Width(width), m_Height(height) {} //构造函数 inline unsigned int GetWidth() const { return m_Width; } inline unsigned int GetHeight() const { return m_Height; } std::string ToString() const override { std::stringstream ss; ss 窗口大小改变事件: m_Width , m_Height; return ss.str(); } EVENT_CLASS_TYPE(WindowResize) EVENT_CLASS_CATEGORY(EventCategoryApplication) private: unsigned int m_Width, m_Height; }; //////////////////////////////////////////////////////////////////////// //窗口事件窗口关闭 class DTC_API WindowCloseEvent : public Event { public: WindowCloseEvent() {} EVENT_CLASS_TYPE(WindowClose) EVENT_CLASS_CATEGORY(EventCategoryApplication) }; //////////////////////////////////////////////////////////////////////// class DTC_API AppTickEvent :public Event { public: AppTickEvent() {} EVENT_CLASS_TYPE(AppTick) EVENT_CLASS_CATEGORY(EventCategoryApplication) }; //////////////////////////////////////////////////////////////////////// class DTC_API AppUpdateEvent :public Event { public: AppUpdateEvent() {} EVENT_CLASS_TYPE(AppUpdate) EVENT_CLASS_CATEGORY(EventCategoryApplication) }; //////////////////////////////////////////////////////////////////////// class DTC_API AppRenderEvent :public Event { public: AppRenderEvent() {} EVENT_CLASS_TYPE(AppRender) EVENT_CLASS_CATEGORY(EventCategoryApplication) }; }测试事件系统在Application.h 中添加 #include Events/ApplicationEvent.h#pragma once #include Core.h #include Events/ApplicationEvent.h namespace DTC { class DTC_API Application { public: Application(); virtual ~Application(); void Run(); }; Application* CreateApplication(); //函数CreateApplication的声明 }Application.cpp中#include Application.h #include DTClass/Events/ApplicationEvent.h #include DTClass/Log.h #include spdlog/fmt/ostr.h namespace DTC { Application::Application(){} Application::~Application(){} void Application::Run() { WindowResizeEvent e(1280, 720); //创建事件窗口大小改变事件 if (e.IsInCategory(EventCategoryApplication)) { DTC_CORE_WARN(e); } while(true){} } }输出结果为还在premake配置DTClass中
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2592571.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!