2 个不稳定版本
0.2.0 | 2020 年 10 月 24 日 |
---|---|
0.1.0 | 2020 年 4 月 12 日 |
#491 in 游戏开发
115KB
3K SLoC
goggles
它就像一副漂亮的太阳镜,只是不舒服且不方便
这个包是 specs
ECS 库的重度修改和精简版本。它与其说是一个用于尽可能轻松地完成特定风格的 ECS 的框架,不如说是一个 DIY 库,允许您根据自己需求进行修改。
goggles
可能不如其他 ECS 库(如 specs
或 legion
)容易使用,如果类似 specs
或 legion
的库已经满足您的需求,那么您可能应该使用它。
基本数据结构设计几乎与 specs
完全相同,它使用与 specs
相同的基本数据结构来存储组件和执行连接。就像 specs
一样,它将组件存储在单独的存储中,并使用来自 hibitset
的分层位集合来记录它们的存在,并使用该分层位集合来执行连接。
然而,在此基础上,它提供的 API 比甚至 specs
还要简洁和零散。它在删除方面有些主观:我感到所有不必要的或神秘的东西,只尝试处理非常 困难 的操作或是不安全的操作,并将更容易的部分留给用户自行设计。
该库包含一系列相对独立的组件,您可以在适当的抽象级别停止
-
par_seq
模块是完全独立的方式来设置和运行通用的并行和顺序系统。它可以与shred
相比较,但它包含一个更通用的System
特性,并且不包含锁定和读取资源的功能。它只是允许您在System
中定义一组资源,使用Par
和Seq
组合这些系统,确保结果没有资源冲突,然后运行它。 -
system_data
模块为par_seq
模块定义了一个用于静态定义资源的SystemData
特性,并为SystemData
的元组提供了实现。 -
resource_set
模块定义了一个类似于AnyMap
的ResourceSet
,其值存储在RwLock
中。与一组RwLock
不同,它永远不会阻塞,而是在别名规则被违反时直接引发恐慌。它被设计成可以使用par_seq
模块构建在定义资源上运行的系统。它还包括方便的类型来定义和请求对实现SystemData
的资源的读写句柄,因此它们可以用于类似(Read<ResourceA>, Write<ResourceB>)
的元组中。它与shred
中的World
类型非常相似。 -
join
模块包含一个为u32
索引存储和由BitSet
跟踪的Join
特质的定义。它提供了快速、不安全的访问,并且能够安全地顺序和并行迭代Join
,还提供了将多个Join
实例连接在一起的手段。它与specs
中的Join
特质类似,但为了提高安全性而进行了重新设计。 -
storage
模块包含RawStorage
特质以及 3 个有用的实现:VecStorage
、DenseVecStorage
和HashMapStorage
。这是一个存储与索引关联的值的抽象、不安全特质。它与specs
中的等效功能非常相似。 -
tracked
模块包含一个跟踪组件变化的RawStorage
包装器。与specs
不同,这相当简约,仅在可选的情况下在可变访问时在AtomicBitSet
中设置一个标志。 -
masked
模块包含一个MaskedStorage
结构,该结构安全地封装了一个RawStorage
和一个BitSet
来跟踪哪些组件存在。MaskedStorage
也支持连接。 -
entity
模块包含一个原子生成索引分配器,它还使用hibitset
类型来跟踪哪些索引是活动的。它还允许你连接到分配器以输出活动的Entity
。 -
world
模块将所有这些功能结合在一起,形成了一个具有可识别的 ECS API 的系统。如果你想了解它是如何工作的,或者想构建自己的抽象而不是这个模块中提供的,请从这里开始。对specs
的许多更改都是为了使world
模块只包含安全代码。
以下是移除自 shred
和 specs
的一些重要内容的未完整列表
-
没有自动设置,你必须插入/注册所有资源和组件类型。
-
没有保存/加载支持,你应该自己处理。
-
没有自动系统调度/分派/批处理,你必须自己使用
par
和seq
设计执行策略,然后在启动时检查冲突。 -
没有懒更新,你可能需要为你的应用程序专门处理。并不总是有一种普遍的最佳方式来做这件事。
以下是从 specs
中提取的关于该库和 specs
共同功能的重要变更的不完整列表
-
不需要 T: Sync 来进行对资源/组件的可变访问(只需要 T: Send)。
-
重新设计了 Join 特性,以增强健壮性和安全性。还有一个额外的
IntoJoin
特性,允许您在不编写不安全代码的情况下参与方便的元组连接语法。 -
组件
RawStorage
的实现需要UnsafeCell
来保证健壮性。 -
组件
RawStorage
的实现始终假设存储是互斥的,并且可以安全地并行迭代。 -
简化了组件修改跟踪。
-
移除了一些已知不健壮的
specs
功能,例如通过迭代器进行索引组件访问。 -
库的各个部分尽量松散耦合,有时以增加代码或用户便利性为代价。
-
几乎所有的内部代码都是公开的,以便您可以根据需要构建不同的抽象。
为什么会有这个东西?
我一直在使用 specs
的项目,并且我不断需要重新设计它的一些小部分。多亏了 specs
的贡献,它已经是一个可以非常零散、独立使用的库,这正是我所做的。在某一点上,我抬头一看,意识到我只使用了 specs
提供的核心功能的约 20%,那时我开始需要使用杂乱的扩展特性来更进一步。我决定重新实现我仍然使用的 specs
的核心部分,把它和一些我制作的更灵活(但可能更难使用)的东西打包在一起(与 shred /
specs
提供的东西相比),然后把它放在这里。
我应该使用这个吗?
您很可能不需要或想要这个crate。尽管如此,如果您发现自己需要将 specs
分解成其组成部分并在其上构建自己的API,这个crate就在这里供您使用。
致谢
本项目直接源自 specs
,所以大部分功劳归于 specs
的创造者。这个crate中任何特别巧妙的东西可能都是他们的。
许可证
这是从 specs
衍生的,所以它同样采用 Apache-2.0 / MIT 双许可证。
依赖关系
~1.7–2.3MB
~48K SLoC