despero_hecs/serialize/
column.rs

1//! Fast column-major serialization
2//!
3//! Stores each archetype in a block where each type of component is laid out
4//! contiguously. Preferred for data that will be read/written programmatically. Efficient, compact,
5//! and highly compressible, but difficult to read or edit by hand.
6//!
7//! This module builds on the public archetype-related APIs and [`World::spawn_column_batch_at()`],
8//! and is somewhat opinionated. For some applications, a custom approach may be preferable.
9//!
10//! In terms of the serde data model, we treat a [`World`] as a sequence of archetypes, where each
11//! archetype is a 4-tuple of an entity count `n`, component count `k`, a `k`-tuple of
12//! user-controlled component IDs, and a `k+1`-tuple of `n`-tuples of components, such that the
13//! first `n`-tuple contains `Entity` values and the remainder each contain components of the type
14//! identified by the corresponding component ID.
15
16use crate::alloc::vec::Vec;
17use core::{any::type_name, cell::RefCell, fmt, marker::PhantomData};
18
19use serde::{
20    de::{self, DeserializeSeed, SeqAccess, Unexpected, Visitor},
21    ser::{SerializeSeq, SerializeTuple},
22    Deserialize, Deserializer, Serialize, Serializer,
23};
24
25use crate::{
26    Archetype, ColumnBatch, ColumnBatchBuilder, ColumnBatchType, Component, Entity, World,
27};
28
29/// Implements serialization of archetypes
30///
31/// `serialize_component_ids` and `serialize_components` must serialize exactly the number of
32/// elements indicated by `component_count` or return `Err`.
33///
34/// Data external to the [`World`] can be exposed during serialization by storing references inside
35/// the struct implementing this trait.
36///
37/// # Example
38///
39/// ```
40/// # use serde::{Serialize, Deserialize};
41/// # #[derive(Serialize)]
42/// # struct Position([f32; 3]);
43/// # #[derive(Serialize)]
44/// # struct Velocity([f32; 3]);
45/// use std::any::TypeId;
46/// use hecs::{*, serialize::column::*};
47///
48/// #[derive(Serialize, Deserialize)]
49/// enum ComponentId { Position, Velocity }
50///
51/// struct Context;
52///
53/// impl SerializeContext for Context {
54///     fn component_count(&self, archetype: &Archetype) -> usize {
55///         archetype.component_types()
56///             .filter(|&t| t == TypeId::of::<Position>() || t == TypeId::of::<Velocity>())
57///             .count()
58///     }
59///
60///     fn serialize_component_ids<S: serde::ser::SerializeTuple>(
61///         &mut self,
62///         archetype: &Archetype,
63///         mut out: S,
64///     ) -> Result<S::Ok, S::Error> {
65///         try_serialize_id::<Position, _, _>(archetype, &ComponentId::Position, &mut out)?;
66///         try_serialize_id::<Velocity, _, _>(archetype, &ComponentId::Velocity, &mut out)?;
67///         out.end()
68///     }
69///
70///     fn serialize_components<S: serde::ser::SerializeTuple>(
71///         &mut self,
72///         archetype: &Archetype,
73///         mut out: S,
74///     ) -> Result<S::Ok, S::Error> {
75///         try_serialize::<Position, _>(archetype, &mut out)?;
76///         try_serialize::<Velocity, _>(archetype, &mut out)?;
77///         out.end()
78///     }
79/// }
80/// ```
81// Serializing the ID tuple separately from component data allows the deserializer to allocate the
82// entire output archetype up front, rather than having to allocate storage for each component type
83// after processing the previous one and copy into an archetype at the end.
84pub trait SerializeContext {
85    /// Number of entries that [`serialize_component_ids`](Self::serialize_component_ids) and
86    /// [`serialize_components`](Self::serialize_components) will produce for `archetype`
87    fn component_count(&self, archetype: &Archetype) -> usize;
88
89    /// Serialize the IDs of the components from `archetype` that will be serialized
90    // We use a wrapper here rather than exposing the serde type directly because it's a huge pain
91    // to determine how many IDs were written otherwise, and we need that to set the component data
92    // tuple length correctly.
93    fn serialize_component_ids<S: SerializeTuple>(
94        &mut self,
95        archetype: &Archetype,
96        out: S,
97    ) -> Result<S::Ok, S::Error>;
98
99    /// Serialize component data from `archetype` into `out`
100    ///
101    /// For each component ID written by `serialize_component_ids`, this method must write a tuple
102    /// containing one value for each entity, e.g. using [`try_serialize`], in the same order. Each
103    /// tuple's length must exactly match the number of entities in `archetype`, and there must be
104    /// exactly the same number of tuples as there were IDs.
105    fn serialize_components<S: SerializeTuple>(
106        &mut self,
107        archetype: &Archetype,
108        out: S,
109    ) -> Result<S::Ok, S::Error>;
110}
111
112/// If `archetype` has `T` components, serialize `id` into `S`
113pub fn try_serialize_id<T, I, S>(archetype: &Archetype, id: &I, out: &mut S) -> Result<(), S::Error>
114where
115    T: Component,
116    I: Serialize + ?Sized,
117    S: SerializeTuple,
118{
119    if archetype.has::<T>() {
120        out.serialize_element(id)?;
121    }
122    Ok(())
123}
124
125/// If `archetype` has `T` components, serialize them into `out`
126///
127/// Useful for implementing [`SerializeContext::serialize_components()`].
128pub fn try_serialize<T, S>(archetype: &Archetype, out: &mut S) -> Result<(), S::Error>
129where
130    T: Component + Serialize,
131    S: SerializeTuple,
132{
133    if let Some(xs) = archetype.get::<&T>() {
134        serialize_collection(&*xs, out)?;
135    }
136    Ok(())
137}
138
139/// Serialize components from `collection` into a single element of `out`
140fn serialize_collection<I, S>(collection: I, out: &mut S) -> Result<(), S::Error>
141where
142    I: IntoIterator,
143    I::IntoIter: ExactSizeIterator,
144    I::Item: Serialize,
145    S: SerializeTuple,
146{
147    struct SerializeColumn<I>(RefCell<I>);
148
149    impl<I> Serialize for SerializeColumn<I>
150    where
151        I: ExactSizeIterator,
152        I::Item: Serialize,
153    {
154        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
155        where
156            S: Serializer,
157        {
158            let mut iter = self.0.borrow_mut();
159            let mut tuple = serializer.serialize_tuple(iter.len())?;
160            for x in &mut *iter {
161                tuple.serialize_element(&x)?;
162            }
163            tuple.end()
164        }
165    }
166
167    out.serialize_element(&SerializeColumn(RefCell::new(collection.into_iter())))
168}
169
170/// Serialize a [`World`] through a [`SerializeContext`] to a [`Serializer`]
171pub fn serialize<C, S>(world: &World, context: &mut C, serializer: S) -> Result<S::Ok, S::Error>
172where
173    S: Serializer,
174    C: SerializeContext,
175{
176    struct SerializeArchetype<'a, C> {
177        world: &'a World,
178        archetype: &'a Archetype,
179        ctx: RefCell<&'a mut C>,
180    }
181
182    impl<C> Serialize for SerializeArchetype<'_, C>
183    where
184        C: SerializeContext,
185    {
186        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
187        where
188            S: Serializer,
189        {
190            let ctx = &mut *self.ctx.borrow_mut();
191            let mut tuple = serializer.serialize_tuple(4)?;
192            tuple.serialize_element(&self.archetype.len())?;
193            let components = ctx.component_count(self.archetype);
194            tuple.serialize_element(&(components as u32))?;
195            let helper = SerializeComponentIds::<'_, C> {
196                archetype: self.archetype,
197                ctx: RefCell::new(ctx),
198                components,
199            };
200            tuple.serialize_element(&helper)?;
201            tuple.serialize_element(&SerializeComponents::<'_, C> {
202                world: self.world,
203                archetype: self.archetype,
204                ctx: RefCell::new(ctx),
205                components,
206            })?;
207            tuple.end()
208        }
209    }
210
211    struct SerializeComponentIds<'a, C> {
212        archetype: &'a Archetype,
213        ctx: RefCell<&'a mut C>,
214        components: usize,
215    }
216
217    impl<C> Serialize for SerializeComponentIds<'_, C>
218    where
219        C: SerializeContext,
220    {
221        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
222        where
223            S: Serializer,
224        {
225            let tuple = serializer.serialize_tuple(self.components)?;
226            self.ctx
227                .borrow_mut()
228                .serialize_component_ids(self.archetype, tuple)
229        }
230    }
231
232    struct SerializeComponents<'a, C> {
233        world: &'a World,
234        archetype: &'a Archetype,
235        ctx: RefCell<&'a mut C>,
236        components: usize,
237    }
238
239    impl<C> Serialize for SerializeComponents<'_, C>
240    where
241        C: SerializeContext,
242    {
243        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
244        where
245            S: Serializer,
246        {
247            let ctx = &mut *self.ctx.borrow_mut();
248            let mut tuple = serializer.serialize_tuple(self.components + 1)?;
249
250            // Serialize entity IDs
251            tuple.serialize_element(&SerializeEntities {
252                world: self.world,
253                ids: self.archetype.ids(),
254            })?;
255
256            // Serialize component data
257            ctx.serialize_components(self.archetype, tuple)
258        }
259    }
260
261    struct SerializeEntities<'a> {
262        world: &'a World,
263        ids: &'a [u32],
264    }
265
266    impl Serialize for SerializeEntities<'_> {
267        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
268        where
269            S: Serializer,
270        {
271            let mut tuple = serializer.serialize_tuple(self.ids.len())?;
272            for &id in self.ids {
273                let entity = unsafe { self.world.find_entity_from_id(id) };
274                tuple.serialize_element(&entity)?;
275            }
276            tuple.end()
277        }
278    }
279
280    let mut seq =
281        serializer.serialize_seq(Some(world.archetypes().filter(|x| !x.is_empty()).count()))?;
282    for archetype in world.archetypes().filter(|x| !x.is_empty()) {
283        seq.serialize_element(&SerializeArchetype {
284            world,
285            archetype,
286            ctx: RefCell::new(context),
287        })?;
288    }
289    seq.end()
290}
291
292/// Implements deserialization of archetypes
293///
294/// # Example
295///
296/// ```
297/// # use serde::{Serialize, Deserialize};
298/// # #[derive(Deserialize)]
299/// # struct Position([f32; 3]);
300/// # #[derive(Deserialize)]
301/// # struct Velocity([f32; 3]);
302/// use hecs::{*, serialize::column::*};
303///
304/// #[derive(Serialize, Deserialize)]
305/// enum ComponentId { Position, Velocity }
306///
307/// // Could include references to external state for use by serialization methods
308/// struct Context {
309///     /// Components of the archetype currently being deserialized
310///     components: Vec<ComponentId>,
311/// }
312///
313/// impl DeserializeContext for Context {
314///     fn deserialize_component_ids<'de, A>(
315///         &mut self,
316///         mut seq: A,
317///     ) -> Result<ColumnBatchType, A::Error>
318///     where
319///         A: serde::de::SeqAccess<'de>,
320///     {
321///         self.components.clear(); // Discard data from the previous archetype
322///         let mut batch = ColumnBatchType::new();
323///         while let Some(id) = seq.next_element()? {
324///             match id {
325///                 ComponentId::Position => {
326///                     batch.add::<Position>();
327///                 }
328///                 ComponentId::Velocity => {
329///                     batch.add::<Velocity>();
330///                 }
331///             }
332///             self.components.push(id);
333///         }
334///         Ok(batch)
335///     }
336///
337///     fn deserialize_components<'de, A>(
338///         &mut self,
339///         entity_count: u32,
340///         mut seq: A,
341///         batch: &mut ColumnBatchBuilder,
342///     ) -> Result<(), A::Error>
343///     where
344///         A: serde::de::SeqAccess<'de>,
345///     {
346///         // Decode component data in the order that the component IDs appeared
347///         for component in &self.components {
348///             match *component {
349///                 ComponentId::Position => {
350///                     deserialize_column::<Position, _>(entity_count, &mut seq, batch)?;
351///                 }
352///                 ComponentId::Velocity => {
353///                     deserialize_column::<Velocity, _>(entity_count, &mut seq, batch)?;
354///                 }
355///             }
356///         }
357///         Ok(())
358///     }
359/// }
360pub trait DeserializeContext {
361    /// Deserialize a set of component IDs
362    ///
363    /// Implementers should usually store the deserialized component IDs in `self` to guide the
364    /// following `deserialize_components` call.
365    fn deserialize_component_ids<'de, A>(&mut self, seq: A) -> Result<ColumnBatchType, A::Error>
366    where
367        A: SeqAccess<'de>;
368
369    /// Deserialize all component data for an archetype
370    ///
371    /// `seq` is a sequence of tuples directly corresponding to the IDs read in
372    /// `deserialize_component_ids`, each containing `entity_count` elements.
373    fn deserialize_components<'de, A>(
374        &mut self,
375        entity_count: u32,
376        seq: A,
377        batch: &mut ColumnBatchBuilder,
378    ) -> Result<(), A::Error>
379    where
380        A: SeqAccess<'de>;
381}
382
383/// Deserialize a column of `entity_count` `T`s from `seq` into `out`
384pub fn deserialize_column<'de, T, A>(
385    entity_count: u32,
386    seq: &mut A,
387    out: &mut ColumnBatchBuilder,
388) -> Result<(), A::Error>
389where
390    T: Component + Deserialize<'de>,
391    A: SeqAccess<'de>,
392{
393    seq.next_element_seed(DeserializeColumn::<T>::new(entity_count, out))?
394        .ok_or_else(|| {
395            de::Error::invalid_value(
396                Unexpected::Other("end of components"),
397                &"a column of components",
398            )
399        })
400}
401
402/// Deserializer for a single component type, for use in [`DeserializeContext::deserialize_components()`]
403struct DeserializeColumn<'a, T> {
404    entity_count: u32,
405    out: &'a mut ColumnBatchBuilder,
406    marker: PhantomData<fn() -> T>,
407}
408
409impl<'de, 'a, T> DeserializeColumn<'a, T>
410where
411    T: Component + Deserialize<'de>,
412{
413    /// Construct a deserializer for `entity_count` `T` components, writing into `batch`
414    pub fn new(entity_count: u32, batch: &'a mut ColumnBatchBuilder) -> Self {
415        Self {
416            entity_count,
417            out: batch,
418            marker: PhantomData,
419        }
420    }
421}
422
423impl<'de, 'a, T> DeserializeSeed<'de> for DeserializeColumn<'a, T>
424where
425    T: Component + Deserialize<'de>,
426{
427    type Value = ();
428
429    fn deserialize<D>(self, deserializer: D) -> Result<(), D::Error>
430    where
431        D: Deserializer<'de>,
432    {
433        deserializer.deserialize_tuple(
434            self.entity_count as usize,
435            ColumnVisitor::<T> {
436                entity_count: self.entity_count,
437                out: self.out,
438                marker: PhantomData,
439            },
440        )
441    }
442}
443
444struct ColumnVisitor<'a, T> {
445    entity_count: u32,
446    out: &'a mut ColumnBatchBuilder,
447    marker: PhantomData<fn() -> T>,
448}
449
450impl<'de, 'a, T> Visitor<'de> for ColumnVisitor<'a, T>
451where
452    T: Component + Deserialize<'de>,
453{
454    type Value = ();
455
456    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
457        write!(
458            formatter,
459            "a set of {} {} values",
460            self.entity_count,
461            type_name::<T>()
462        )
463    }
464
465    fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
466    where
467        A: SeqAccess<'de>,
468    {
469        let mut out = self.out.writer::<T>().expect("unexpected component type");
470        while let Some(component) = seq.next_element()? {
471            if out.push(component).is_err() {
472                return Err(de::Error::invalid_value(
473                    Unexpected::Other("extra component"),
474                    &self,
475                ));
476            }
477        }
478        if out.fill() < self.entity_count {
479            return Err(de::Error::invalid_length(out.fill() as usize, &self));
480        }
481        Ok(())
482    }
483}
484
485/// Deserialize a [`World`] with a [`DeserializeContext`] and a [`Deserializer`]
486pub fn deserialize<'de, C, D>(context: &mut C, deserializer: D) -> Result<World, D::Error>
487where
488    C: DeserializeContext,
489    D: Deserializer<'de>,
490{
491    deserializer.deserialize_seq(WorldVisitor(context))
492}
493
494struct WorldVisitor<'a, C>(&'a mut C);
495
496impl<'de, 'a, C> Visitor<'de> for WorldVisitor<'a, C>
497where
498    C: DeserializeContext,
499{
500    type Value = World;
501
502    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
503        formatter.write_str("a sequence of archetypes")
504    }
505
506    fn visit_seq<A>(self, mut seq: A) -> Result<World, A::Error>
507    where
508        A: SeqAccess<'de>,
509    {
510        let mut world = World::new();
511        let mut entities = Vec::new();
512        while let Some(bundle) =
513            seq.next_element_seed(DeserializeArchetype(self.0, &mut entities))?
514        {
515            world.spawn_column_batch_at(&entities, bundle);
516            entities.clear();
517        }
518        Ok(world)
519    }
520}
521
522struct DeserializeArchetype<'a, C>(&'a mut C, &'a mut Vec<Entity>);
523
524impl<'de, 'a, C> DeserializeSeed<'de> for DeserializeArchetype<'a, C>
525where
526    C: DeserializeContext,
527{
528    type Value = ColumnBatch;
529
530    fn deserialize<D>(self, deserializer: D) -> Result<ColumnBatch, D::Error>
531    where
532        D: Deserializer<'de>,
533    {
534        deserializer.deserialize_tuple(4, ArchetypeVisitor(self.0, self.1))
535    }
536}
537
538struct ArchetypeVisitor<'a, C>(&'a mut C, &'a mut Vec<Entity>);
539
540impl<'de, 'a, C> Visitor<'de> for ArchetypeVisitor<'a, C>
541where
542    C: DeserializeContext,
543{
544    type Value = ColumnBatch;
545
546    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
547        formatter.write_str("a 4-tuple of an entity count, a component count, a component ID list, and a component value list")
548    }
549
550    fn visit_seq<A>(self, mut seq: A) -> Result<ColumnBatch, A::Error>
551    where
552        A: SeqAccess<'de>,
553    {
554        let entity_count = seq
555            .next_element::<u32>()?
556            .ok_or_else(|| de::Error::invalid_length(0, &self))?;
557        let component_count = seq
558            .next_element::<u32>()?
559            .ok_or_else(|| de::Error::invalid_length(1, &self))?;
560        self.1.reserve(entity_count as usize);
561        let ty = seq
562            .next_element_seed(DeserializeComponentIds(self.0, component_count))?
563            .ok_or_else(|| de::Error::invalid_length(2, &self))?;
564        let mut batch = ty.into_batch(entity_count);
565        seq.next_element_seed(DeserializeComponents {
566            ctx: self.0,
567            entity_count,
568            component_count,
569            entities: self.1,
570            out: &mut batch,
571        })?
572        .ok_or_else(|| de::Error::invalid_length(3, &self))?;
573        batch.build().map_err(|_| {
574            de::Error::invalid_value(
575                Unexpected::Other("incomplete archetype"),
576                &"a complete archetype",
577            )
578        })
579    }
580}
581
582struct DeserializeComponentIds<'a, C>(&'a mut C, u32);
583
584impl<'de, 'a, C> DeserializeSeed<'de> for DeserializeComponentIds<'a, C>
585where
586    C: DeserializeContext,
587{
588    type Value = ColumnBatchType;
589
590    fn deserialize<D>(self, deserializer: D) -> Result<ColumnBatchType, D::Error>
591    where
592        D: Deserializer<'de>,
593    {
594        deserializer.deserialize_tuple(self.1 as usize, ComponentIdVisitor(self.0, self.1))
595    }
596}
597
598struct ComponentIdVisitor<'a, C>(&'a mut C, u32);
599
600impl<'de, 'a, C> Visitor<'de> for ComponentIdVisitor<'a, C>
601where
602    C: DeserializeContext,
603{
604    type Value = ColumnBatchType;
605
606    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
607        write!(f, "a set of {} component IDs", self.1)
608    }
609
610    fn visit_seq<A>(self, seq: A) -> Result<ColumnBatchType, A::Error>
611    where
612        A: SeqAccess<'de>,
613    {
614        self.0.deserialize_component_ids(seq)
615    }
616}
617
618struct DeserializeComponents<'a, C> {
619    ctx: &'a mut C,
620    component_count: u32,
621    entity_count: u32,
622    entities: &'a mut Vec<Entity>,
623    out: &'a mut ColumnBatchBuilder,
624}
625
626impl<'de, 'a, C> DeserializeSeed<'de> for DeserializeComponents<'a, C>
627where
628    C: DeserializeContext,
629{
630    type Value = ();
631
632    fn deserialize<D>(self, deserializer: D) -> Result<(), D::Error>
633    where
634        D: Deserializer<'de>,
635    {
636        deserializer.deserialize_tuple(
637            self.component_count as usize + 1,
638            ComponentsVisitor {
639                ctx: self.ctx,
640                entity_count: self.entity_count,
641                entities: self.entities,
642                out: self.out,
643            },
644        )
645    }
646}
647
648struct ComponentsVisitor<'a, C> {
649    ctx: &'a mut C,
650    entity_count: u32,
651    entities: &'a mut Vec<Entity>,
652    out: &'a mut ColumnBatchBuilder,
653}
654
655impl<'de, 'a, C> Visitor<'de> for ComponentsVisitor<'a, C>
656where
657    C: DeserializeContext,
658{
659    type Value = ();
660
661    fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
662        write!(f, "a set of {} components", self.entity_count)
663    }
664
665    fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
666    where
667        A: SeqAccess<'de>,
668    {
669        seq.next_element_seed(DeserializeEntities {
670            count: self.entity_count,
671            out: self.entities,
672        })?;
673        self.ctx
674            .deserialize_components(self.entity_count, seq, self.out)
675    }
676}
677
678struct DeserializeEntities<'a> {
679    count: u32,
680    out: &'a mut Vec<Entity>,
681}
682
683impl<'de, 'a> DeserializeSeed<'de> for DeserializeEntities<'a> {
684    type Value = ();
685
686    fn deserialize<D>(self, deserializer: D) -> Result<(), D::Error>
687    where
688        D: Deserializer<'de>,
689    {
690        deserializer.deserialize_tuple(
691            self.count as usize,
692            EntitiesVisitor {
693                count: self.count,
694                out: self.out,
695            },
696        )
697    }
698}
699
700struct EntitiesVisitor<'a> {
701    count: u32,
702    out: &'a mut Vec<Entity>,
703}
704
705impl<'de, 'a> Visitor<'de> for EntitiesVisitor<'a> {
706    type Value = ();
707
708    fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
709        write!(formatter, "a list of {} entity IDs", self.count)
710    }
711
712    fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
713    where
714        A: SeqAccess<'de>,
715    {
716        let mut n = 0;
717        while let Some(id) = seq.next_element()? {
718            self.out.push(id);
719            n += 1;
720        }
721        if n != self.count {
722            return Err(de::Error::invalid_length(n as usize, &self));
723        }
724        Ok(())
725    }
726}
727
728#[cfg(test)]
729mod tests {
730    use crate::alloc::vec::Vec;
731    use core::fmt;
732
733    use serde::{Deserialize, Serialize};
734
735    use super::*;
736    use crate::*;
737
738    #[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
739    struct Position([f32; 3]);
740    #[derive(Serialize, Deserialize, PartialEq, Debug, Copy, Clone)]
741    struct Velocity([f32; 3]);
742
743    #[derive(Default)]
744    struct Context {
745        components: Vec<ComponentId>,
746    }
747    #[derive(Serialize, Deserialize)]
748    enum ComponentId {
749        Position,
750        Velocity,
751    }
752
753    #[derive(Serialize, Deserialize)]
754    /// Bodge into serde_test's very strict interface
755    struct SerWorld(#[serde(with = "helpers")] World);
756
757    impl PartialEq for SerWorld {
758        fn eq(&self, other: &Self) -> bool {
759            fn same_components<T: Component + PartialEq>(x: &EntityRef, y: &EntityRef) -> bool {
760                x.get::<&T>().as_ref().map(|x| &**x) == y.get::<&T>().as_ref().map(|x| &**x)
761            }
762
763            for (x, y) in self.0.iter().zip(other.0.iter()) {
764                if x.entity() != y.entity()
765                    || !same_components::<Position>(&x, &y)
766                    || !same_components::<Velocity>(&x, &y)
767                {
768                    return false;
769                }
770            }
771            true
772        }
773    }
774
775    impl fmt::Debug for SerWorld {
776        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
777            f.debug_map()
778                .entries(self.0.iter().map(|e| {
779                    (
780                        e.entity(),
781                        (
782                            e.get::<&Position>().map(|x| *x),
783                            e.get::<&Velocity>().map(|x| *x),
784                        ),
785                    )
786                }))
787                .finish()
788        }
789    }
790
791    mod helpers {
792        use super::*;
793        pub fn serialize<S: Serializer>(x: &World, s: S) -> Result<S::Ok, S::Error> {
794            crate::serialize::column::serialize(
795                x,
796                &mut Context {
797                    components: Vec::new(),
798                },
799                s,
800            )
801        }
802        pub fn deserialize<'de, D: Deserializer<'de>>(d: D) -> Result<World, D::Error> {
803            crate::serialize::column::deserialize(
804                &mut Context {
805                    components: Vec::new(),
806                },
807                d,
808            )
809        }
810    }
811
812    impl DeserializeContext for Context {
813        fn deserialize_component_ids<'de, A>(
814            &mut self,
815            mut seq: A,
816        ) -> Result<ColumnBatchType, A::Error>
817        where
818            A: SeqAccess<'de>,
819        {
820            self.components.clear();
821            let mut batch = ColumnBatchType::new();
822            while let Some(id) = seq.next_element()? {
823                match id {
824                    ComponentId::Position => {
825                        batch.add::<Position>();
826                    }
827                    ComponentId::Velocity => {
828                        batch.add::<Velocity>();
829                    }
830                }
831                self.components.push(id);
832            }
833            Ok(batch)
834        }
835
836        fn deserialize_components<'de, A>(
837            &mut self,
838            entity_count: u32,
839            mut seq: A,
840            batch: &mut ColumnBatchBuilder,
841        ) -> Result<(), A::Error>
842        where
843            A: SeqAccess<'de>,
844        {
845            for component in &self.components {
846                match *component {
847                    ComponentId::Position => {
848                        deserialize_column::<Position, _>(entity_count, &mut seq, batch)?;
849                    }
850                    ComponentId::Velocity => {
851                        deserialize_column::<Velocity, _>(entity_count, &mut seq, batch)?;
852                    }
853                }
854            }
855            Ok(())
856        }
857    }
858
859    impl SerializeContext for Context {
860        fn component_count(&self, archetype: &Archetype) -> usize {
861            archetype.component_types().len()
862        }
863
864        fn serialize_component_ids<S: SerializeTuple>(
865            &mut self,
866            archetype: &Archetype,
867            mut out: S,
868        ) -> Result<S::Ok, S::Error> {
869            try_serialize_id::<Position, _, _>(archetype, &ComponentId::Position, &mut out)?;
870            try_serialize_id::<Velocity, _, _>(archetype, &ComponentId::Velocity, &mut out)?;
871            out.end()
872        }
873
874        fn serialize_components<S: SerializeTuple>(
875            &mut self,
876            archetype: &Archetype,
877            mut out: S,
878        ) -> Result<S::Ok, S::Error> {
879            try_serialize::<Position, _>(archetype, &mut out)?;
880            try_serialize::<Velocity, _>(archetype, &mut out)?;
881            out.end()
882        }
883    }
884
885    #[test]
886    #[rustfmt::skip]
887    fn roundtrip() {
888        use serde_test::{Token, assert_tokens};
889
890        let mut world = World::new();
891        let p0 = Position([0.0, 0.0, 0.0]);
892        let v0 = Velocity([1.0, 1.0, 1.0]);
893        let p1 = Position([2.0, 2.0, 2.0]);
894        let e0 = world.spawn((p0, v0));
895        let e1 = world.spawn((p1,));
896        let e2 = world.spawn(());
897
898        assert_tokens(&SerWorld(world), &[
899            Token::NewtypeStruct { name: "SerWorld" },
900            Token::Seq { len: Some(3) },
901
902            Token::Tuple { len: 4 },
903            Token::U32(1),
904            Token::U32(0),
905            Token::Tuple { len: 0 },
906            Token::TupleEnd,
907            Token::Tuple { len: 1 },
908            Token::Tuple { len: 1 },
909            Token::U64(e2.to_bits().into()),
910            Token::TupleEnd,
911            Token::TupleEnd,
912            Token::TupleEnd,
913
914            Token::Tuple { len: 4 },
915            Token::U32(1),
916            Token::U32(2),
917            Token::Tuple { len: 2 },
918            Token::UnitVariant { name: "ComponentId", variant: "Position" },
919            Token::UnitVariant { name: "ComponentId", variant: "Velocity" },
920            Token::TupleEnd,
921            Token::Tuple { len: 3 },
922            Token::Tuple { len: 1 },
923            Token::U64(e0.to_bits().into()),
924            Token::TupleEnd,
925            Token::Tuple { len: 1 },
926            Token::NewtypeStruct { name: "Position" },
927            Token::Tuple { len: 3 },
928            Token::F32(0.0),
929            Token::F32(0.0),
930            Token::F32(0.0),
931            Token::TupleEnd,
932            Token::TupleEnd,
933            Token::Tuple { len: 1 },
934            Token::NewtypeStruct { name: "Velocity" },
935            Token::Tuple { len: 3 },
936            Token::F32(1.0),
937            Token::F32(1.0),
938            Token::F32(1.0),
939            Token::TupleEnd,
940            Token::TupleEnd,
941            Token::TupleEnd,
942            Token::TupleEnd,
943
944            Token::Tuple { len: 4 },
945            Token::U32(1),
946            Token::U32(1),
947            Token::Tuple { len: 1 },
948            Token::UnitVariant { name: "ComponentId", variant: "Position" },
949            Token::TupleEnd,
950            Token::Tuple { len: 2 },
951            Token::Tuple { len: 1 },
952            Token::U64(e1.to_bits().into()),
953            Token::TupleEnd,
954            Token::Tuple { len: 1 },
955            Token::NewtypeStruct { name: "Position" },
956            Token::Tuple { len: 3 },
957            Token::F32(2.0),
958            Token::F32(2.0),
959            Token::F32(2.0),
960            Token::TupleEnd,
961            Token::TupleEnd,
962            Token::TupleEnd,
963            Token::TupleEnd,
964
965            Token::SeqEnd,
966        ])
967    }
968}