Trying to deserialize from JSON file
Hi! I'm trying to follow the rust rogueliketoolkit tutorial and trying to convert it to legion.
I'm trying to deserialize a savegame.json file, but I'm getting errors. The deserializer isn't well documented, but I've tried my best:
pub fn load_game(world: &mut World, resources: &mut Resources) {
/*{
let mut cmd = CommandBuffer::new(world);
let mut to_delete = Vec::new();
for e in <Entity>::query().iter_mut(world) {
to_delete.push(*e);
}
for del in to_delete.iter() {
cmd.remove(*del);
}
cmd.flush(world, resources);
} */
let mut registry = Registry::<String>::default();
register_components!(registry, BlocksTile, CombatStats, Player, Position, Monster, Name, Item, Renderable, SufferDamage, Viewshed, WantsToMelee, InBackpack, WantsToPickupItem, WantsToUseItem, WantsToDropItem, Consumable, ProvidesHealing, Ranged, InflictsDamage, AreaOfEffect, Confusion, SerializationHelper);
let data = fs::read_to_string("./savegame.json").unwrap();
let entity_serializer = Canon::default();
let new_world: World = registry.as_deserialize(&entity_serializer).deserialize(data).expect("Unable to deserialize world");
//let new_world: World = registry.as_deserialize(&entity_serializer).deserialize(data).unwrap();
*world = new_world;
let mut deleteme: Option<Entity> = None;
{
for (entity, helper) in <(Entity, &SerializationHelper)>::query().iter(world) {
resources.insert(helper.map.clone());
let mut map = resources.get_mut::<Map>().unwrap();
map.tile_content = vec![Vec::new(); super::map::MAP_COUNT];
deleteme = Some(*entity);
}
for (entity, _player, position) in <(Entity, &Player, &Position)>::query().iter(world) {
resources.insert(rltk::Point::new(position.x, position.y));
resources.insert(PlayerEntity { entity: *entity })
}
}
let mut cmd = CommandBuffer::new(world);
cmd.remove(deleteme.unwrap());
cmd.flush(world, resources);
}
The register_components! macro is just a way to iterate over all my components and register them with a name of their lowercase struct name
error[E0277]: the trait bound `std::string::String: components::_::_serde::Deserializer<'_>` is not satisfied
--> src\saveload_system.rs:58:84
|
58 | let new_world: World = registry.as_deserialize(&entity_serializer).deserialize(data).expect("Unable to deserialize world");
| ^^^^ the trait `components::_::_serde::Deserializer<'_>` is not implemented for `std::string::String`
sorry for such a basic question, but I'm really having problems and I don't know how to fix it.
Hi @dyedquartz, I haven't tried the deserialization by myself yet, but as I can see from documentation for legion::serialize module, they pass a serde_json::Value as an argument to deserialize(), not a String (because serde_json::to_value() returns serde_json::Value there).
What you can try is adding something like let json = serde_json::from_str(data).unwrap(); and then passing that json to deserialize() instead of data.
Just solved the same issue by converting String to json::Value.
However, I have a next issue now: after calling as_deserialize_into_world(...).deserialize(json_value), I don't have the id of the newly created Entities.
How can I refer to the newly created entities?
@zedrian @dyedquartz Herbert, the author of the said tutorial and "Hands-on Rust" book (which is another tutorial), has created a forum. I've opened a topic about prefabs here (might take some time to pass pre-moderaion). I have also published a working deserializer in issue #269 in this repo.