amethyst / amethyst/legion

Failed World::clone_from(), because of missing Duplicate::register_clone(), asserts

Aperta
#271 0 commenti 1 reazione 0 assegnatari Vedi su GitHub
Lingua principale
Rust
Stelle
1.7k
Fork
140
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

This code tries to implement the request from #269 – to deserialize into an existing World and to find out what exactly we have deserialized.

I didn't realize one needs `Duplicate::register_clone()` or `Duplicate::register_copy()` in order to copy/clone anything between `World`s.

As a result, the following crashes:
```
use std::{fs, fmt, io};
use std::ops::Range;
use std::path::Path;
use std::error::Error;
use std::fmt::{Display, Formatter};

use serde::de::DeserializeSeed;

use legion::{Entity, World};
use legion::serialize::Canon;
use legion::world::{Merger, Duplicate, Allocate};

use crate::item::{Item, Headwear};
use crate::components::Render;
use crate::prelude::storage::{Archetype, Components, ArchetypeWriter};

impl Registry {

pub fn new() -> Self {
let mut result = Self { registry: legion::Registry::::default() };

result.registry.register::("render".to_string());
result.registry.register::("item".to_string());
result.registry.register::("headwear".to_string());

result
}

fn deser(&self, item_name: &str) -> Result {
let path = Path::new("data/items").join(item_name).with_extension("json");
let json = fs::read_to_string(path)?;
let json_val: serde_json::Value = serde_json::from_str(&json)?;

let entity_serializer = Canon::default();

let w = self.registry
.as_deserialize(&entity_serializer)
.deserialize(json_val)?;

Ok(w)
}

pub fn load(&self, item_name: &str, world: &mut World) -> Result, PrefabError> {
struct PrefabMerger {
pub dup: Duplicate,
pub entities: Vec,
}

impl Merger for PrefabMerger {
fn assign_id(&mut self, existing: Entity, allocator: &mut Allocate) -> Entity {
let id = self.dup.assign_id(existing, allocator);
self.entities.push(id);
id
}

fn merge_archetype(&mut self, src_entity_range: Range, src_arch: &Archetype, src_components: &Components, dst: &mut ArchetypeWriter) {
self.dup.merge_archetype(src_entity_range, src_arch, src_components, dst)
}
}

impl PrefabMerger {
pub fn new() -> Self {
Self { dup: Duplicate::default(), entities: vec![] }
}
}

let mut mirage_world = self.deser(item_name)?;
let mut merger = PrefabMerger::new();
world.clone_from(&mut mirage_world, &legion::any(), &mut merger);

Ok(merger.entities)
}
}

#[cfg(test)]
mod tests {
#[test]
fn cask() -> Result<(), PrefabError> {
let mut world = World::default();
let reg = Registry::new();
let entities = reg.load("one_cask", &mut world)?;
assert_eq!(1, entities.len());

Ok(())
}
}
```

It fails with the following stack:
```
3: core::panicking::assert_failed
at /Users/vic/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/panicking.rs:143:5
4: ::drop
at /Users/vic/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/insert.rs:113:9
5: core::ptr::drop_in_place
at /Users/vic/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:192:1
6: legion::internals::world::World::clone_from
at /Users/vic/.cargo/registry/src/github.com-1ecc6299db9ec823/legion-0.4.0/src/internals/world.rs:691:9
7: rifrl::item::prefabs::Registry::load
at ./src/item/prefabs.rs:103:9
8: rifrl::item::prefabs::tests::cask
at ./src/item/prefabs.rs:183:24
```
in `impl Drop for ArchetypeWriter::drop()`:
```
assert_eq!(
self.claimed.count_ones() as usize,
self.archetype.layout().component_types().len()
);
```

I guess this should not crash, but instead just clone nothing. Or, maybe, it should, but with a more clear error message.

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.