Rust中的动态类型实体组件系统 问题

Rust中的动态类型实体组件系统 问题,rust,game-development,type-systems,entity-component-system,Rust,Game Development,Type Systems,Entity Component System,我正在为我试图构建的游戏引擎构建一个实体组件系统,我不太确定如何使用严格的类型化语言,在本例中是Rust 我希望组件类型是任意结构,可以包含关于实体的任何类型的状态,但不知道其行为。例如,通过这种方式,实体可以包含位置、点击框和速度组件,但物理子系统可以单独更改或交换,而无需修改有关这些组件的任何内容 我还希望能够从模块外部添加新的组件类型。这将允许一个新的游戏模块向现有实体添加自己的自定义组件,而无需修改游戏的核心代码 我生锈了,而且在C++中做了有限的工作,所以我可能完全错了,如果是这样的话

我正在为我试图构建的游戏引擎构建一个实体组件系统,我不太确定如何使用严格的类型化语言,在本例中是Rust

我希望组件类型是任意结构,可以包含关于实体的任何类型的状态,但不知道其行为。例如,通过这种方式,实体可以包含
位置
点击框
速度
组件,但物理子系统可以单独更改或交换,而无需修改有关这些组件的任何内容

我还希望能够从模块外部添加新的组件类型。这将允许一个新的游戏模块向现有实体添加自己的自定义组件,而无需修改游戏的核心代码

<>我生锈了,而且在C++中做了有限的工作,所以我可能完全错了,如果是这样的话,我会很欣赏解决这个问题的更好的方法。

在一种没有严格类型系统(我更熟悉)的语言中,如JavaScript,我可以拥有一个实体数组,其中包含任意类型的组件集合,然后执行运行时类型检查以获取数据:

类位置{
构造函数(x=0,y=0,z=0){
这个.x=x;
这个。y=y;
这个。z=z;
}
}
类速度{
构造函数(x=0,y=0,z=0){
这个.x=x;
这个。y=y;
这个。z=z;
}
}
康斯特世界=[
[
位置(0,0,0),
速度(0.25,0.1,1.2)
]
]
const physicsystem=(world=[])=>world.map((entity=[])=>{
常量速度=实体。查找((组件)=>组件速度实例)
返回速度!=null?实体.map((组件)=>组件实例位置
位置(组件x+速度x,组件y+速度y,组件z+速度z)
:组件
):组件
})
window.setInterval(()=>world=physicsystem(world),100)
在上面的示例中,实体可以包含任何类型的组件,处理它们的系统可以检索它们所依赖的特定组件,直接访问它们的具体属性,然后修改组件。外部代码也可以将一个完全未知的组件添加到其中一个实体中,物理组件不需要更改以适应它。这是我希望在我的云服务器中具有的相同行为

作为旁注,因为游戏需要比我的示例javascript提供的更高性能的解决方案,所以我希望尽可能地减少指针间接寻址、哈希表查找、内存分配和优化数据位置,但自然地,优化仅次于功能。我的示例代码忽略了这些优化

我一直在尝试的 我考虑过创建
ComponentStorage
的hashmap,其中
ComponentStorage
是一种特性,它允许我抽象用于存储组件的底层数据结构。
状态
结构将包含一个
HashMap
。可以通过TypeId散列查找特定存储,然后使用ComponentStorage trait,我可以通过实体ID从该存储中检索
选项
,然后访问
T
包含的任何属性

但是,这不起作用,因为类型T对于
HashMap
中的每个项目都是不同的,并且我不能通过为类型参数的每个变体创建一个单独的特征来删除类型参数(正如在这个类似的问题中所建议的:)因为我需要访问处理实体的系统中的具体类型T

我可以通过使用
Any
来存储组件,实现类似于我的示例JavaScript的东西,但我的理解是,在任意自定义结构上使用
Any
意味着没有相邻的存储,指针间接寻址非常多。我并不想过早地进行优化,但我不太愿意沿着这条路线进行原型设计,因为似乎任何
的这些限制都不可能在以后完全重写它的情况下被克服

由于指针间接寻址显然必须发生才能将类型硬编码到这个系统中,因此我希望组件集合(而不是组件本身)具有多态性,同时能够通过具体类型访问给定集合中包含的项


如果你能在这里给我任何帮助,我将永远感激你。谢谢

在同一个容器中只有一种方法可以使不同类型的对象处于同一容器中:指针间接寻址


实际上,JavaScript引擎在幕后为您做了完全相同的事情。

只有一种方法可以将不同类型的对象放在同一个容器中:指针间接寻址


事实上,JavaScript引擎在幕后为你做了完全相同的事情。

你听说过吗?@FrancisGagné我听说过Amethyst,但我从未研究过他们是如何解决这个问题的。我可能最终只是使用他们的库,而不是重新发明轮子,但为了学习,我仍然很好奇他们是如何设法保持不同组件存储的动态集合的。我得做些调查。谢谢你的链接!你听说过吗?@FrancisGagné我听说过Amethyst,但我从来没有研究过他们是如何解决这个问题的。我可能最终只是使用他们的库,而不是重新发明轮子,但为了学习,我仍然很好奇他们是如何设法保持不同组件存储的动态集合的。我得做些调查。谢谢你的链接!我要澄清一下我的问题。是的,我确实知道我需要在代码中的某个地方使用指针间接寻址,但是由于一个游戏在每个刻度上会迭代数千到数百万个组件,所以看起来是这样的