#bevy #bevy-ecs #serialization #serde #save

bevy_serde_lens

bevy引擎的状态化、结构化和可读性序列化库

8 个不稳定版本 (3 个破坏性更新)

0.4.0 2024年7月4日
0.4.0-rc.42024年7月1日
0.3.0 2024年5月24日
0.2.0 2024年4月28日
0.1.4 2024年4月26日

#268 in 编码

Download history 306/week @ 2024-04-22 66/week @ 2024-04-29 119/week @ 2024-05-20 2/week @ 2024-05-27 7/week @ 2024-06-03 1/week @ 2024-06-10 250/week @ 2024-07-01 13/week @ 2024-07-08 125/week @ 2024-07-29

每月下载量:127次

MIT/Apache

105KB
2K SLoC

bevy_serde_lens

Crates.io Docs Bevy tracking

为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

我们提供了一个框架来序列化 EntityParent 等。在开始之前请注意,这仅在可以保留映射顺序的序列化器中有效。例如,在 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_anyAnyTagged 允许 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-2.0许可证定义的,您有意提交以包含在作品中的任何贡献,将作为以上双授权使用,不附加任何额外条款或条件。

依赖项

~13-48MB
~784K SLoC