bevy_scene/
serde.rs

1//! `serde` serialization and deserialization implementation for Bevy scenes.
2
3use crate::{DynamicEntity, DynamicScene};
4use bevy_ecs::entity::Entity;
5use bevy_reflect::{
6    serde::{
7        ReflectDeserializer, TypeRegistrationDeserializer, TypedReflectDeserializer,
8        TypedReflectSerializer,
9    },
10    PartialReflect, ReflectFromReflect, TypeRegistry,
11};
12use bevy_utils::HashSet;
13use core::fmt::Formatter;
14use serde::{
15    de::{DeserializeSeed, Error, MapAccess, SeqAccess, Visitor},
16    ser::{SerializeMap, SerializeStruct},
17    Deserialize, Deserializer, Serialize, Serializer,
18};
19
20/// Name of the serialized scene struct type.
21pub const SCENE_STRUCT: &str = "Scene";
22/// Name of the serialized resources field in a scene struct.
23pub const SCENE_RESOURCES: &str = "resources";
24/// Name of the serialized entities field in a scene struct.
25pub const SCENE_ENTITIES: &str = "entities";
26
27/// Name of the serialized entity struct type.
28pub const ENTITY_STRUCT: &str = "Entity";
29/// Name of the serialized component field in an entity struct.
30pub const ENTITY_FIELD_COMPONENTS: &str = "components";
31
32/// Serializer for a [`DynamicScene`].
33///
34/// Helper object defining Bevy's serialize format for a [`DynamicScene`] and implementing
35/// the [`Serialize`] trait for use with Serde.
36///
37/// # Example
38///
39/// ```
40/// # use bevy_ecs::prelude::*;
41/// # use bevy_scene::{DynamicScene, serde::SceneSerializer};
42/// # let mut world = World::default();
43/// # world.insert_resource(AppTypeRegistry::default());
44/// // Get the type registry
45/// let registry = world.resource::<AppTypeRegistry>();
46/// let registry = registry.read();
47///
48/// // Get a DynamicScene to serialize, for example from the World itself
49/// let scene = DynamicScene::from_world(&world);
50///
51/// // Create a serializer for that DynamicScene, using the associated TypeRegistry
52/// let scene_serializer = SceneSerializer::new(&scene, &registry);
53///
54/// // Serialize through any serde-compatible Serializer
55/// let ron_string = bevy_scene::ron::ser::to_string(&scene_serializer);
56/// ```
57pub struct SceneSerializer<'a> {
58    /// The scene to serialize.
59    pub scene: &'a DynamicScene,
60    /// The type registry containing the types present in the scene.
61    pub registry: &'a TypeRegistry,
62}
63
64impl<'a> SceneSerializer<'a> {
65    /// Create a new serializer from a [`DynamicScene`] and an associated [`TypeRegistry`].
66    ///
67    /// The type registry must contain all types present in the scene. This is generally the case
68    /// if you obtain both the scene and the registry from the same [`World`].
69    ///
70    /// [`World`]: bevy_ecs::world::World
71    pub fn new(scene: &'a DynamicScene, registry: &'a TypeRegistry) -> Self {
72        SceneSerializer { scene, registry }
73    }
74}
75
76impl<'a> Serialize for SceneSerializer<'a> {
77    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
78    where
79        S: Serializer,
80    {
81        let mut state = serializer.serialize_struct(SCENE_STRUCT, 2)?;
82        state.serialize_field(
83            SCENE_RESOURCES,
84            &SceneMapSerializer {
85                entries: &self.scene.resources,
86                registry: self.registry,
87            },
88        )?;
89        state.serialize_field(
90            SCENE_ENTITIES,
91            &EntitiesSerializer {
92                entities: &self.scene.entities,
93                registry: self.registry,
94            },
95        )?;
96        state.end()
97    }
98}
99
100/// Handles serialization of multiple entities as a map of entity id to serialized entity.
101pub struct EntitiesSerializer<'a> {
102    /// The entities to serialize.
103    pub entities: &'a [DynamicEntity],
104    /// Type registry in which the component types used by the entities are registered.
105    pub registry: &'a TypeRegistry,
106}
107
108impl<'a> Serialize for EntitiesSerializer<'a> {
109    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
110    where
111        S: Serializer,
112    {
113        let mut state = serializer.serialize_map(Some(self.entities.len()))?;
114        for entity in self.entities {
115            state.serialize_entry(
116                &entity.entity,
117                &EntitySerializer {
118                    entity,
119                    registry: self.registry,
120                },
121            )?;
122        }
123        state.end()
124    }
125}
126
127/// Handles entity serialization as a map of component type to component value.
128pub struct EntitySerializer<'a> {
129    /// The entity to serialize.
130    pub entity: &'a DynamicEntity,
131    /// Type registry in which the component types used by the entity are registered.
132    pub registry: &'a TypeRegistry,
133}
134
135impl<'a> Serialize for EntitySerializer<'a> {
136    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
137    where
138        S: Serializer,
139    {
140        let mut state = serializer.serialize_struct(ENTITY_STRUCT, 1)?;
141        state.serialize_field(
142            ENTITY_FIELD_COMPONENTS,
143            &SceneMapSerializer {
144                entries: &self.entity.components,
145                registry: self.registry,
146            },
147        )?;
148        state.end()
149    }
150}
151
152/// Handles serializing a list of values with a unique type as a map of type to value.
153///
154/// Used to serialize scene resources in [`SceneSerializer`] and entity components in [`EntitySerializer`].
155/// Note that having several entries of the same type in `entries` will lead to an error when using the RON format and
156/// deserializing through [`SceneMapDeserializer`].
157///
158/// Note: The entries are sorted by type path before they're serialized.
159pub struct SceneMapSerializer<'a> {
160    /// List of boxed values of unique type to serialize.
161    pub entries: &'a [Box<dyn PartialReflect>],
162    /// Type registry in which the types used in `entries` are registered.
163    pub registry: &'a TypeRegistry,
164}
165
166impl<'a> Serialize for SceneMapSerializer<'a> {
167    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
168    where
169        S: Serializer,
170    {
171        let mut state = serializer.serialize_map(Some(self.entries.len()))?;
172        let sorted_entries = {
173            let mut entries = self
174                .entries
175                .iter()
176                .map(|entry| {
177                    (
178                        entry.get_represented_type_info().unwrap().type_path(),
179                        entry.as_partial_reflect(),
180                    )
181                })
182                .collect::<Vec<_>>();
183            entries.sort_by_key(|(type_path, _partial_reflect)| *type_path);
184            entries
185        };
186
187        for (type_path, partial_reflect) in sorted_entries {
188            state.serialize_entry(
189                type_path,
190                &TypedReflectSerializer::new(partial_reflect, self.registry),
191            )?;
192        }
193        state.end()
194    }
195}
196
197#[derive(Deserialize)]
198#[serde(field_identifier, rename_all = "lowercase")]
199enum SceneField {
200    Resources,
201    Entities,
202}
203
204#[derive(Deserialize)]
205#[serde(field_identifier, rename_all = "lowercase")]
206enum EntityField {
207    Components,
208}
209
210/// Handles scene deserialization.
211pub struct SceneDeserializer<'a> {
212    /// Type registry in which the components and resources types used in the scene to deserialize are registered.
213    pub type_registry: &'a TypeRegistry,
214}
215
216impl<'a, 'de> DeserializeSeed<'de> for SceneDeserializer<'a> {
217    type Value = DynamicScene;
218
219    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
220    where
221        D: Deserializer<'de>,
222    {
223        deserializer.deserialize_struct(
224            SCENE_STRUCT,
225            &[SCENE_RESOURCES, SCENE_ENTITIES],
226            SceneVisitor {
227                type_registry: self.type_registry,
228            },
229        )
230    }
231}
232
233struct SceneVisitor<'a> {
234    pub type_registry: &'a TypeRegistry,
235}
236
237impl<'a, 'de> Visitor<'de> for SceneVisitor<'a> {
238    type Value = DynamicScene;
239
240    fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
241        formatter.write_str("scene struct")
242    }
243
244    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
245    where
246        A: SeqAccess<'de>,
247    {
248        let resources = seq
249            .next_element_seed(SceneMapDeserializer {
250                registry: self.type_registry,
251            })?
252            .ok_or_else(|| Error::missing_field(SCENE_RESOURCES))?;
253
254        let entities = seq
255            .next_element_seed(SceneEntitiesDeserializer {
256                type_registry: self.type_registry,
257            })?
258            .ok_or_else(|| Error::missing_field(SCENE_ENTITIES))?;
259
260        Ok(DynamicScene {
261            resources,
262            entities,
263        })
264    }
265
266    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
267    where
268        A: MapAccess<'de>,
269    {
270        let mut resources = None;
271        let mut entities = None;
272        while let Some(key) = map.next_key()? {
273            match key {
274                SceneField::Resources => {
275                    if resources.is_some() {
276                        return Err(Error::duplicate_field(SCENE_RESOURCES));
277                    }
278                    resources = Some(map.next_value_seed(SceneMapDeserializer {
279                        registry: self.type_registry,
280                    })?);
281                }
282                SceneField::Entities => {
283                    if entities.is_some() {
284                        return Err(Error::duplicate_field(SCENE_ENTITIES));
285                    }
286                    entities = Some(map.next_value_seed(SceneEntitiesDeserializer {
287                        type_registry: self.type_registry,
288                    })?);
289                }
290            }
291        }
292
293        let resources = resources.ok_or_else(|| Error::missing_field(SCENE_RESOURCES))?;
294        let entities = entities.ok_or_else(|| Error::missing_field(SCENE_ENTITIES))?;
295
296        Ok(DynamicScene {
297            resources,
298            entities,
299        })
300    }
301}
302
303/// Handles deserialization for a collection of entities.
304pub struct SceneEntitiesDeserializer<'a> {
305    /// Type registry in which the component types used by the entities to deserialize are registered.
306    pub type_registry: &'a TypeRegistry,
307}
308
309impl<'a, 'de> DeserializeSeed<'de> for SceneEntitiesDeserializer<'a> {
310    type Value = Vec<DynamicEntity>;
311
312    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
313    where
314        D: Deserializer<'de>,
315    {
316        deserializer.deserialize_map(SceneEntitiesVisitor {
317            type_registry: self.type_registry,
318        })
319    }
320}
321
322struct SceneEntitiesVisitor<'a> {
323    pub type_registry: &'a TypeRegistry,
324}
325
326impl<'a, 'de> Visitor<'de> for SceneEntitiesVisitor<'a> {
327    type Value = Vec<DynamicEntity>;
328
329    fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
330        formatter.write_str("map of entities")
331    }
332
333    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
334    where
335        A: MapAccess<'de>,
336    {
337        let mut entities = Vec::new();
338        while let Some(entity) = map.next_key::<Entity>()? {
339            let entity = map.next_value_seed(SceneEntityDeserializer {
340                entity,
341                type_registry: self.type_registry,
342            })?;
343            entities.push(entity);
344        }
345
346        Ok(entities)
347    }
348}
349
350/// Handle deserialization of an entity and its components.
351pub struct SceneEntityDeserializer<'a> {
352    /// Id of the deserialized entity.
353    pub entity: Entity,
354    /// Type registry in which the component types used by the entity to deserialize are registered.
355    pub type_registry: &'a TypeRegistry,
356}
357
358impl<'a, 'de> DeserializeSeed<'de> for SceneEntityDeserializer<'a> {
359    type Value = DynamicEntity;
360
361    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
362    where
363        D: Deserializer<'de>,
364    {
365        deserializer.deserialize_struct(
366            ENTITY_STRUCT,
367            &[ENTITY_FIELD_COMPONENTS],
368            SceneEntityVisitor {
369                entity: self.entity,
370                registry: self.type_registry,
371            },
372        )
373    }
374}
375
376struct SceneEntityVisitor<'a> {
377    pub entity: Entity,
378    pub registry: &'a TypeRegistry,
379}
380
381impl<'a, 'de> Visitor<'de> for SceneEntityVisitor<'a> {
382    type Value = DynamicEntity;
383
384    fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
385        formatter.write_str("entities")
386    }
387
388    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
389    where
390        A: SeqAccess<'de>,
391    {
392        let components = seq
393            .next_element_seed(SceneMapDeserializer {
394                registry: self.registry,
395            })?
396            .ok_or_else(|| Error::missing_field(ENTITY_FIELD_COMPONENTS))?;
397
398        Ok(DynamicEntity {
399            entity: self.entity,
400            components,
401        })
402    }
403
404    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
405    where
406        A: MapAccess<'de>,
407    {
408        let mut components = None;
409        while let Some(key) = map.next_key()? {
410            match key {
411                EntityField::Components => {
412                    if components.is_some() {
413                        return Err(Error::duplicate_field(ENTITY_FIELD_COMPONENTS));
414                    }
415
416                    components = Some(map.next_value_seed(SceneMapDeserializer {
417                        registry: self.registry,
418                    })?);
419                }
420            }
421        }
422
423        let components = components
424            .take()
425            .ok_or_else(|| Error::missing_field(ENTITY_FIELD_COMPONENTS))?;
426        Ok(DynamicEntity {
427            entity: self.entity,
428            components,
429        })
430    }
431}
432
433/// Handles deserialization of a sequence of values with unique types.
434pub struct SceneMapDeserializer<'a> {
435    /// Type registry in which the types of the values to deserialize are registered.
436    pub registry: &'a TypeRegistry,
437}
438
439impl<'a, 'de> DeserializeSeed<'de> for SceneMapDeserializer<'a> {
440    type Value = Vec<Box<dyn PartialReflect>>;
441
442    fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
443    where
444        D: Deserializer<'de>,
445    {
446        deserializer.deserialize_map(SceneMapVisitor {
447            registry: self.registry,
448        })
449    }
450}
451
452struct SceneMapVisitor<'a> {
453    pub registry: &'a TypeRegistry,
454}
455
456impl<'a, 'de> Visitor<'de> for SceneMapVisitor<'a> {
457    type Value = Vec<Box<dyn PartialReflect>>;
458
459    fn expecting(&self, formatter: &mut Formatter) -> core::fmt::Result {
460        formatter.write_str("map of reflect types")
461    }
462
463    fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
464    where
465        A: SeqAccess<'de>,
466    {
467        let mut dynamic_properties = Vec::new();
468        while let Some(entity) = seq.next_element_seed(ReflectDeserializer::new(self.registry))? {
469            dynamic_properties.push(entity);
470        }
471
472        Ok(dynamic_properties)
473    }
474
475    fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
476    where
477        A: MapAccess<'de>,
478    {
479        let mut added = HashSet::new();
480        let mut entries = Vec::new();
481        while let Some(registration) =
482            map.next_key_seed(TypeRegistrationDeserializer::new(self.registry))?
483        {
484            if !added.insert(registration.type_id()) {
485                return Err(Error::custom(format_args!(
486                    "duplicate reflect type: `{}`",
487                    registration.type_info().type_path(),
488                )));
489            }
490
491            let value =
492                map.next_value_seed(TypedReflectDeserializer::new(registration, self.registry))?;
493
494            // Attempt to convert using FromReflect.
495            let value = self
496                .registry
497                .get(registration.type_id())
498                .and_then(|tr| tr.data::<ReflectFromReflect>())
499                .and_then(|fr| fr.from_reflect(value.as_partial_reflect()))
500                .map(PartialReflect::into_partial_reflect)
501                .unwrap_or(value);
502
503            entries.push(value);
504        }
505
506        Ok(entries)
507    }
508}
509
510#[cfg(test)]
511mod tests {
512    use crate::{
513        ron,
514        serde::{SceneDeserializer, SceneSerializer},
515        DynamicScene, DynamicSceneBuilder,
516    };
517    use bevy_ecs::{
518        entity::{Entity, EntityHashMap, VisitEntities, VisitEntitiesMut},
519        prelude::{Component, ReflectComponent, ReflectResource, Resource, World},
520        query::{With, Without},
521        reflect::{AppTypeRegistry, ReflectMapEntities},
522        world::FromWorld,
523    };
524    use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
525    use bincode::Options;
526    use serde::{de::DeserializeSeed, Deserialize, Serialize};
527    use std::io::BufReader;
528
529    #[derive(Component, Reflect, Default)]
530    #[reflect(Component)]
531    struct Foo(i32);
532    #[derive(Component, Reflect, Default)]
533    #[reflect(Component)]
534    struct Bar(i32);
535    #[derive(Component, Reflect, Default)]
536    #[reflect(Component)]
537    struct Baz(i32);
538
539    // De/serialize as hex.
540    mod qux {
541        use serde::{de::Error, Deserialize, Deserializer, Serializer};
542
543        pub fn serialize<S>(value: &u32, serializer: S) -> Result<S::Ok, S::Error>
544        where
545            S: Serializer,
546        {
547            serializer.serialize_str(&format!("{:X}", value))
548        }
549
550        pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
551        where
552            D: Deserializer<'de>,
553        {
554            u32::from_str_radix(<&str as Deserialize>::deserialize(deserializer)?, 16)
555                .map_err(Error::custom)
556        }
557    }
558
559    #[derive(Component, Copy, Clone, Reflect, Debug, PartialEq, Serialize, Deserialize)]
560    #[reflect(Component, Serialize, Deserialize)]
561    struct Qux(#[serde(with = "qux")] u32);
562
563    #[derive(Component, Reflect, Default)]
564    #[reflect(Component)]
565    struct MyComponent {
566        foo: [usize; 3],
567        bar: (f32, f32),
568        baz: MyEnum,
569    }
570
571    #[derive(Reflect, Default)]
572    enum MyEnum {
573        #[default]
574        Unit,
575        Tuple(String),
576        Struct {
577            value: u32,
578        },
579    }
580
581    #[derive(Resource, Reflect, Default)]
582    #[reflect(Resource)]
583    struct MyResource {
584        foo: i32,
585    }
586
587    #[derive(Clone, Component, Reflect, PartialEq, VisitEntities, VisitEntitiesMut)]
588    #[reflect(Component, MapEntities, PartialEq)]
589    struct MyEntityRef(Entity);
590
591    impl FromWorld for MyEntityRef {
592        fn from_world(_world: &mut World) -> Self {
593            Self(Entity::PLACEHOLDER)
594        }
595    }
596
597    fn create_world() -> World {
598        let mut world = World::new();
599        let registry = AppTypeRegistry::default();
600        {
601            let mut registry = registry.write();
602            registry.register::<Foo>();
603            registry.register::<Bar>();
604            registry.register::<Baz>();
605            registry.register::<Qux>();
606            registry.register::<MyComponent>();
607            registry.register::<MyEnum>();
608            registry.register::<String>();
609            registry.register_type_data::<String, ReflectSerialize>();
610            registry.register::<[usize; 3]>();
611            registry.register::<(f32, f32)>();
612            registry.register::<MyEntityRef>();
613            registry.register::<Entity>();
614            registry.register::<MyResource>();
615        }
616        world.insert_resource(registry);
617        world
618    }
619
620    #[test]
621    fn should_serialize() {
622        let mut world = create_world();
623
624        let a = world.spawn(Foo(123)).id();
625        let b = world.spawn((Foo(123), Bar(345))).id();
626        let c = world.spawn((Foo(123), Bar(345), Baz(789))).id();
627
628        world.insert_resource(MyResource { foo: 123 });
629
630        let scene = DynamicSceneBuilder::from_world(&world)
631            .extract_entities([a, b, c].into_iter())
632            .extract_resources()
633            .build();
634
635        let expected = r#"(
636  resources: {
637    "bevy_scene::serde::tests::MyResource": (
638      foo: 123,
639    ),
640  },
641  entities: {
642    4294967296: (
643      components: {
644        "bevy_scene::serde::tests::Foo": (123),
645      },
646    ),
647    4294967297: (
648      components: {
649        "bevy_scene::serde::tests::Bar": (345),
650        "bevy_scene::serde::tests::Foo": (123),
651      },
652    ),
653    4294967298: (
654      components: {
655        "bevy_scene::serde::tests::Bar": (345),
656        "bevy_scene::serde::tests::Baz": (789),
657        "bevy_scene::serde::tests::Foo": (123),
658      },
659    ),
660  },
661)"#;
662        let output = scene
663            .serialize(&world.resource::<AppTypeRegistry>().read())
664            .unwrap();
665        assert_eq!(expected, output);
666    }
667
668    #[test]
669    fn should_deserialize() {
670        let world = create_world();
671
672        let input = r#"(
673  resources: {
674    "bevy_scene::serde::tests::MyResource": (
675      foo: 123,
676    ),
677  },
678  entities: {
679    4294967296: (
680      components: {
681        "bevy_scene::serde::tests::Foo": (123),
682      },
683    ),
684    4294967297: (
685      components: {
686        "bevy_scene::serde::tests::Foo": (123),
687        "bevy_scene::serde::tests::Bar": (345),
688      },
689    ),
690    4294967298: (
691      components: {
692        "bevy_scene::serde::tests::Foo": (123),
693        "bevy_scene::serde::tests::Bar": (345),
694        "bevy_scene::serde::tests::Baz": (789),
695      },
696    ),
697  },
698)"#;
699        let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
700        let scene_deserializer = SceneDeserializer {
701            type_registry: &world.resource::<AppTypeRegistry>().read(),
702        };
703        let scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
704
705        assert_eq!(
706            1,
707            scene.resources.len(),
708            "expected `resources` to contain 1 resource"
709        );
710        assert_eq!(
711            3,
712            scene.entities.len(),
713            "expected `entities` to contain 3 entities"
714        );
715
716        let mut map = EntityHashMap::default();
717        let mut dst_world = create_world();
718        scene.write_to_world(&mut dst_world, &mut map).unwrap();
719
720        let my_resource = dst_world.get_resource::<MyResource>();
721        assert!(my_resource.is_some());
722        let my_resource = my_resource.unwrap();
723        assert_eq!(my_resource.foo, 123);
724
725        assert_eq!(3, dst_world.query::<&Foo>().iter(&dst_world).count());
726        assert_eq!(2, dst_world.query::<&Bar>().iter(&dst_world).count());
727        assert_eq!(1, dst_world.query::<&Baz>().iter(&dst_world).count());
728    }
729
730    fn roundtrip_ron(world: &World) -> (DynamicScene, DynamicScene) {
731        let scene = DynamicScene::from_world(world);
732        let registry = world.resource::<AppTypeRegistry>().read();
733        let serialized = scene.serialize(&registry).unwrap();
734        let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap();
735        let scene_deserializer = SceneDeserializer {
736            type_registry: &registry,
737        };
738        let deserialized_scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
739        (scene, deserialized_scene)
740    }
741
742    #[test]
743    fn should_roundtrip_with_later_generations_and_obsolete_references() {
744        let mut world = create_world();
745
746        world.spawn_empty().despawn();
747
748        let a = world.spawn_empty().id();
749        let foo = world.spawn(MyEntityRef(a)).insert(Foo(123)).id();
750        world.despawn(a);
751        world.spawn(MyEntityRef(foo)).insert(Bar(123));
752
753        let (scene, deserialized_scene) = roundtrip_ron(&world);
754
755        let mut map = EntityHashMap::default();
756        let mut dst_world = create_world();
757        deserialized_scene
758            .write_to_world(&mut dst_world, &mut map)
759            .unwrap();
760
761        assert_eq!(2, deserialized_scene.entities.len());
762        assert_scene_eq(&scene, &deserialized_scene);
763
764        let bar_to_foo = dst_world
765            .query_filtered::<&MyEntityRef, Without<Foo>>()
766            .get_single(&dst_world)
767            .cloned()
768            .unwrap();
769        let foo = dst_world
770            .query_filtered::<Entity, With<Foo>>()
771            .get_single(&dst_world)
772            .unwrap();
773
774        assert_eq!(foo, bar_to_foo.0);
775        assert!(dst_world
776            .query_filtered::<&MyEntityRef, With<Foo>>()
777            .iter(&dst_world)
778            .all(|r| world.get_entity(r.0).is_err()));
779    }
780
781    #[test]
782    fn should_roundtrip_with_custom_serialization() {
783        let mut world = create_world();
784        let qux = Qux(42);
785        world.spawn(qux);
786
787        let (scene, deserialized_scene) = roundtrip_ron(&world);
788
789        assert_eq!(1, deserialized_scene.entities.len());
790        assert_scene_eq(&scene, &deserialized_scene);
791
792        let mut world = create_world();
793        deserialized_scene
794            .write_to_world(&mut world, &mut EntityHashMap::default())
795            .unwrap();
796        assert_eq!(&qux, world.query::<&Qux>().single(&world));
797    }
798
799    #[test]
800    fn should_roundtrip_postcard() {
801        let mut world = create_world();
802
803        world.spawn(MyComponent {
804            foo: [1, 2, 3],
805            bar: (1.3, 3.7),
806            baz: MyEnum::Tuple("Hello World!".to_string()),
807        });
808
809        let registry = world.resource::<AppTypeRegistry>();
810        let registry = &registry.read();
811
812        let scene = DynamicScene::from_world(&world);
813
814        let scene_serializer = SceneSerializer::new(&scene, registry);
815        let serialized_scene = postcard::to_allocvec(&scene_serializer).unwrap();
816
817        assert_eq!(
818            vec![
819                0, 1, 128, 128, 128, 128, 16, 1, 37, 98, 101, 118, 121, 95, 115, 99, 101, 110, 101,
820                58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, 121,
821                67, 111, 109, 112, 111, 110, 101, 110, 116, 1, 2, 3, 102, 102, 166, 63, 205, 204,
822                108, 64, 1, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33
823            ],
824            serialized_scene
825        );
826
827        let scene_deserializer = SceneDeserializer {
828            type_registry: registry,
829        };
830        let deserialized_scene = scene_deserializer
831            .deserialize(&mut postcard::Deserializer::from_bytes(&serialized_scene))
832            .unwrap();
833
834        assert_eq!(1, deserialized_scene.entities.len());
835        assert_scene_eq(&scene, &deserialized_scene);
836    }
837
838    #[test]
839    fn should_roundtrip_messagepack() {
840        let mut world = create_world();
841
842        world.spawn(MyComponent {
843            foo: [1, 2, 3],
844            bar: (1.3, 3.7),
845            baz: MyEnum::Tuple("Hello World!".to_string()),
846        });
847
848        let registry = world.resource::<AppTypeRegistry>();
849        let registry = &registry.read();
850
851        let scene = DynamicScene::from_world(&world);
852
853        let scene_serializer = SceneSerializer::new(&scene, registry);
854        let mut buf = Vec::new();
855        let mut ser = rmp_serde::Serializer::new(&mut buf);
856        scene_serializer.serialize(&mut ser).unwrap();
857
858        assert_eq!(
859            vec![
860                146, 128, 129, 207, 0, 0, 0, 1, 0, 0, 0, 0, 145, 129, 217, 37, 98, 101, 118, 121,
861                95, 115, 99, 101, 110, 101, 58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115,
862                116, 115, 58, 58, 77, 121, 67, 111, 109, 112, 111, 110, 101, 110, 116, 147, 147, 1,
863                2, 3, 146, 202, 63, 166, 102, 102, 202, 64, 108, 204, 205, 129, 165, 84, 117, 112,
864                108, 101, 172, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33
865            ],
866            buf
867        );
868
869        let scene_deserializer = SceneDeserializer {
870            type_registry: registry,
871        };
872        let mut reader = BufReader::new(buf.as_slice());
873
874        let deserialized_scene = scene_deserializer
875            .deserialize(&mut rmp_serde::Deserializer::new(&mut reader))
876            .unwrap();
877
878        assert_eq!(1, deserialized_scene.entities.len());
879        assert_scene_eq(&scene, &deserialized_scene);
880    }
881
882    #[test]
883    fn should_roundtrip_bincode() {
884        let mut world = create_world();
885
886        world.spawn(MyComponent {
887            foo: [1, 2, 3],
888            bar: (1.3, 3.7),
889            baz: MyEnum::Tuple("Hello World!".to_string()),
890        });
891
892        let registry = world.resource::<AppTypeRegistry>();
893        let registry = &registry.read();
894
895        let scene = DynamicScene::from_world(&world);
896
897        let scene_serializer = SceneSerializer::new(&scene, registry);
898        let serialized_scene = bincode::serialize(&scene_serializer).unwrap();
899
900        assert_eq!(
901            vec![
902                0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0,
903                0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 115, 99, 101, 110, 101,
904                58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, 121,
905                67, 111, 109, 112, 111, 110, 101, 110, 116, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0,
906                0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 102, 102, 166, 63, 205, 204, 108, 64, 1, 0, 0, 0,
907                12, 0, 0, 0, 0, 0, 0, 0, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33
908            ],
909            serialized_scene
910        );
911
912        let scene_deserializer = SceneDeserializer {
913            type_registry: registry,
914        };
915
916        let deserialized_scene = bincode::DefaultOptions::new()
917            .with_fixint_encoding()
918            .deserialize_seed(scene_deserializer, &serialized_scene)
919            .unwrap();
920
921        assert_eq!(1, deserialized_scene.entities.len());
922        assert_scene_eq(&scene, &deserialized_scene);
923    }
924
925    /// A crude equality checker for [`DynamicScene`], used solely for testing purposes.
926    fn assert_scene_eq(expected: &DynamicScene, received: &DynamicScene) {
927        assert_eq!(
928            expected.entities.len(),
929            received.entities.len(),
930            "entity count did not match",
931        );
932
933        for expected in &expected.entities {
934            let received = received
935                .entities
936                .iter()
937                .find(|dynamic_entity| dynamic_entity.entity == expected.entity)
938                .unwrap_or_else(|| panic!("missing entity (expected: `{:?}`)", expected.entity));
939
940            assert_eq!(expected.entity, received.entity, "entities did not match");
941
942            for expected in &expected.components {
943                let received = received
944                    .components
945                    .iter()
946                    .find(|component| {
947                        component.get_represented_type_info().unwrap().type_path()
948                            == expected.get_represented_type_info().unwrap().type_path()
949                    })
950                    .unwrap_or_else(|| {
951                        panic!(
952                            "missing component (expected: `{}`)",
953                            expected.get_represented_type_info().unwrap().type_path()
954                        )
955                    });
956
957                assert!(
958                    expected
959                        .reflect_partial_eq(received.as_ref())
960                        .unwrap_or_default(),
961                    "components did not match: (expected: `{expected:?}`, received: `{received:?}`)",
962                );
963            }
964        }
965    }
966
967    /// These tests just verify that the [`assert_scene_eq`] function is working properly for our tests.
968    mod assert_scene_eq_tests {
969        use super::*;
970
971        #[test]
972        #[should_panic(expected = "entity count did not match")]
973        fn should_panic_when_entity_count_not_eq() {
974            let mut world = create_world();
975            let scene_a = DynamicScene::from_world(&world);
976
977            world.spawn(MyComponent {
978                foo: [1, 2, 3],
979                bar: (1.3, 3.7),
980                baz: MyEnum::Unit,
981            });
982
983            let scene_b = DynamicScene::from_world(&world);
984
985            assert_scene_eq(&scene_a, &scene_b);
986        }
987
988        #[test]
989        #[should_panic(expected = "components did not match")]
990        fn should_panic_when_components_not_eq() {
991            let mut world = create_world();
992
993            let entity = world
994                .spawn(MyComponent {
995                    foo: [1, 2, 3],
996                    bar: (1.3, 3.7),
997                    baz: MyEnum::Unit,
998                })
999                .id();
1000
1001            let scene_a = DynamicScene::from_world(&world);
1002
1003            world.entity_mut(entity).insert(MyComponent {
1004                foo: [3, 2, 1],
1005                bar: (1.3, 3.7),
1006                baz: MyEnum::Unit,
1007            });
1008
1009            let scene_b = DynamicScene::from_world(&world);
1010
1011            assert_scene_eq(&scene_a, &scene_b);
1012        }
1013
1014        #[test]
1015        #[should_panic(expected = "missing component")]
1016        fn should_panic_when_missing_component() {
1017            let mut world = create_world();
1018
1019            let entity = world
1020                .spawn(MyComponent {
1021                    foo: [1, 2, 3],
1022                    bar: (1.3, 3.7),
1023                    baz: MyEnum::Unit,
1024                })
1025                .id();
1026
1027            let scene_a = DynamicScene::from_world(&world);
1028
1029            world.entity_mut(entity).remove::<MyComponent>();
1030
1031            let scene_b = DynamicScene::from_world(&world);
1032
1033            assert_scene_eq(&scene_a, &scene_b);
1034        }
1035    }
1036}