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_platform::collections::HashSet;
6use bevy_reflect::{
7    serde::{
8        ReflectDeserializer, TypeRegistrationDeserializer, TypedReflectDeserializer,
9        TypedReflectSerializer,
10    },
11    PartialReflect, ReflectFromReflect, TypeRegistry,
12};
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, _)| *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<_>>::default();
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},
519        prelude::{Component, ReflectComponent, ReflectResource, Resource, World},
520        query::{With, Without},
521        reflect::AppTypeRegistry,
522        world::FromWorld,
523    };
524    use bevy_reflect::{Reflect, ReflectDeserialize, ReflectSerialize};
525    use serde::{de::DeserializeSeed, Deserialize, Serialize};
526    use std::io::BufReader;
527
528    #[derive(Component, Reflect, Default)]
529    #[reflect(Component)]
530    struct Foo(i32);
531    #[derive(Component, Reflect, Default)]
532    #[reflect(Component)]
533    struct Bar(i32);
534    #[derive(Component, Reflect, Default)]
535    #[reflect(Component)]
536    struct Baz(i32);
537
538    // De/serialize as hex.
539    mod qux {
540        use serde::{de::Error, Deserialize, Deserializer, Serializer};
541
542        pub fn serialize<S>(value: &u32, serializer: S) -> Result<S::Ok, S::Error>
543        where
544            S: Serializer,
545        {
546            serializer.serialize_str(&format!("{value:X}"))
547        }
548
549        pub fn deserialize<'de, D>(deserializer: D) -> Result<u32, D::Error>
550        where
551            D: Deserializer<'de>,
552        {
553            u32::from_str_radix(<&str as Deserialize>::deserialize(deserializer)?, 16)
554                .map_err(Error::custom)
555        }
556    }
557
558    #[derive(Component, Copy, Clone, Reflect, Debug, PartialEq, Serialize, Deserialize)]
559    #[reflect(Component, Serialize, Deserialize)]
560    struct Qux(#[serde(with = "qux")] u32);
561
562    #[derive(Component, Reflect, Default)]
563    #[reflect(Component)]
564    struct MyComponent {
565        foo: [usize; 3],
566        bar: (f32, f32),
567        baz: MyEnum,
568    }
569
570    #[derive(Reflect, Default)]
571    enum MyEnum {
572        #[default]
573        Unit,
574        Tuple(String),
575        Struct {
576            value: u32,
577        },
578    }
579
580    #[derive(Resource, Reflect, Default)]
581    #[reflect(Resource)]
582    struct MyResource {
583        foo: i32,
584    }
585
586    #[derive(Clone, Component, Reflect, PartialEq)]
587    #[reflect(Component, PartialEq)]
588    struct MyEntityRef(#[entities] Entity);
589
590    impl FromWorld for MyEntityRef {
591        fn from_world(_world: &mut World) -> Self {
592            Self(Entity::PLACEHOLDER)
593        }
594    }
595
596    fn create_world() -> World {
597        let mut world = World::new();
598        let registry = AppTypeRegistry::default();
599        {
600            let mut registry = registry.write();
601            registry.register::<Foo>();
602            registry.register::<Bar>();
603            registry.register::<Baz>();
604            registry.register::<Qux>();
605            registry.register::<MyComponent>();
606            registry.register::<MyEnum>();
607            registry.register::<String>();
608            registry.register_type_data::<String, ReflectSerialize>();
609            registry.register::<[usize; 3]>();
610            registry.register::<(f32, f32)>();
611            registry.register::<MyEntityRef>();
612            registry.register::<Entity>();
613            registry.register::<MyResource>();
614        }
615        world.insert_resource(registry);
616        world
617    }
618
619    #[test]
620    fn should_serialize() {
621        let mut world = create_world();
622
623        let a = world.spawn(Foo(123)).id();
624        let b = world.spawn((Foo(123), Bar(345))).id();
625        let c = world.spawn((Foo(123), Bar(345), Baz(789))).id();
626
627        world.insert_resource(MyResource { foo: 123 });
628
629        let scene = DynamicSceneBuilder::from_world(&world)
630            .extract_entities([a, b, c].into_iter())
631            .extract_resources()
632            .build();
633
634        let expected = r#"(
635  resources: {
636    "bevy_scene::serde::tests::MyResource": (
637      foo: 123,
638    ),
639  },
640  entities: {
641    4294967293: (
642      components: {
643        "bevy_scene::serde::tests::Bar": (345),
644        "bevy_scene::serde::tests::Baz": (789),
645        "bevy_scene::serde::tests::Foo": (123),
646      },
647    ),
648    4294967294: (
649      components: {
650        "bevy_scene::serde::tests::Bar": (345),
651        "bevy_scene::serde::tests::Foo": (123),
652      },
653    ),
654    4294967295: (
655      components: {
656        "bevy_scene::serde::tests::Foo": (123),
657      },
658    ),
659  },
660)"#;
661        let output = scene
662            .serialize(&world.resource::<AppTypeRegistry>().read())
663            .unwrap();
664        assert_eq!(expected, output);
665    }
666
667    #[test]
668    fn should_deserialize() {
669        let world = create_world();
670
671        let input = r#"(
672  resources: {
673    "bevy_scene::serde::tests::MyResource": (
674      foo: 123,
675    ),
676  },
677  entities: {
678    8589934591: (
679      components: {
680        "bevy_scene::serde::tests::Foo": (123),
681      },
682    ),
683    8589934590: (
684      components: {
685        "bevy_scene::serde::tests::Foo": (123),
686        "bevy_scene::serde::tests::Bar": (345),
687      },
688    ),
689    8589934589: (
690      components: {
691        "bevy_scene::serde::tests::Foo": (123),
692        "bevy_scene::serde::tests::Bar": (345),
693        "bevy_scene::serde::tests::Baz": (789),
694      },
695    ),
696  },
697)"#;
698        let mut deserializer = ron::de::Deserializer::from_str(input).unwrap();
699        let scene_deserializer = SceneDeserializer {
700            type_registry: &world.resource::<AppTypeRegistry>().read(),
701        };
702        let scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
703
704        assert_eq!(
705            1,
706            scene.resources.len(),
707            "expected `resources` to contain 1 resource"
708        );
709        assert_eq!(
710            3,
711            scene.entities.len(),
712            "expected `entities` to contain 3 entities"
713        );
714
715        let mut map = EntityHashMap::default();
716        let mut dst_world = create_world();
717        scene.write_to_world(&mut dst_world, &mut map).unwrap();
718
719        let my_resource = dst_world.get_resource::<MyResource>();
720        assert!(my_resource.is_some());
721        let my_resource = my_resource.unwrap();
722        assert_eq!(my_resource.foo, 123);
723
724        assert_eq!(3, dst_world.query::<&Foo>().iter(&dst_world).count());
725        assert_eq!(2, dst_world.query::<&Bar>().iter(&dst_world).count());
726        assert_eq!(1, dst_world.query::<&Baz>().iter(&dst_world).count());
727    }
728
729    fn roundtrip_ron(world: &World) -> (DynamicScene, DynamicScene) {
730        let scene = DynamicScene::from_world(world);
731        let registry = world.resource::<AppTypeRegistry>().read();
732        let serialized = scene.serialize(&registry).unwrap();
733        let mut deserializer = ron::de::Deserializer::from_str(&serialized).unwrap();
734        let scene_deserializer = SceneDeserializer {
735            type_registry: &registry,
736        };
737        let deserialized_scene = scene_deserializer.deserialize(&mut deserializer).unwrap();
738        (scene, deserialized_scene)
739    }
740
741    #[test]
742    fn should_roundtrip_with_later_generations_and_obsolete_references() {
743        let mut world = create_world();
744
745        world.spawn_empty().despawn();
746
747        let a = world.spawn_empty().id();
748        let foo = world.spawn(MyEntityRef(a)).insert(Foo(123)).id();
749        world.despawn(a);
750        world.spawn(MyEntityRef(foo)).insert(Bar(123));
751
752        let (scene, deserialized_scene) = roundtrip_ron(&world);
753
754        let mut map = EntityHashMap::default();
755        let mut dst_world = create_world();
756        deserialized_scene
757            .write_to_world(&mut dst_world, &mut map)
758            .unwrap();
759
760        assert_eq!(2, deserialized_scene.entities.len());
761        assert_scene_eq(&scene, &deserialized_scene);
762
763        let bar_to_foo = dst_world
764            .query_filtered::<&MyEntityRef, Without<Foo>>()
765            .single(&dst_world)
766            .cloned()
767            .unwrap();
768        let foo = dst_world
769            .query_filtered::<Entity, With<Foo>>()
770            .single(&dst_world)
771            .unwrap();
772
773        assert_eq!(foo, bar_to_foo.0);
774        assert!(dst_world
775            .query_filtered::<&MyEntityRef, With<Foo>>()
776            .iter(&dst_world)
777            .all(|r| world.get_entity(r.0).is_err()));
778    }
779
780    #[test]
781    fn should_roundtrip_with_custom_serialization() {
782        let mut world = create_world();
783        let qux = Qux(42);
784        world.spawn(qux);
785
786        let (scene, deserialized_scene) = roundtrip_ron(&world);
787
788        assert_eq!(1, deserialized_scene.entities.len());
789        assert_scene_eq(&scene, &deserialized_scene);
790
791        let mut world = create_world();
792        deserialized_scene
793            .write_to_world(&mut world, &mut EntityHashMap::default())
794            .unwrap();
795        assert_eq!(&qux, world.query::<&Qux>().single(&world).unwrap());
796    }
797
798    #[test]
799    fn should_roundtrip_postcard() {
800        let mut world = create_world();
801
802        world.spawn(MyComponent {
803            foo: [1, 2, 3],
804            bar: (1.3, 3.7),
805            baz: MyEnum::Tuple("Hello World!".to_string()),
806        });
807
808        let registry = world.resource::<AppTypeRegistry>();
809        let registry = &registry.read();
810
811        let scene = DynamicScene::from_world(&world);
812
813        let scene_serializer = SceneSerializer::new(&scene, registry);
814        let serialized_scene = postcard::to_allocvec(&scene_serializer).unwrap();
815
816        assert_eq!(
817            vec![
818                0, 1, 255, 255, 255, 255, 15, 1, 37, 98, 101, 118, 121, 95, 115, 99, 101, 110, 101,
819                58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58, 77, 121,
820                67, 111, 109, 112, 111, 110, 101, 110, 116, 1, 2, 3, 102, 102, 166, 63, 205, 204,
821                108, 64, 1, 12, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33
822            ],
823            serialized_scene
824        );
825
826        let scene_deserializer = SceneDeserializer {
827            type_registry: registry,
828        };
829        let deserialized_scene = scene_deserializer
830            .deserialize(&mut postcard::Deserializer::from_bytes(&serialized_scene))
831            .unwrap();
832
833        assert_eq!(1, deserialized_scene.entities.len());
834        assert_scene_eq(&scene, &deserialized_scene);
835    }
836
837    #[test]
838    fn should_roundtrip_messagepack() {
839        let mut world = create_world();
840
841        world.spawn(MyComponent {
842            foo: [1, 2, 3],
843            bar: (1.3, 3.7),
844            baz: MyEnum::Tuple("Hello World!".to_string()),
845        });
846
847        let registry = world.resource::<AppTypeRegistry>();
848        let registry = &registry.read();
849
850        let scene = DynamicScene::from_world(&world);
851
852        let scene_serializer = SceneSerializer::new(&scene, registry);
853        let mut buf = Vec::new();
854        let mut ser = rmp_serde::Serializer::new(&mut buf);
855        scene_serializer.serialize(&mut ser).unwrap();
856
857        assert_eq!(
858            vec![
859                146, 128, 129, 206, 255, 255, 255, 255, 145, 129, 217, 37, 98, 101, 118, 121, 95,
860                115, 99, 101, 110, 101, 58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115,
861                116, 115, 58, 58, 77, 121, 67, 111, 109, 112, 111, 110, 101, 110, 116, 147, 147, 1,
862                2, 3, 146, 202, 63, 166, 102, 102, 202, 64, 108, 204, 205, 129, 165, 84, 117, 112,
863                108, 101, 172, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100, 33
864            ],
865            buf
866        );
867
868        let scene_deserializer = SceneDeserializer {
869            type_registry: registry,
870        };
871        let mut reader = BufReader::new(buf.as_slice());
872
873        let deserialized_scene = scene_deserializer
874            .deserialize(&mut rmp_serde::Deserializer::new(&mut reader))
875            .unwrap();
876
877        assert_eq!(1, deserialized_scene.entities.len());
878        assert_scene_eq(&scene, &deserialized_scene);
879    }
880
881    #[test]
882    fn should_roundtrip_bincode() {
883        let mut world = create_world();
884
885        world.spawn(MyComponent {
886            foo: [1, 2, 3],
887            bar: (1.3, 3.7),
888            baz: MyEnum::Tuple("Hello World!".to_string()),
889        });
890
891        let registry = world.resource::<AppTypeRegistry>();
892        let registry = &registry.read();
893
894        let scene = DynamicScene::from_world(&world);
895
896        let config = bincode::config::standard().with_fixed_int_encoding();
897        let scene_serializer = SceneSerializer::new(&scene, registry);
898        let serialized_scene = bincode::serde::encode_to_vec(&scene_serializer, config).unwrap();
899
900        assert_eq!(
901            vec![
902                0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1,
903                0, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 0, 0, 0, 98, 101, 118, 121, 95, 115, 99, 101,
904                110, 101, 58, 58, 115, 101, 114, 100, 101, 58, 58, 116, 101, 115, 116, 115, 58, 58,
905                77, 121, 67, 111, 109, 112, 111, 110, 101, 110, 116, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0,
906                0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 102, 102, 166, 63, 205, 204, 108, 64, 1,
907                0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 72, 101, 108, 108, 111, 32, 87, 111, 114, 108,
908                100, 33
909            ],
910            serialized_scene
911        );
912
913        let scene_deserializer = SceneDeserializer {
914            type_registry: registry,
915        };
916
917        let (deserialized_scene, _read_bytes) =
918            bincode::serde::seed_decode_from_slice(scene_deserializer, &serialized_scene, config)
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}