【问题标题】:Is it possible to base a language around the Entity-Component-System architecture?是否可以围绕实体-组件-系统架构建立一种语言?
【发布时间】:2020-09-09 20:19:42
【问题描述】:

几周以来,我一直在想着在脑海中创建一种基于 ECS 的编程语言。但是,我不太确定是否可以创建基于 ECS 的通用语言。

如何实现数据结构?你怎么能做图形或网络的东西?

我开始认为这是不可能的,但我决定在放弃这个想法之前先在这里问一下。我真的很想完成这项工作,但我只是不知道这是否可能。

那么,有可能吗?你会怎么做我提到的事情?

提前致谢!

【问题讨论】:

    标签: programming-languages entity-component-system


    【解决方案1】:

    在我们的案例中,我们实际上有一个专有的。它远不是一种功能齐全的语言,而只是一种旨在使使用 ECS 数据结构和组件更容易的 DSEL。

    我们的主要关注点实际上是编译时反射,例如语言中定义的任何数据类型的自动序列化(UDT 使用 C 中相同的 struct 接口定义,具有相同的成员对齐)以及允许任何数据语言中定义的类型可以立即用作场景中的组件类型,无需任何明确的数据类型注册(每个数据类型都有自己的唯一类型索引,可以在编译时轻松获取,无需 RTTI)。大多数情况下,我们发现像序列化和类型注册,最重要的是,在 C 和 C++ 等语言中进行反射往往需要大量的样板文件或极其花哨的模板元编程。我们开始厌倦这一切,所以我们制作了一种相当简单的类 C 语言(而编译器实际上只是生成 C 代码)为我们自动完成所有工作。实际上,一旦 C++ 从Reflection TS 实现reflexpr,我们将不再从中受益。

    该语言实际上主要侧重于以与 C 兼容的方式定义数据类型,但会自动生成函数来序列化、反序列化、比较、交换和向 ECS 注册它们。在编译时迭代 struct 的所有成员变量并将它们序列化、交换它们等操作很简单。我们最终仍然在 C++ 中实现大部分逻辑,并通过我们的语言传递数据到 C++。例如,我们可以这样写:

    struct Foo
    {
        float x, y, z;
    };
    

    ... 并立即将Foo 组件插入到我们的 ECS 场景中,而无需编写类似 ecs.register<Foo>(); 或类似性质的任何内容。我从来没有发现类型注册如此重要,因为大多数引擎没有超过几十个组件类型,但是序列化和反序列化尤其是在我们的编辑器中生成 GUI 是一个很大的 PITA。该语言的重点主要是让它变得轻而易举,尽管它确实围绕着 ECS 作为存储和表示所有程序数据的中心方式。它允许我们执行以下操作:

    def(generic_type) void serialize(out_stream& out, generic_type udt)
    {
        // Compile-time reflection: the key feature of our language and the
        // main rationale for its existence. Calls serialize(out, member) for
        // each member of the user-defined type/struct.
        $for_each_member(udt, serialize, out);
    }
    def void serialize(out_stream& out, float val)
    {
        out.write_float(val);
    }
    

    我们还对泛型提供了一些有限的支持,如上所示,以及函数重载(我们实际上没有成员函数,但编写 x.some_func(y) 只是编写 some_func(x, y) 的语法替代方案——我们没有由于主要关注的是 ECS,因此不必担心封装和面向对象的编程)。

    至于 ECS 数据结构,它们与我们用 C 或 C++ 等语言实现它们的方式没有什么不同,实际上,它们是用 C++ 实现的。我们对编译器所做的第一件事是确保它可以轻松地与 C 互操作,并调用 C API 函数,以便我们可以在 C 端实现我们需要的任何东西(包括基本的 ECS 数据结构以及图形函数之类的东西) .这是相当标准的东西,尽管在实现一种新语言时,编译器/解释器是通过一些统一的 API 或外部函数接口让它与像 C 这样的语言互操作。在我们的例子中,由于我们的编译器生成的是 C 代码而不是机器代码,因此允许它立即调用我们喜欢通过 dylib 导出的任何 C 函数(包括用 C++ 实现的函数)非常简单。

    【讨论】:

    • 我有一个想法,虽然围绕 ECS 旋转语言当然是可能的,但除了组件注册系统之外,ECS 本身并没有那么多东西,也许原型作为实现,系统查询,和这种性质的东西。但是,根据 ECS 用例中经常出现的语言,如序列化、反序列化、多线程、分支和数据的热/冷拆分、SIMD SoA 处理、事件等,有很多事情可能会非常乏味。一种非常关注这些东西的语言可能会变得非常复杂。
    • 在我们的案例中,我们只是构建了一个尽可能接近 C 的极简 DSEL,并且可以轻松地在它之间来回通信数据,而无需任何翻译,从而自动化了我们经常做的很多事情使用我们在 C++ 中极其繁琐的 ECS 架构。
    猜你喜欢
    • 2016-03-29
    • 2015-03-12
    • 1970-01-01
    • 2018-11-24
    • 2018-08-04
    • 2021-07-13
    • 1970-01-01
    • 1970-01-01
    • 2014-01-08
    相关资源
    最近更新 更多