核心类型
Godot 具有构成其核心的丰富的类和模板集,并且所有内容都基于它们构建。 这份参考将试着按顺序列出它们,使之更容易被理解。
定义
uint8_t、uint32_t、int64_t 等,现在每个编译器都支持。为这些东西重新发明轮子没什么意思,只会让代码更难以阅读。
int。这样做是因为如今每个设备都至少具有 32 位总线,并且可以在一个周期中执行这样的操作。它也使代码更具可读性。
size_t,保证为 64 位。
对于 Unicode 字符,使用 CharType 而不是 wchar_t,因为许多架构中 wchar_t 的长度是 4 个字节,而我们需要的是 2 个字节。但是默认情况下,这不会被强制,CharType 会直接映射到 wchar_t。
参考:
- core/typedefs.h
内存模型
PC 是一个很棒的架构。计算机通常具有 GB 级的内存、TB 级的存储空间和 GHz 级的 CPU,当应用程序需要更多资源时,操作系统会交换出不活动的资源。其他架构(如移动设备或游戏主机)在这些方面通常有更多的限制。 最常见的内存模型是堆,应用程序会从中请求一块内存区域,底层操作系统会试着从某处找到一块适合这样的内存并返回它。这通常效果最好,并且很灵活,但是随着时间的流逝和滥用,这可能会导致分段。 分段缓慢地产生对于大多数常见分配而言太小的孔洞,从而浪费了内存。关于堆和分段的文献有很多,因此在此不再赘述。现代操作系统使用分页内存,这有助于减轻但不能解决分段问题。 然而,许多研究和测试显示,在给出足够内存的情况下,如果最大分配大小所占堆最大大小的比例低于一个给定的阈值,并且有一定比例的内存本来就是不使用的,那么分段就不会变化,不会随着时间的推移成为问题。换句话说,如果留出 10-20% 的可用内存空间,并且执行的都是小额内存分配,那么就不会出事。 Godot 确保所有的可动态分配的对象都很小(最多不到几 kb)。但是如果出现很大的分配(像图像、网格几何数据或大数组)会怎样呢?在这种情况下,Godot 可以选择使用动态内存池。内存会被锁定以进行访问操作;如果内存不足,则内存池会根据需要进行重新排列和压缩。根据游戏的需要,程序员可以配置动态内存池的大小。内存分配
Godot有许多工具可用于跟踪游戏中的内存使用情况, 尤其是在调试期间. 因此, 不应使用常规的C和C++库调用. 相反,Godot提供了一些其它的供你使用. Godot提供了一些宏可以用来处理C风格的内存分配:
这些等效于标准C库中通常的malloc, realloc, free. 这些宏可以用来处理C++风格的内存分配:memalloc()memrealloc()memfree()
这些等效于new, delete, new[]和delete[]. memnew/memdelete也使用一点C++的小技巧, 在对象创建之后和删除之前, 通知对象. 对于动态内存, 提供了PoolVector<>模板.PoolVector是一个标准的Vector类, 与C++标准库中的vector非常相似. 要创建PoolVector缓冲区, 请使用以下命令:memnew( Class / Class(args) )memdelete( instance )memnew_arr( Class , amount )memdelete_arr( pointer to array )
可以使用[]运算符访问PoolVector, 并且存在一些帮助:PoolVector<int> data;
PoolVector<int>::Read r = data.read()int someint = r[4]
这些操作允许从PoolVectors快速读/写并保持锁定直到它们超出作用域. 但是,PoolVectors应该用于小型动态内存操作, 因为read()和write()对于大量访问来说太慢了.PoolVector<int>::Write w = data.write()w[4] = 22;
参考:
- core/os/memory.h
- core/pool_vector.h
容器
Godot 还提供了一系列通用的容器: - 向量
- List
- 设置
- Map
它们很简单, 旨在尽可能小, 因为C++中的模板经常被内联, 并且在调试符号和代码中使二进制大小更加大. 可以使用指针迭代List, Set和Map, 如下所示:
Vector<>类还具有一些不错的功能:for(List<int>::Element *E=somelist.front();E;E=E->next()) { print_line(E->get()); // print the element}
- 它会在写入时进行复制, 因此只要不对其进行修改, 制作拷贝就很容易.
- 通过在引用计数器上使用原子操作, 来支持多线程.
参考:
- core/vector.h
- core/list.h
- core/set.h
- core/map.h
字符串
Godot 还提供了一个字符串类 String.Godot还提供了String类. 此类具有大量功能, 在所有函数(如大小写操作)和utf8解析/提取中均提供全面的Unicode支持, 以及提供用于转换和可视化的帮助函数.参考:
- core/ustring.h
StringName
StringName(字符串名称)和 String(字符串)类似,但它们是唯一的。从字符串创建 StringName 会为所有相等的字符串产生唯一的内部指针。StringNames 对于将字符串用作标识符非常有用,因为比较它们基本上是在比较指针。 创建一个字符串名称(尤其是一个新的) 是慢的, 但比较它们是快的.参考:
- core/string_name.h
数学类型
在core/math目录中, 有几种线性代数常用的类型.参考:
- core/math
节点路径
这是一种特殊的数据类型, 用于在场景树中存储路径并快速引用它们.参考:
- core/node_path.h
RID
RID是资源ID. 服务使用这些来引用存储在其中的数据.RID是不透明的, 这意味着它们引用的数据不能直接访问.RID是唯一的, 甚至对于不同类型的引用数据也是如此.参考:
- core/rid.h
