use std::io::Write;
use bevy_archive::{
binary_archive::{WorldArrowSnapshot, WorldBinArchSnapshot},
prelude::*,
};
use bevy_ecs::prelude::*;
use serde::{Deserialize, Serialize};
#[derive(Component, Serialize, Deserialize, Debug, Clone, PartialEq)]
struct Position {
x: f32,
y: f32,
}
#[derive(Component, Serialize, Deserialize, Debug, Clone, PartialEq)]
struct Velocity {
dx: f32,
dy: f32,
}
#[derive(Component, Serialize, Deserialize, Debug, Clone, PartialEq, Default)]
struct Tag;
#[derive(Component, Serialize, Deserialize, Debug, Clone, PartialEq)]
struct Inventory(Vec<String>);
#[derive(Component, Serialize, Deserialize, Debug, Clone)]
struct NestedComponent {
inner: Vector2,
name: String,
}
#[derive(Resource, Serialize, Deserialize, Debug, Clone)]
struct ResComponent {
inner: Vector2,
name: String,
sim_duration: f64,
}
#[derive(Clone, Serialize, Deserialize, Debug, Component)]
pub struct Vector2([f32; 2]);
#[derive(Clone, Serialize, Deserialize, Default, Debug)]
pub struct Vector2Wrapper {
pub x: f32,
pub y: f32,
}
#[derive(Clone, Serialize, Deserialize, Default, Debug)]
pub struct TagWrapper {
value: bool,
}
#[derive(Clone, Serialize, Deserialize, Default, Debug)]
pub struct ChildOfWrapper(pub u32);
impl From<&Vector2> for Vector2Wrapper {
fn from(p: &Vector2) -> Self {
Self {
x: p.0[0],
y: p.0[1],
}
}
}
impl From<Vector2Wrapper> for Vector2 {
fn from(value: Vector2Wrapper) -> Self {
Vector2([value.x, value.y])
}
}
impl From<&ChildOf> for ChildOfWrapper {
fn from(c: &ChildOf) -> Self {
ChildOfWrapper(c.0.index())
}
}
impl From<ChildOfWrapper> for ChildOf {
fn from(value: ChildOfWrapper) -> Self {
ChildOf(Entity::from_raw_u32(value.0).unwrap())
}
}
impl From<&Tag> for TagWrapper {
fn from(_c: &Tag) -> Self {
TagWrapper { value: true }
}
}
impl From<TagWrapper> for Tag {
fn from(_value: TagWrapper) -> Self {
Self
}
}
fn setup_registry() -> SnapshotRegistry {
let mut registry = SnapshotRegistry::default();
registry.register::<Position>();
registry.register::<Velocity>();
registry.register_with::<Tag, TagWrapper>();
registry.register::<Inventory>();
registry.register::<NestedComponent>();
registry.register_with::<Vector2, Vector2Wrapper>();
registry.register_with::<ChildOf, ChildOfWrapper>();
registry.resource_register::<ResComponent>();
registry
}
fn build_sample_world(world: &mut World) -> Entity {
world.spawn((Position { x: 1.0, y: 2.0 }, Velocity { dx: 0.1, dy: -0.2 }));
world.spawn((Tag, Position { x: 9.0, y: 3.5 }));
world.spawn((Inventory(vec!["potion".into(), "sword".into()]),));
world.insert_resource(ResComponent {
inner: Vector2([0.0, 3.0]),
name: "sim_cfg".to_string(),
sim_duration: 10.0,
});
let mut boss = world.spawn((
Position { x: 0.0, y: 0.0 },
Tag,
NestedComponent {
inner: Vector2([3.0, 2.0]),
name: "Boss".into(),
},
Vector2([3.0, 2.0]),
));
boss.with_children(|children| {
let minion1 = children
.spawn((
Position { x: -1.0, y: 0.0 },
Inventory(vec!["dagger".into()]),
))
.id();
let minion2 = children
.spawn((
Position { x: 1.0, y: 0.0 },
Inventory(vec!["shield".into()]),
))
.id();
println!(
"Spawned parent {:?} with children {:?} and {:?}",
children.target_entity(),
minion1,
minion2
);
});
boss.id()
}
fn main() {
let mut world = World::new();
build_sample_world(&mut world);
let registry = setup_registry();
let arrow = WorldArrowSnapshot::from_world_reg(&world, ®istry).unwrap();
let data = WorldBinArchSnapshot::from(arrow);
let final_data = rmp_serde::to_vec(&data).unwrap();
let data: WorldBinArchSnapshot = rmp_serde::from_slice(&final_data).unwrap();
let arrow = WorldArrowSnapshot::from(data);
let mut new_world = World::new();
arrow.to_world_reg(&mut new_world, ®istry).unwrap();
let mut q = new_world.query::<(Entity, &Position)>();
let zip = arrow.to_zip(Some(6)).unwrap();
let mut f = std::fs::File::create("ecs_world.zip").unwrap();
f.write_all(&zip).unwrap();
for (entity, data) in q.iter(&new_world) {
println!("entity: {} data: {:?}", entity, data);
}
}