amethyst / amethyst/legion

Serialize Example results in a world that panics when you use it

Ouverte
#143 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub
Langage dominant
Rust
Étoiles
1.7k
Forks
140
Métriques de merge des PR
Aucune PR mergée en 30 j

Description

Here is a code sample. Basically, the world that is deserialized is able to satisfy certain queries, but panics if you try to delete an entity. Other kinds of actions also cause panics; I don't know enough about the internals of legion to interpret the stack trace or see the common thread behind which things break and which don't.

To avoid copy-pasting 500 lines of code into a github issue; this is the implementation of `main`; it becomes compiling code if you replace `main` from https://github.com/TomGillen/legion/blob/2adcf95e3353e12efff3b1b2fb5bb20d5d243927/example/serialization/src/main.rs with the following:

```
fn main() {
// create world
let universe = Universe::new();
let mut world = universe.create_world();

// Pos and Vel are both serializable, so all components in this chunkset will be serialized
world.insert(
(),
vec![
(Pos(1., 2., 3.), Vel(1., 2., 3.)),
(Pos(1., 2., 3.), Vel(1., 2., 3.)),
(Pos(1., 2., 3.), Vel(1., 2., 3.)),
(Pos(1., 2., 3.), Vel(1., 2., 3.)),
],
);
// Unserializable components are not serialized, so only the Pos components should be serialized in this chunkset
for _ in 0..1000 {
world.insert(
(Pos(4., 5., 6.), Unregistered(4., 5., 6.)),
vec![
(Pos(1., 2., 3.), Unregistered(4., 5., 6.)),
(Pos(1., 2., 3.), Unregistered(4., 5., 6.)),
(Pos(1., 2., 3.), Unregistered(4., 5., 6.)),
(Pos(1., 2., 3.), Unregistered(4., 5., 6.)),
],
);
}
// Entities with no serializable components are not serialized, so this entire chunkset should be skipped in the output
world.insert(
(Unregistered(4., 5., 6.),),
vec![(Unregistered(4., 5., 6.),), (Unregistered(4., 5., 6.),)],
);

let comp_registrations = [
ComponentRegistration::of::(),
ComponentRegistration::of::(),
];
let tag_registrations = [TagRegistration::of::(), TagRegistration::of::()];

use std::iter::FromIterator;
let ser_helper = SerializeImpl {
comp_types: HashMap::from_iter(comp_registrations.iter().map(|reg| (reg.ty, reg.clone()))),
tag_types: HashMap::from_iter(tag_registrations.iter().map(|reg| (reg.ty, reg.clone()))),
entity_map: RefCell::new(HashMap::new()),
};

let serializable = legion::serialize::ser::serializable_world(&world, &ser_helper);
let serialized_data = serde_json::to_string(&serializable).unwrap();
let de_helper = DeserializeImpl {
tag_types_by_uuid: HashMap::from_iter(
ser_helper
.tag_types
.iter()
.map(|reg| (reg.1.uuid, reg.1.clone())),
),
comp_types_by_uuid: HashMap::from_iter(
ser_helper
.comp_types
.iter()
.map(|reg| (reg.1.uuid, reg.1.clone())),
),
tag_types: ser_helper.tag_types,
comp_types: ser_helper.comp_types,
// re-use the entity-uuid mapping
entity_map: RefCell::new(HashMap::from_iter(
ser_helper
.entity_map
.into_inner()
.into_iter()
.map(|(e, uuid)| (uuid, e)),
)),
};
let mut deserialized_world = universe.create_world();
let mut deserializer = serde_json::Deserializer::from_str(&serialized_data);
legion::serialize::de::deserialize(&mut deserialized_world, &de_helper, &mut deserializer)
.unwrap();

let count = >::query().iter(&deserialized_world).count();
// This works ...
assert_eq!(count, 4004);

let count = >::query().iter_entities(&deserialized_world).count();
// ... and this works ...
assert_eq!(count, 4004);

let to_delete: Entity = >::query().iter_entities(&deserialized_world).next().map(|(e, _)| e).unwrap();
// ... but this panics.
deserialized_world.delete(to_delete);
}
```

The stacktrace is a little baffling; I don't know how you could have a runtime failure of a struct to implement a trait:

```
14: core::option::Option::unwrap
at /rustc/8d69840ab92ea7f4d323420088dd8c9775f180cd/src/libcore/macros/mod.rs:10
15: legion_core::world::World::delete
at /Users/richard.rast/rustdev/derp/legion/legion_core/src/world.rs:309
16: serialization::main
at serialization/src/main.rs:462
17: std::rt::lang_start::{{closure}}
at /rustc/8d69840ab92ea7f4d323420088dd8c9775f180cd/src/libstd/rt.rs:67
18: std::rt::lang_start_internal::{{closure}}
at src/libstd/rt.rs:52
19: std::panicking::try::do_call
at src/libstd/panicking.rs:303
20: __rust_maybe_catch_panic
at src/libpanic_unwind/lib.rs:86
21: std::panicking::try
at src/libstd/panicking.rs:281
22: std::panic::catch_unwind
at src/libstd/panic.rs:394
23: std::rt::lang_start_internal
at src/libstd/rt.rs:51
24: std::rt::lang_start
at /rustc/8d69840ab92ea7f4d323420088dd8c9775f180cd/src/libstd/rt.rs:67
25: ::deserialize::__Visitor as serde::de::Visitor>::expecting
```

Guide de contribution

Aucun guide de contribution indexé pour ce dépôt

Évaluation

Cette issue n'a pas encore été évaluée.

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.