This repository has been archived by the owner on Nov 27, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 33
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Update hecs, add to serialization benchmarks
- Loading branch information
Showing
5 changed files
with
307 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
use hecs::{serialize::column::*, *}; | ||
use serde::{de::SeqAccess, ser::SerializeTuple, Deserialize, Serialize}; | ||
|
||
#[derive(Default, Copy, Clone, Serialize, Deserialize)] | ||
struct Transform([f32; 16]); | ||
|
||
#[derive(Default, Copy, Clone, Serialize, Deserialize)] | ||
struct Position { | ||
x: f32, | ||
y: f32, | ||
z: f32, | ||
} | ||
|
||
#[derive(Default, Copy, Clone, Serialize, Deserialize)] | ||
struct Rotation { | ||
x: f32, | ||
y: f32, | ||
z: f32, | ||
} | ||
|
||
#[derive(Default, Copy, Clone, Serialize, Deserialize)] | ||
struct Velocity { | ||
x: f32, | ||
y: f32, | ||
z: f32, | ||
} | ||
|
||
struct SerContext; | ||
|
||
#[derive(Serialize, Deserialize, Debug, Copy, Clone)] | ||
enum ComponentId { | ||
Transform, | ||
Position, | ||
Rotation, | ||
Velocity, | ||
} | ||
|
||
impl SerializeContext for SerContext { | ||
fn component_count(&self, archetype: &Archetype) -> usize { | ||
use std::any::TypeId; | ||
archetype | ||
.component_types() | ||
.filter(|&x| { | ||
x == TypeId::of::<Transform>() | ||
|| x == TypeId::of::<Position>() | ||
|| x == TypeId::of::<Rotation>() | ||
|| x == TypeId::of::<Velocity>() | ||
}) | ||
.count() | ||
} | ||
|
||
fn serialize_component_ids<S: SerializeTuple>( | ||
&mut self, | ||
archetype: &Archetype, | ||
out: &mut S, | ||
) -> Result<(), S::Error> { | ||
if archetype.has::<Transform>() { | ||
out.serialize_element(&ComponentId::Transform)?; | ||
} | ||
if archetype.has::<Position>() { | ||
out.serialize_element(&ComponentId::Position)?; | ||
} | ||
if archetype.has::<Rotation>() { | ||
out.serialize_element(&ComponentId::Rotation)?; | ||
} | ||
if archetype.has::<Velocity>() { | ||
out.serialize_element(&ComponentId::Velocity)?; | ||
} | ||
Ok(()) | ||
} | ||
|
||
fn serialize_components<S: SerializeTuple>( | ||
&mut self, | ||
archetype: &Archetype, | ||
out: &mut S, | ||
) -> Result<(), S::Error> { | ||
try_serialize::<Transform, _>(archetype, out)?; | ||
try_serialize::<Position, _>(archetype, out)?; | ||
try_serialize::<Rotation, _>(archetype, out)?; | ||
try_serialize::<Velocity, _>(archetype, out)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
struct DeContext { | ||
components: Vec<ComponentId>, | ||
} | ||
|
||
impl DeserializeContext for DeContext { | ||
fn deserialize_component_ids<'de, A>(&mut self, mut seq: A) -> Result<ColumnBatchType, A::Error> | ||
where | ||
A: SeqAccess<'de>, | ||
{ | ||
self.components.clear(); | ||
let mut batch = ColumnBatchType::new(); | ||
while let Some(id) = seq.next_element()? { | ||
match id { | ||
ComponentId::Transform => { | ||
batch.add::<Transform>(); | ||
} | ||
ComponentId::Position => { | ||
batch.add::<Position>(); | ||
} | ||
ComponentId::Rotation => { | ||
batch.add::<Rotation>(); | ||
} | ||
ComponentId::Velocity => { | ||
batch.add::<Velocity>(); | ||
} | ||
} | ||
self.components.push(id); | ||
} | ||
Ok(batch) | ||
} | ||
|
||
fn deserialize_components<'de, A>( | ||
&mut self, | ||
entity_count: u32, | ||
mut seq: A, | ||
batch: &mut ColumnBatchBuilder, | ||
) -> Result<(), A::Error> | ||
where | ||
A: SeqAccess<'de>, | ||
{ | ||
for &component in &self.components { | ||
match component { | ||
ComponentId::Transform => { | ||
deserialize_column::<Transform, _>(entity_count, &mut seq, batch)?; | ||
} | ||
ComponentId::Position => { | ||
deserialize_column::<Position, _>(entity_count, &mut seq, batch)?; | ||
} | ||
ComponentId::Rotation => { | ||
deserialize_column::<Rotation, _>(entity_count, &mut seq, batch)?; | ||
} | ||
ComponentId::Velocity => { | ||
deserialize_column::<Velocity, _>(entity_count, &mut seq, batch)?; | ||
} | ||
} | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub struct Benchmark(World); | ||
|
||
impl Benchmark { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
world.spawn_batch((0..1000).map(|_| { | ||
( | ||
Transform::default(), | ||
Position::default(), | ||
Rotation::default(), | ||
Velocity::default(), | ||
) | ||
})); | ||
|
||
Self(world) | ||
} | ||
|
||
pub fn run(&mut self) { | ||
let Self(world) = self; | ||
let mut encoded = Vec::new(); | ||
serialize( | ||
&world, | ||
&mut SerContext, | ||
&mut bincode::Serializer::new(&mut encoded, bincode::options()), | ||
) | ||
.unwrap(); | ||
deserialize( | ||
&mut DeContext { | ||
components: Vec::new(), | ||
}, | ||
&mut bincode::Deserializer::from_slice(&encoded, bincode::options()), | ||
) | ||
.unwrap(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
use hecs::{serialize::row::*, *}; | ||
use serde::{de::MapAccess, ser::SerializeMap, Deserialize, Serialize}; | ||
|
||
#[derive(Default, Copy, Clone, Serialize, Deserialize)] | ||
struct Transform([f32; 16]); | ||
|
||
#[derive(Default, Copy, Clone, Serialize, Deserialize)] | ||
struct Position { | ||
x: f32, | ||
y: f32, | ||
z: f32, | ||
} | ||
|
||
#[derive(Default, Copy, Clone, Serialize, Deserialize)] | ||
struct Rotation { | ||
x: f32, | ||
y: f32, | ||
z: f32, | ||
} | ||
|
||
#[derive(Default, Copy, Clone, Serialize, Deserialize)] | ||
struct Velocity { | ||
x: f32, | ||
y: f32, | ||
z: f32, | ||
} | ||
|
||
struct SerContext; | ||
|
||
#[derive(Serialize, Deserialize, Debug, Copy, Clone)] | ||
enum ComponentId { | ||
Transform, | ||
Position, | ||
Rotation, | ||
Velocity, | ||
} | ||
|
||
impl SerializeContext for SerContext { | ||
fn serialize_entity<S: SerializeMap>( | ||
&mut self, | ||
entity: EntityRef<'_>, | ||
map: &mut S, | ||
) -> Result<(), S::Error> { | ||
try_serialize::<Transform, _, _>(&entity, &ComponentId::Transform, map)?; | ||
try_serialize::<Position, _, _>(&entity, &ComponentId::Position, map)?; | ||
try_serialize::<Rotation, _, _>(&entity, &ComponentId::Rotation, map)?; | ||
try_serialize::<Velocity, _, _>(&entity, &ComponentId::Velocity, map)?; | ||
Ok(()) | ||
} | ||
} | ||
|
||
struct DeContext; | ||
|
||
impl DeserializeContext for DeContext { | ||
fn deserialize_entity<'de, M>( | ||
&mut self, | ||
mut map: M, | ||
entity: &mut EntityBuilder, | ||
) -> Result<(), M::Error> | ||
where | ||
M: MapAccess<'de>, | ||
{ | ||
while let Some(key) = map.next_key()? { | ||
match key { | ||
ComponentId::Transform => { | ||
entity.add::<Transform>(map.next_value()?); | ||
} | ||
ComponentId::Position => { | ||
entity.add::<Position>(map.next_value()?); | ||
} | ||
ComponentId::Rotation => { | ||
entity.add::<Rotation>(map.next_value()?); | ||
} | ||
ComponentId::Velocity => { | ||
entity.add::<Velocity>(map.next_value()?); | ||
} | ||
} | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub struct Benchmark(World); | ||
|
||
impl Benchmark { | ||
pub fn new() -> Self { | ||
let mut world = World::new(); | ||
|
||
world.spawn_batch((0..1000).map(|_| { | ||
( | ||
Transform::default(), | ||
Position::default(), | ||
Rotation::default(), | ||
Velocity::default(), | ||
) | ||
})); | ||
|
||
Self(world) | ||
} | ||
|
||
pub fn run(&mut self) { | ||
let Self(world) = self; | ||
let mut encoded = Vec::new(); | ||
serialize( | ||
&world, | ||
&mut SerContext, | ||
&mut ron::Serializer::new(&mut encoded, None, false).unwrap(), | ||
) | ||
.unwrap(); | ||
deserialize( | ||
&mut DeContext, | ||
&mut ron::Deserializer::from_bytes(&encoded).unwrap(), | ||
) | ||
.unwrap(); | ||
} | ||
} |