[译]Godot 引擎 GDNative 架构初探

GDNative的架构从最早叫“DLScript”的时候到目前为止已经发生了很大的变化。随着Godot 3.0版本接近最终发布以及API越来越稳定,是时候对GDNative目前的形态作一个概述了。
GDNATIVELIBRARY
GDNativeLibrary是一种资源类型。它是对每种平台所需的实际二进制文件的一种抽象:包含一些属性、“入口”库加载路径清单及“入口”库所依赖库的清单。
这些清单是一套功能特性标记的简单映射形式 - 一般是一个文件路径;如果有依赖关系的话,就是一组路径。
特性标记
Godot有一套特性标记系统。特性标记表示拥有对应的特定的属性或功能,例如Windows, X11, 32, 64, mobile等等。在导出游戏时,你也可以自行定义标记,从而可能改变游戏的运行方式。
更多关于特性标记的信息,可以去http://docs.godotengine.org/en/latest/learning/workflow/export/feature_tags.html查看。
GDNativeLibrary资源中的列表由键值对形式组成,键中根据需要可以包含多个特性标记,以英文句点“.”分隔。
例如一个支持64位Linux机器的库,它的键名即“X11.64”,如果对应的是Windows的机器,则键名为“Windows.64”。
Godot编辑器提供了GUI来更人性化的进行这种资源的定义和编辑。

它会从上而下的对所有入口进行检测,并跳过那些不存在的特性标记。在所有可用的标记中,第一个会被用作入口,所以排序很重要。
SINGLETON 库
GDNativeLibrary中有一个属性是用于定义其是否支持单例形式使用的。单例库会在Godot启动期间尽可能早地载入,且会调用库中的gdnative_singleton函数。这种库常用于需要提供与Godot紧密结合的功能。
GDNATIVE
GDNative对象代表所载入的库,至于具体要加载哪个库就要从GDNativeLibrary资源文件中匹配了,Godot环境下的C++代码可以去调用该库中的函数。由于这种方式去调用函数太过灵活、底层且不安全,所以是不建议从GDScript这些脚本语言中去调的。
如果真想从脚本语言环境直接调用相应功能,可以用GDNative.call_native方法来满足需求。对于这种函数指针调用的底层细节,抽象出了一种所谓的“调用类型”来进行描述。目前仅有一种预定义调用类型:standard_varcall - 要求被调用的函数签名为 godot_variant function_name(godot_array *) 。单例库可以按需注册新的调用类型。
GDNATIVE/GODOT API
如果某个库想调用Godot的一些功能,它就需要去调用Godot的代码。而各种C++编译器之间的移植性非常有问题,所以我们选择用C语言API的形式来封装对C++的调用。这开启了多种语言访问API的可能性,但也带来了一些冗余性。
API 结构
一个库为了访问那些用C封装的函数,它首先要知道那些函数的位置。最直接的想法是留空,然后让操作系统的库加载机制来处理。
不幸的是,这种方式不能在所有平台正常运作(此处Windows可能要尴尬的咳两声),所以为了保证在所有平台设置GDNative库用同样的代码和步骤,我们决定采取另一种途径:在加载函数时,以函数指针结构(struct)的形式传递。
该结构存在于Godot中,并包含版本信息、将来的API改动字段及扩展API列表。
struct godot_gdnative_api_struct {
unsigned int type;
godot_gdnative_api_version version;
const godot_gdnative_api_struct *next;
};
struct godot_gdnative_core_api_struct {
unsigned int type;
godot_gdnative_api_version version;
const godot_gdnative_api_struct *next;
unsigned int num_extensions;
const godot_gdnative_api_struct **extensions;
// ...
};
库可以从这种struct中访问所需的函数,也就意味着不再是编写 godot_some_function();这种形式了,而是api->godot_some_function();。
有些人喜欢简单的通过函数名而不是struct来访问函数,所以在有需要时,Godot的构建系统会生成一个静态库,来包裹所有的同名函数指针为静态函数。
扩展
GDNative 扩展是一种给库提供GDNative/Godot API 之外功能的方式。它们可以不同方式应用,下面会列出几种当前支持的形式的扩展。
扩展通常带有C语言API,可能还伴随着有自定义数据类型。Godot里通常有用于包裹那些和其它功能密切结合的C函数的C++类/方法。
每个扩展都有它自己的子API结构,其中包含了版本信息及未来API修改信息的字段。
ARVR
采用GDNative来实现一种VR驱动的所有API可以参考文档: file。
这套API的起点是 godot_arvr_register_interface 函数,它需要从一个单例库进行调用。那些要被Godot调用的函数则组织成一个结构以参数的形式传递过去。
目前有 null-driver 的实现、 OpenVR 的实现 和 WIP OpenHMD 的实现。
NATIVESCRIPT
GDNative的早期开发生涯里,它仅被计划用于脚本化编程,后来被发掘出更多灵活和有用的地方,脚本化编程能力现在仅仅是其中一个扩展。
NativeScript 实现了一套“脚本语言” - 在Godot中可以这么叫,但其实是用GDNative库而不是像GDScript那样的文本和文件的形式来保存相关逻辑。
NativeScript会调用库中的一个函数 nativescript_init - 告知Godot哪些类和方法是可用的。在要用到那些类和方法的时候,NativeScript就能很简单的去调用这个库来实现相应功能。
因为 NativeScript 仅对库进行操作,它并不关心这些库是用什么语言构建的,如果开发者要用自己喜欢的编程语言进行库的开发,就使得 NativeScript 成为 Godot 里的一种最佳选择,尽管在这个基础上还要付出很多努力。
那想要更灵活且更像脚本的感觉的话,就应该考虑用一下 PluginScript 了。
PLUGINSCRIPT
PluginScript也是一个扩展,它给Godot加入了封装脚本语言实现的特性。对Godot而言,它是一种运行良好且完全集成的脚本语言,但所有逻辑都是在一个库中实现的。
NativeScript 把库都当作脚本用,而PluginScript是用库来定义脚本。也就是只要在你的Godot项目中添加一些文件,就可以添加一种新的脚本语言支持。
目前为止,这种“野生”的主要应用还只有一个 godot-python项目。
与ARVR扩展类似,PluginScript的API也是非常小巧,仅有一个需要调用的函数 godot_pluginscript_register_language。该函数接受一个struct作为参数,struct里包含函数指针及脚本语言的其它信息。
Godot编辑器重启后,就能生效了。
计划
我们正在计划创建更多的扩展,如可插拔式音视频解码器。
对于GDNative当前的架构,我们已经相当满意了,下一步主要是完善文档和改善语言绑定。
[译]Godot 引擎 GDNative 架构初探的更多相关文章
- scrapy架构初探
scrapy架构初探 引言 Python即时网络爬虫启动的目标是一起把互联网变成大数据库.单纯的开放源代码并不是开源的全部,开源的核心是"开放的思想",聚合最好的想法.技术.人员, ...
- OceanBase 架构初探
OceanBase 架构初探 原创衣舞晨风 发布于2018-11-13 08:44:14 阅读数 1417 收藏 展开 1.设计思路 OceanBase的目标是支持数百TB的数据量以及数十万TPS. ...
- [译]Godot系列教程一 - 场景与节点
场景(Scene)与节点(Node) 简介 先设想有那么一瞬间你自己不再是一名游戏开发者了,而是一名大厨! 你的装备换成了一套大厨的制服.不要考虑制作游戏的事情,你现在的职责是为你的顾客创建新的可口的 ...
- F2工作流引擎这工作流引擎体系架构(二)
F2工作流体系架构概览图 为了能更好的了解F2工作流引擎的架构体系,花了些时间画了整个架构的体系图.F2工作流引擎遵循参考WFCM规范,目标是实现轻量级的工作流引擎,支持多种数据库及快速应用到任何基于 ...
- 云原生时代, Kubernetes 多集群架构初探
为什么我们需要多集群? 近年来,多集群架构已经成为“老生常谈”.我们喜欢高可用,喜欢异地多可用区,而多集群架构天生就具备了这样的能力.另一方面我们也希望通过多集群混合云来降低成本,利用到不同集群各自的 ...
- MySQL InnoDB存储引擎体系架构 —— 索引高级
转载地址:https://mp.weixin.qq.com/s/HNnzAgUtBoDhhJpsA0fjKQ 世界上只两件东西能震撼人们的心灵:一件是我们心中崇高的道德标准:另一件是我们头顶上灿烂的星 ...
- [译]Godot系列教程四 - 编写脚本
编写脚本(Scripting) 简介 关于无需编程即可创建视频游戏的那些工具的谈论有很多.不用学习编程知识对很多独立开发者来说就是一个梦想.这种需求 - 游戏开发者.甚至在很多公司内部,希望对游戏流程 ...
- [译]Godot系列教程三 - 场景实例化(续)
场景实例化(续) 要点 场景实例化带来很多便利的用法,总体来说有: 将场景细分,更便于管理 相对于某些引擎中的Prefab组件更灵活,并且在许多方面更强大 是一种设计更复杂的游戏流程甚至UI的方式 这 ...
- [译]Godot系列教程五 - 制作Godot编辑器插件
制作插件 下文仅针对2.1版本. 关于插件 插件是为编辑器扩展出更多有用工具的重要方式.它可以完全用GDScript和标准场景开发,甚至都不需重新加载编辑器就可生效.不像模块,你无需创建C++代码.也 ...
随机推荐
- JavaEE - 20181225
作者:沈世钧链接:https://www.zhihu.com/question/305924723/answer/557800752来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...
- MySql:Table 'database.TABLE_ONE' doesn't exist
1. 问题描述 由于最近使用本地的MySQL奔溃了,在修改管理员密码时,不慎修改错误,导致无法重新写会,甚至按照MySQL官网手册都无法修改正确,遂放弃修改root密码,直接将一个未有数据的纯净版My ...
- dns 安全
域名系统组织架构 DNS是全球互联网中最重要的基础服务之一,也是如今唯一的一种有中心点的服务.全球域名系统组织与管理架构如下图所示: ICANN 互联网名称与数字地址分配机构(The Interne ...
- loj#2054. 「TJOI / HEOI2016」树
题目链接 loj#2054. 「TJOI / HEOI2016」树 题解 每次标记覆盖整棵字数,子树维护对于标记深度取max dfs序+线段树维护一下 代码 #include<cstdio> ...
- Python3学习策略
自学Python要点 [来自:http://www.cnblogs.com/shsxt/p/9138950.html] 1.找一本浅显易懂,例程比较好的教程,从头到尾看下去. 不要看很多本,专注于一本 ...
- 1207 ACM 汉诺塔II 数学
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1207 中文题目,在原来三个柱子的情况下(汉诺塔一),增加了一个柱子,难度也增加了. 思路: 思考时尽量和汉 ...
- 潭州课堂25班:Ph201805201 爬虫基础 第八课 selenium (课堂笔记)
Selenium笔记(1)安装和简单使用 简介 Selenium是一个用于Web应用程序测试的工具. Selenium测试直接运行在浏览器中,就像真正的用户在操作一样.支持的浏览器包括IE(7, 8, ...
- BZOJ1395 : [Baltic2005]Trip
建立新图,原图中每条边在新图中是点,新图中每个点的点权为$-e[i].c+e[i].b$,边权为$0$. 若$e[i].d\leq e[j].a$,则连一条$i$到$j$的单向边. 对于原图中每个点, ...
- pom.xml将jar包导入
2.5是Maven的版本
- CocosCreator资源工作流程
--摘自官方文档 资源工作流程 添加资源 资源管理器 提供了三种在项目中添加资源的方式: 通过 创建按钮 添加资源 在操作系统的文件管理器中,将资源文件复制到项目资源文件夹下,之后再打开或激活 Coc ...