当前位置: 首页 > article >正文

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中

相关文章:

TheCherno——Engine(五)

事件系统计划:Application中可以了解Window的所有信息,在Application的构造函数中,就可以创建一个Window类;Window中监测事件的发生,若事件发生,有相应的回调函数响应;在回调函数中,…...

Ryujinx深度解析:从架构设计到性能调优的任天堂Switch模拟器实战指南

Ryujinx深度解析:从架构设计到性能调优的任天堂Switch模拟器实战指南 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx Ryujinx作为用C#编写的开源Nintendo Switch模拟器&…...

2026数据科学技术趋势全解析:新兴领域与高效学习路径指南

2026数据科学技术趋势全解析:新兴领域与高效学习路径指南 【免费下载链接】data-science 📊 Path to a free self-taught education in Data Science! 项目地址: https://gitcode.com/gh_mirrors/da/data-science GitHub 加速计划 / da / data-sc…...

为内部知识库问答工具集成 Taotoken 提供的多模型检索增强

为内部知识库问答工具集成 Taotoken 提供的多模型检索增强 在企业知识管理实践中,内部知识库问答工具是提升信息流转效率的关键。然而,单一模型在应对复杂、专业或需要多角度推理的查询时,其回答质量可能受限。通过集成 Taotoken 平台&#…...

明日方舟游戏资源库:你的终极素材宝库与创作指南

明日方舟游戏资源库:你的终极素材宝库与创作指南 【免费下载链接】ArknightsGameResource 明日方舟客户端素材 项目地址: https://gitcode.com/gh_mirrors/ar/ArknightsGameResource 还在为寻找高质量的明日方舟游戏素材而苦恼吗?想要获取高清角色…...

AI执行契约:结构化协作框架,提升AI产品构建效率与确定性

1. 项目概述:从灵感到成品的AI驱动产品构建框架如果你和我一样,经常使用 Cursor、Claude 或 ChatGPT 来辅助构建产品原型或功能,那你一定经历过这样的场景:你有一个绝佳的想法,兴冲冲地打开 AI 对话窗口,开…...

将 Taotoken 配置为 Claude Code 编程助手的自定义模型提供商

将 Taotoken 配置为 Claude Code 编程助手的自定义模型提供商 Claude Code 是一款专注于代码生成与编程辅助的 AI 工具,它支持通过自定义配置连接到不同的模型服务。对于希望统一管理多个模型调用、并希望获得稳定计费与用量观测的开发者而言,将 Taotok…...

基于提示词工程的AI智慧日报系统:零代码实现跨文化历史故事生成

1. 项目概述:一个永不重复的AI智慧日报系统每天早晨,当大多数人还在与闹钟挣扎时,我已经习惯性地打开手机,期待一份独特的“精神早餐”。它不是来自某个新闻客户端,也不是来自社交媒体的信息流,而是一段由A…...

开源ChatGPT WebUI:自托管部署、核心功能与安全实践全解析

1. 项目概述:一个开源ChatGPT WebUI的诞生与价值最近在GitHub上看到一个名为“HemulGM/ChatGPT”的项目,点进去一看,发现这是一个基于Web的ChatGPT用户界面。作为一个长期关注AI应用落地的开发者,我立刻来了兴趣。这不仅仅是一个简…...

ComfyUI-OpenClaw:为AI工作流注入安全灵魂的自动化控制层

1. 项目概述:ComfyUI-OpenClaw,一个为AI工作流注入“安全灵魂”的自动化控制层如果你和我一样,长期在本地折腾Stable Diffusion和ComfyUI,肯定遇到过这样的困境:想用AI辅助生成提示词,得手动切到另一个网页…...

为AI工具协议MCP构建零信任安全代理:从OAuth到RBAC的实战指南

1. 项目概述:为AI工具协议筑起安全围墙最近在折腾AI Agent的开发,发现一个挺有意思但容易被忽视的安全问题。我们都在用Claude、Cursor、Copilot这些工具,它们背后连接各种数据源和服务,靠的是一个叫MCP(Model Context…...

OpenRelay:本地AI代理聚合工具,统一调度Claude、Cursor等多平台订阅与API

1. 项目概述:打破AI订阅的孤岛如果你和我一样,每天要在Claude Desktop、Cursor、Aider、Goose这些AI工具之间来回切换,那你一定深有体会:每个工具的订阅配额都是独立的“信息孤岛”。Claude Pro的额度只能在Claude官方客户端里用&…...

Cursor AI 效率革命:MCP.json 构建器与开源工具站实战指南

1. 项目概述:一个为 Cursor AI 用户打造的“百宝箱” 如果你和我一样,日常重度依赖 Cursor 这款 AI 驱动的代码编辑器,那你肯定遇到过这样的场景:想快速接入一个外部数据源,比如查查 AWS 文档,或者调用下 …...

如何快速开发车牌识别新特征?EasyPR模板工具让你5分钟上手

如何快速开发车牌识别新特征?EasyPR模板工具让你5分钟上手 【免费下载链接】EasyPR (CGCSTCD2017) An easy, flexible, and accurate plate recognition project for Chinese licenses in unconstrained situations. CGCSTCD China Graduate Contest on Smart-city…...

AI Agent技能开发实战:逆向工程赋能餐厅搜索自动化

1. 项目概述:一个为AI助手赋能的餐厅搜索技能 如果你在以色列生活或旅行,想在Ontopo这个主流餐厅预订平台上找个好位子,大概率经历过这样的折磨:打开网站或App,选好餐厅,点开日历,一天一天地往…...

如何用MobileSAM与Inpaint-Anything实现高效图像修复:完整实战指南

如何用MobileSAM与Inpaint-Anything实现高效图像修复:完整实战指南 【免费下载链接】MobileSAM This is the official code for MobileSAM project that makes SAM lightweight for mobile applications and beyond! 项目地址: https://gitcode.com/gh_mirrors/mo…...

3分钟上手ChanlunX:零基础实现缠论自动化分析的终极方案

3分钟上手ChanlunX:零基础实现缠论自动化分析的终极方案 【免费下载链接】ChanlunX 缠中说禅炒股缠论可视化插件 项目地址: https://gitcode.com/gh_mirrors/ch/ChanlunX 你是否还在为复杂的缠论分析而头疼?面对K线图上密密麻麻的走势&#xff0c…...

Honey Select 2强力汉化补丁:3步实现游戏完全中文化

Honey Select 2强力汉化补丁:3步实现游戏完全中文化 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 还在为Honey Select 2的日语界面感到困扰吗&…...

如何在CI/CD中集成Flow:提升JavaScript代码质量的完整指南

如何在CI/CD中集成Flow:提升JavaScript代码质量的完整指南 【免费下载链接】flow Adds static typing to JavaScript to improve developer productivity and code quality. 项目地址: https://gitcode.com/gh_mirrors/flow30/flow Flow是一个为JavaScript添…...

在Node.js后端服务中集成多模型API实现智能对话功能

在Node.js后端服务中集成多模型API实现智能对话功能 为产品添加智能对话能力已成为提升用户体验的关键路径。对于Node.js开发者而言,直接对接单一模型厂商的API虽然直接,但往往面临模型选择固定、服务稳定性依赖单一供应商、以及密钥与计费管理分散等工…...

AI应用开发利器:基于Docker Compose的一体化本地部署方案

1. 项目概述:一个为AI应用量身定制的“开箱即用”工具箱最近在折腾一些AI相关的本地化部署和实验,发现一个挺普遍的问题:每次想跑个新模型或者搭个实验环境,都得花大量时间在环境配置、依赖安装和基础服务搭建上。从Python版本冲突…...

Vim插件备份恢复终极指南:Vundle.vim确保配置永不丢失

Vim插件备份恢复终极指南:Vundle.vim确保配置永不丢失 【免费下载链接】Vundle.vim Vundle, the plug-in manager for Vim 项目地址: https://gitcode.com/gh_mirrors/vu/Vundle.vim Vundle.vim作为Vim的插件管理器,不仅能帮助用户轻松管理各类插…...

8线程Python网站离线下载器:打造你的永久数字档案库

8线程Python网站离线下载器:打造你的永久数字档案库 【免费下载链接】WebSite-Downloader 项目地址: https://gitcode.com/gh_mirrors/web/WebSite-Downloader WebSite-Downloader是一款基于Python开发的高效网站离线下载工具,能够将整个网站完整…...

解放你的耳朵:用Open-Lyrics为任何音频生成精准字幕

解放你的耳朵:用Open-Lyrics为任何音频生成精准字幕 【免费下载链接】openlrc Transcribe and translate voice into LRC file using Whisper and LLMs (GPT, Claude, et,al). 使用whisper和LLM(GPT,Claude等)来转录、翻译你的音频为字幕文件。 项目地…...

保姆级教程:解决ORB-SLAM2_with_pointcloud_map编译报错(PCL版本冲突、段错误闪退)

ORB-SLAM2点云地图构建实战:从编译报错到稳定运行的完整指南 在三维视觉SLAM领域,ORB-SLAM2因其出色的实时性和鲁棒性成为众多研究者和开发者的首选框架。但当我们将目光投向更具实用价值的稠密点云地图构建时,高翔博士的ORB-SLAM2_with_poin…...

CookieCutter扩展开发终极指南:自定义Jinja2过滤器与函数

CookieCutter扩展开发终极指南:自定义Jinja2过滤器与函数 【免费下载链接】cookiecutter A cross-platform command-line utility that creates projects from cookiecutters (project templates), e.g. Python package projects, C projects. 项目地址: https://…...

3步解锁HS2完整体验:专业汉化补丁终极指南

3步解锁HS2完整体验:专业汉化补丁终极指南 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 还在为Honey Select 2的日文界面感到困惑?HS2…...

独立开发者如何利用Taotoken构建具备多模型切换能力的AI应用

独立开发者如何利用Taotoken构建具备多模型切换能力的AI应用 对于独立开发者而言,在小型应用中集成AI功能时,常常面临一个核心矛盾:既要提供稳定、强大的智能能力,又要控制成本并适应不同用户的偏好。直接对接单一模型供应商&…...

Flink实时数据处理终极指南:从零构建企业级流处理系统

Flink实时数据处理终极指南:从零构建企业级流处理系统 【免费下载链接】InterviewGuide 🔥🔥「InterviewGuide」是阿秀从校园->职场多年计算机自学过程的记录以及学弟学妹们计算机校招&秋招经验总结文章的汇总,包括但不限于…...

5步在PC上运行任天堂Switch游戏:Ryujinx模拟器完全指南

5步在PC上运行任天堂Switch游戏:Ryujinx模拟器完全指南 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 想在电脑上畅玩《塞尔达传说:王国之泪》,却不…...