8 个不稳定版本 (3 个破坏性更新)
0.4.0 | 2024年7月4日 |
---|---|
0.4.0-rc.4 | 2024年7月1日 |
0.3.0 | 2024年5月24日 |
0.2.0 | 2024年4月28日 |
0.1.4 | 2024年4月26日 |
#268 in 编码
每月下载量:127次
105KB
2K SLoC
bevy_serde_lens
为bevy引擎提供闪电般快速、状态化、结构化和可读性序列化库。
功能
- 具有世界访问权限的状态化序列化和反序列化。
- 闪电般快速(与
DynamicScene
相比)。 - 将
Entity
、其Component
及其子项视为单个serde对象。 - 将类似于
Box<dyn T>
的特例对象反序列化,作为typetag
的替代方案。 - 极其轻量级和模块化。没有系统,没有插件。
- 支持使用熟悉语法的每种serde格式。
- 序列化
Handle
并提供通用数据归一化接口。 - 以安全的方式序列化存储的
Entity
。 - 无需反射。
入门指南
想象我们有一个典型的Character
包。
首先我们推导出BevyObject
#[derive(Bundle, BevyObject)]
#[bevy_object(query)]
pub struct Character {
pub transform: Transform,
pub name: Name,
pub position: Position,
pub hp: Hp,
}
#[bevy_object(查询)]
这表示我们正在序列化一个查询而不是层次结构树,这可以提高性能。
要序列化,我们只需这样做
serde_json::to_string(&world.serialize_lens::<Character>());
这将找到符合包的QueryFilter
的所有实体并将它们序列化到数组中。
要反序列化,我们使用deserialize_scope
world.deserialize_scope(|| {
// Returned object doesn't matter, data is stored in the world.
let _ = serde_json::from_str::<InWorld<Character>>(&json_string);
})
此语句在世界上生成新的实体并将它们填充为反序列化的数据。
在加载新的之前,您可能想要删除当前实体,以删除序列化关联的所有实体的关联实体
// Despawn all character.
world.despawn_bound_objects::<Character>()
要批量保存多种类型的对象,使用batch!
宏创建一个批处理序列化类型。
type SaveFile = batch!(
Character, Monster,
// Use `SerializeResource` to serialize a resource.
SerializeResource<Terrain>,
);
world.save::<SaveFile>(serializer)
world.load::<SaveFile>(deserializer)
world.despawn_bound_objects::<SaveFile>()
这将在映射条目中保存每种类型
{
"Character": [
{ .. },
{ .. },
..
],
"Monster": [ .. ],
"Terrain": ..
}
高级序列化
BevyObject
不仅是对Bundle
的克隆,我们支持附加类型。
impl BevyObject
:组件自动成为BevyObject
,并且BevyObject
可以包含多个其他BevyObject
。Maybe<T>
可以用来表示一个项可能存在也可能不存在。DefaultInit
使用FromWorld
初始化非序列化组件。Child<T>
在子组件中查找并序列化单个BevyObject
。ChildVec<T>
在子组件中查找并序列化多个BevyObject
。
有关详细信息,请参阅 BevyObject
继承宏。
// Note we cannot derive bundle anymore :(
// #[bevy_object(query)] also cannot be used due to children being serialized.
#[derive(BevyObject)]
#[bevy_object(rename = "character")]
pub struct Character {
pub transform: Transform,
pub name: Name,
pub position: Position,
pub hp: Hp,
#[serde(default)]
pub weapon: Maybe<Weapon>
#[serde(skip)]
pub cache: DefaultInit<Cache>,
pub potions: ChildVec<Potion>
}
投影类型
该软件包为某些常见用例提供各种投影类型。
例如,要将 Handle
序列化为其字符串路径,可以使用如下 #[serde(with = "PathHandle")]
#[derive(Serialize, Deserialize)]
struct MySprite {
#[serde(with = "PathHandle")]
image: Handle<Image>
}
或者直接使用新类型。
#[derive(Serialize, Deserialize)]
struct MySprite {
image: PathHandle<Image>
}
实体ID
我们提供了一个框架来序列化 Entity
、Parent
等。在开始之前请注意,这仅在可以保留映射顺序的序列化器中有效。例如,在 serde_json
中,您必须启用功能 preserve_order
才能使用这些功能。
当使用 BevyObject
时,我们可以指定 EntityId
组件。这为此实体的 Entity
id 进行注册,以供同一批次的未来使用。
在条目之后,未来实体可以使用 Parented
将其父级设置为该实体,或者使用 EntityPtr
来序列化一个引用该实体的 Entity
。
类型标签
typetag
软件包允许您序列化类似 Box<dyn T>
的特质对象,但使用 typetag
将始终引入与您的构建相关联的所有实现,并且不支持 WASM。为了解决这些限制,此软件包允许您在 bevy World
中手动注册反序列化器,并使用 TypeTagged
投影类型进行序列化。
world.register_typetag::<Box<dyn Animal>, Cat>()
然后
#[derive(Serialize, Deserialize)]
struct MyComponent {
#[serde(with = "TypeTagged")]
weapon: Box<dyn Weapon>
}
为了有用户友好的配置文件,您可以使用 register_deserialize_any
和 AnyTagged
允许 deserialize_any
,即序列化 42
而不是 {"int": 42}
在自描述格式中。请注意,在非自描述格式(如 postcard
)中使用 AnyTagged
总是会返回错误,因为这是由 serde 规范的限制造成的。
world.register_deserialize_any(|s: &str|
Ok(Box::new(s.parse::<Cat>()
.map_err(|e| e.to_string())?
) as Box<dyn Animal>)
)
对于库作者
更理想的是依赖于 bevy_serde_lens_core
,因为它的 semver 在 bevy 主要发布周期内不太可能更改。
版本
bevy | bevy-serde-lens-core | bevy-serde-lens |
---|---|---|
0.13 | - | 0.1-0.3 |
0.14 | 0.14 | 0.4 |
许可证
根据您的要求,许可协议为以下之一
- Apache License,版本 2.0 (LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义的,您有意提交以包含在作品中的任何贡献,将作为以上双授权使用,不附加任何额外条款或条件。
依赖项
~13-48MB
~784K SLoC