| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 游戏开发 -> <2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvTools(四)—— Utils(上) -> 正文阅读 |
|
[游戏开发]<2021SC@SDUSC> 开源游戏引擎 Overload 代码模块分析 之 OvTools(四)—— Utils(上) |
<2021SC@SDUSC> 前言本篇是开源游戏引擎 Overload 模块 OvTools 的第四篇分析,想大致了解 Overload 可前往这篇文章,想看其他相关文章请前往笔者的 Overload 专栏自主选择。 本篇将探究 OvTools 的最后一个小模块:Utils,我们先来大致了解其文件有哪些并计划一下探究进程吧! Utils 模块概述与探究计划Utils 模块是多种工具(例如随机数生成、系统调用等)的集合,其包含文件如下: 分析1、PathParser1.1 PathParser.h1.1.1 头文件该文件仅包含了一个 string 头文件,不多赘述:
1.1.2 主体代码该文件的主体代码是一个 PathParser 类及其函数定义,该类的作用是提供一些工具来获得给出路径的相关信息,代码如下:
构造函数默认删除,之前的文章已讲述过;其他函数的作用已有英文注释,不多赘述;代码定义了类变量 EFileType,内含以文件功能分类的文件类型名(如模型 MODEL、纹理 TEXTURE 等),并用 enum 关键词限定,表示仅能从类内给出的值中选择返回。 由此可以看出,该类可以处理判断路径指向文件的功能类型或以需求的方式(例如更改为 Windows 格式等)输出等,具体实现方式让我们看看 PathParser.cpp 文件: 1.2 PathParser.cpp1.2.1 头文件
除了包含 PathParser.h 文件外,还包含了 algorithm,该头文件属于 C++ 标准库,能提供多种算法函数,例如常用的 sort(),stable_sort(),partical_sort(),nth_element() 等等。 1.2.2 主体代码主体代码都是函数具体定义,让我们一个个看: MakeWindowsStyle() 函数
该函数通过 resize 函数定义 result 字符串长度为路径长度,而后用一个三目运算符依次将路径中的 “ / ” 改为 “ \ ” —— 符合 Windows 系统的路径格式 —— 同时赋值 result 返回。简单一提,for 循环中 i 的类型 size_t 重命名前为 unsigned __int64。 MakeNonWindowsStyle() 函数
该函数和 MakeWindowsStyle 函数同理,但功能是反向操作,将 Windows 格式的 “ \ ” 转为 “ / ”。 GetContainingFolder() 函数
该函数可以返回路径文件夹的父文件路径,让我们直接看 for 循环:rbegin() 函数是一个反向迭代器,即与 begin() 获取第一个元素相反,它获得的是倒数第一个元素;相对的,rend() 就是获得第一个元素了。所以 auto(自判断类型)it 的初值是路径的末尾。 接着先看第二个 if,它判断若 extration 为 false 且 it 扫描到 “ \ ” 或 “ / ” 时,代表已经扫描完了子文件,接下来是父文件的路径,于是赋值 extration 为 true,之后的循环即可在第一个 if 内不断记录下路径。 但是,rbegin() 是反向迭代,循环输入后 result 中的路径是相反的,所以代码调用 reverse() 函数倒序 result 为路径正序,并在最后补上 “ \ ”,最终成功输出。 GetElementName() 函数
该函数和 GetContainingFolder() 函数同理,不过是反向操作,它能获得路径的末尾子文件:if 判断末尾若是 “ \ ” 则删除,接着 for 循环反向迭代记录子文件名称,遇到 “ \ ” “ / ” 时代表子文件输入完毕,退出循环;最后 reverse 使路径正序输出。 GetExtension() 函数
该函数能获得文件扩展名,原理与上两个函数一样,只是将终止条件更换为 “ . ”,不多赘述。 FileTypeToString() 函数
该函数用 switch 判断并转换文件类型为字符串,非常简单,也不多说。值得注意的是,这里的文件类型都来自 PathParser 类自己定义的类 EFileType,是按功能分类的。 GetFileType() 函数
该函数能判断文件格式类型,并转换为 EFileType 中记录的功能类型,若未知返回 EFileType 中的 UNKNOWN。实现方式很简单,调用上述过的函数 GetExtension 得到文件扩展名再 if 判断。 值得注意的是 transform 函数,这里是它的一元操作用法,四个参数的含义依次是:操作起始位、操作终止位、操作后记录的起始位、某种操作。该函数的作用是从操作起始位元素开始,依次按需操作元素直至终止位并记录;此处的操作是 ctype.h 中的 tolower(小写操作),这样就能符合后续 if 内的小写字母判断了。transform 是标准库函数,所以更多的用法在此不作讲解。 至此,PathParser 的所有函数已经探究完了,其实了解了使用的几个库内函数,就能轻松理解。让我们继续看下一个部分 Random。 2、Random2.1 Random.h2.1.1 头文件
文件仅包含了随机数库,不多说。 2.1.2 主体代码主体代码定义了一个类 Random,作用是处理随机数的生成,代码如下:
该类的功能很少,函数也有注释,不多赘述。关于唯一的变量,其类型为 default_random_engine,但这是 random 头文件里用 using 关键词重命名的 mt19937 类型,而 mt19937 也是 using 重命名了的一个 random 里的类模板。而这个类模板就是 mersenne_twister_engine 梅森选择算法,其特点是以一个梅森素数作为周期长度。 梅森素数由梅森数而来,先讲梅森数,是指形如 2p - 1 的一类数,其中 p 是素数;而是素数的梅森数就称为梅森素数,例如 7、127 等等 —— 当然,用在这个算法中的梅森素数更大。虽然这个算法很强大,能生成高质量的序列,但存在速度相对较慢的缺点。该算法很复杂,在此就讲解这么多。 另外,该类模板除了有 mt19937 生成随机的无符号 32 位整数,还有 mt19937_64 生成无符号的 64 位整数。其中,mt19937 随机数生成器的周期长度为 219937-1,因而得名。 了解完变量,现在让我们到 Random.cpp 看看函数们的具体实现方法: 2.2 Random.cpp该文件的头文件只有上述的 Random.h 文件,不多赘述,直接看函数: Generate() 函数
该函数有两个函数重载,仅变量类型不同。函数功能的实现也很简单,它声明了一个 random 头文件中的类对象,能直接生成一个指定范围内的随机数。 值得一提的是,生成随机数的类 uniform_int_distribution 与 uniform_real_distribution 都继承了同是 random 里的 uniform_real 类模板;该类模板的内含一个功能是将一个随机数生成器对象作为参数值传给均匀分布函数对象,从而获得一个随机值。该类还包含了其它功能函数,在此不多赘述。 所以,在返回对象 distribute 时,代码这里还多传入了一个 __GENERATOR 到一个括号 “ ( ) ” 中。其实,该括号不是什么函数的括号,而是括号符号的重载:
显然,需要更深入去查看 _Eval()。这是 uniform_real 类中的私有函数:
其中,_NRAND 是用到了 generate_canonical 均匀分布随机数函数的一个函数,而 generate_canonical 函数模板会提供一个浮点值范围在 [0,1) 内且有给定的随机比特数的标准均匀分布。至此,我们就了解了整个随机数生成并返回的过程。 CheckPercentage() 函数
该函数功能是判断生成数值是否超出给出的百分比值,调用的类模板与函数和 Generate() 一样,所以原理也是一样的,在此就不多赘述。 总结至此,Utils 小模块的前两个部分我们已经探究完毕。总结来说,这些类以及内含的函数们的逻辑并不复杂,许多都是直接依靠 C++ 标准库来实现,由此可见 C++ 标准库的完备与强大;此外,虽然大多是标准库函数,但我们依然可以学习编写者的逻辑思维以及代码的规范性,这都可以成为在工程项目实际应用中的经验。 Utils 分析的中篇,我们将探究接下来两个部分:ReferenceOrValue 与 SizeConverter。代码虽然短,但是也有值得学习的地方。 |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/28 0:45:31- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |