17次发布
0.3.2 | 2024年4月21日 |
---|---|
0.3.1 | 2024年4月18日 |
0.2.3 | 2024年4月15日 |
0.1.11 | 2024年4月2日 |
0.1.6 | 2024年3月18日 |
#852 in 编码
每月下载量57次
用于 bevy_stat_query
96KB
2K SLoC
bevy_serde_project
bevy引擎的具有状态、结构化和可读性的序列化包。
功能
- 具有世界访问权限的状态序列化和反序列化。
- 将
Entity
、其Component
和子项视为单个 serde 对象。 - 序列化
Handle
并提供通用数据合并接口。 - 像智能指针一样序列化存储的
Entity
。 - 将 trait 对象(如
Box<dyn T>
)反序列化为序列化,作为typetag
的替代方案。 - 极其轻量级且模块化。无系统,无插件。
- 支持几乎所有 serde 格式*
* 人体工程学可能取决于 Serializer
、Deserializer
和 DeserializeSeed
特性支持
入门
序列化具有一些组件和子项的 Entity
角色,假设所有组件都是 Serialize
和 DeserializeOwned
bind_object!(Character as "Character" {
#[serde(flatten)]
character: Character,
position: Position,
#[serde(default, skip_serializing_if="Option::is_none")]
weapon: Maybe<Weapon>,
shield: Maybe<Shield>,
#[serde(default, skip_serializing_if="Vec::is_empty")]
potions: ChildVec<Potion>,
})
然后调用 save
在 World
上,其中 serializer
是类似 serde_json::Serializer
的东西。
// Save
world.save::<Character>(serializer)
// Load
world.load::<Character>(deserializer)
// Delete
world.despawn_bound_objects::<Character>()
这将保存角色列表作为数组
[
{ .. },
{ .. },
..
]
要批量保存多种类型的对象,使用 batch!
宏创建批量序列化类型。
type SaveFile = batch!(
Character, Monster, Terrain,
// Use `BindResource` to serialize a resource.
BindResource<MyResource>,
);
world.save::<SaveFile>(serializer)
world.load::<SaveFile>(serializer)
world.despawn_bound_objects::<SaveFile>()
这将按映射条目保存每个类型
{
"Character": [
{ .. },
{ .. },
..
],
"Monster": [ .. ],
"Terrain": [ .. ],
"MyResource": ..
}
常见问题解答
- 如果我的类型不是
Serialize
和DeserializeOwned
呢?
我们可以使用 SerdeProject
派生或实现以将它们转换为 serde
类型。
- 我不拥有该类型
使用 Convert
和 SerdeProject
宏将类型转换为所有权的 newtype。
- 我有一个 ID 并且我想序列化其内容
SerdeProject
允许你在序列化过程中从世界中获取资源。
- 我有一个
Box<dyn T>
如果你在一个非Wasm平台上,你可以尝试 typetag
包。如果不是,或者你想要更多控制,请查看此包中的 typetagged
模块。
特性和它们的作用
Serialize
和DeserializeOwned
任何 Serialize
和 DeserializeOwned
类型都自动是 SerdeProject
,而任何这样的 Component
都自动是 BevyObject
。
这的缺点是我们不能由于孤儿规则而在任何外部类型上实现 SerdeProject
。这就是 Convert
和 SerdeProject
宏发挥作用的地方。
SerdeProject
SerdeProject
将非serde类型投影到具有世界访问权限的serde类型。
SerdeProject
宏在所有字段都实现 SerdeProject
或通过 Convert
特征转换为 SerdeProject
新类型的类型上实现了 SerdeProject
。
示例
将 Handle
序列化为它的路径,存储在 AssetServer
中。
#[derive(SerdeProject)]
struct MySprite {
// implements serde, therefore is `SerdeProject`.
pub name: String,
// Calls `Convert` and `PathHandle<Image>` is `SerdeProject`.
#[serde_project("PathHandle<Image>")]
pub handle: Handle<Image>
}
Convert
Convert 允许你将不可序列化的类型 RefCast
为实现 SerdeProject
的新类型。
例如,PathHandle<Handle<T>>
将 Handle
序列化为 String
,而 UniqueHandle<Handle<T>>
将 Handle
序列化为 T
。这种零成本的转换可以通过 ref_cast
包来完成。
BevyObject
BevyObject
允许将 Entity
序列化。这可以是只是一个组件,或者组件的组合,子组件,子组件上的组件等。
所有 SerdeProject
组件都是 BevyObject
。
BindBevyObject
BindBevyObject
是一个 QueryFilter
,通常是一个键组件,它确定序列化和反序列化的入口点。
任何具有 QueryFilter
但不满足绑定 BevyObject
布局的实体将导致错误。
使用 bind_object!
宏创建序列化条目。
Named
为资源提供序列化名称。
SaveLoad
表示批序列化类型,或单个保存文件的内容。
TypeTag
typetag
包允许你序列化像 Box<dyn T>
这样的特质对象,但使用 typetag
总是会拉入与你的构建相关联的所有实现,并且不适用于WASM。为了解决这些限制,此包允许你在bevy World
中手动注册反序列化器,并使用 TypeTagged
新类型进行序列化。
world.register_typetag::<Box<dyn Animal>, Cat>()
然后
#[derive(SerdeProject)]
struct MyComponent {
#[serde_project("TypeTagged<Box<dyn Weapon>>")]
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 | bevy-serde-project |
---|---|
0.13 | 最新版 |
许可证
许可协议为以下之一
- 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 许可证定义),均应如上双许可,无需附加条款或条件。
依赖项
~18–53MB
~866K SLoC