Last active
April 17, 2022 15:33
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[dependencies] | |
legion = "0.4.0" | |
serde = "1.0.125" | |
serde_json = "1.0.64" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, ®istry, &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