amethyst / amethyst/legion

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

Aberta
#143 0 comentários 0 reações 0 responsáveis Ver no GitHub
Linguagem predominante
Rust
Estrelas
1.7k
Forks
140
Métricas de merge de PRs
Nenhum PR com merge em 30d

Descrição

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
```

Guia de contribuição

Nenhum guia de contribuição indexado para este repositório

Avaliação

Esta issue ainda não foi avaliada.

Receba novas issues na sua caixa de entrada

Um resumo curto de issues do GitHub para quem está começando.