Skip to content

Instantly share code, notes, and snippets.

@matthewjberger
Last active April 17, 2022 15:33
Show Gist options
  • Save matthewjberger/d05494ffe9009061c3d9907925390317 to your computer and use it in GitHub Desktop.
Save matthewjberger/d05494ffe9009061c3d9907925390317 to your computer and use it in GitHub Desktop.
An example of creating and serializing an ecs world with legion ecs in rust
[dependencies]
legion = "0.4.0"
serde = "1.0.125"
serde_json = "1.0.64"
use legion::{
serialize::{set_entity_serializer, Canon},
*,
};
use serde::{Deserialize, Serialize};
// a component is any type that is 'static, sized, send and sync
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
struct Position {
x: f32,
y: f32,
}
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
struct Velocity {
dx: f32,
dy: f32,
}
fn main() {
let mut world = World::default();
// push a component tuple into the world to create an entity
let entity: Entity = world.push((Position { x: 0.0, y: 0.0 },));
// or extend via an IntoIterator of tuples to add many at once (this is faster)
let _entities: &[Entity] = world.extend(vec![
(Position { x: 0.0, y: 0.0 }, Velocity { dx: 0.0, dy: 0.0 }),
(Position { x: 1.0, y: 1.0 }, Velocity { dx: 0.0, dy: 0.0 }),
(Position { x: 2.0, y: 2.0 }, Velocity { dx: 0.0, dy: 0.0 }),
]);
// create a registry which uses strings as the external type ID
let mut registry = Registry::<String>::default();
registry.register::<Position>("position".to_string());
registry.register::<Velocity>("velocity".to_string());
registry.register::<f32>("f32".to_string());
registry.register::<bool>("bool".to_string());
// serialize entities with the `Position` component
// let filter = component::<Position>();
//
// or serialize all entities
let filter = legion::any();
let entity_serializer = Canon::default();
let json = serde_json::to_value(&world.as_serializable(filter, &registry, &entity_serializer))
.expect("Failed to serialize world!");
println!("{:#}", json);
// registries are also serde deserializers
use serde::de::DeserializeSeed;
let _world: World = registry
.as_deserialize(&entity_serializer)
.deserialize(json)
.expect("Failed to deserialize world!");
// Serializing a struct that lives outside the ECS but references entities
#[derive(Debug, Default, Serialize, Deserialize)]
struct EntityContainer {
pub entities: Vec<Entity>,
}
let mut entity_container = EntityContainer::default();
entity_container.entities.push(entity);
let json = set_entity_serializer(&entity_serializer, || {
// The guid here will match the guid of the first entity we created
serde_json::to_value(entity_container).expect("Failed to serialize entity container!")
});
println!("Serialized container: {:#?}", json);
let container: EntityContainer = set_entity_serializer(&entity_serializer, || {
serde_json::from_str(&json.to_string()).expect("Failed to deserialize entity container!")
});
println!("Deserialized container: {:#?}", container);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment