Skip to content

Commit

Permalink
Add basic cloning example
Browse files Browse the repository at this point in the history
  • Loading branch information
caspark committed Jul 6, 2024
1 parent ed23ded commit aee1482
Showing 1 changed file with 89 additions and 0 deletions.
89 changes: 89 additions & 0 deletions examples/cloning.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use hecs::{ColumnBatchBuilder, ColumnBatchType, Component, World};

fn maybe_add_type_to_batch<T: Component>(
archetype: &hecs::Archetype,
batch_type: &mut ColumnBatchType,
) {
if archetype.has::<T>() {
batch_type.add::<T>();
}
}

fn maybe_clone_column<T: Component + Clone>(
archetype: &hecs::Archetype,
batch: &mut ColumnBatchBuilder,
) {
if let Some((column, mut writer)) = archetype.get::<&T>().zip(batch.writer::<T>()) {
for item in column.iter() {
if let Err(_) = writer.push(item.clone()) {
unreachable!("push should always succeed since batch was sized to match archetype");
}
}
}
}

/// Clones world entities along with a hardcoded list of components.
///
/// Components not included are omitted from the cloned world.
///
/// Note that entity allocator state may differ in the cloned world - so for example a new entity
/// spawned in each world may end up with different entity ids, entity iteration order may be
/// different, etc.
fn clone_world(world: &World) -> World {
let mut cloned = World::new();

for archetype in world.archetypes() {
let mut batch = ColumnBatchType::new();
// types have to be listed one by one here
maybe_add_type_to_batch::<String>(archetype, &mut batch);
maybe_add_type_to_batch::<i32>(archetype, &mut batch);

let mut batch = batch.into_batch(archetype.ids().len() as u32);
// and types need to be listed again here
maybe_clone_column::<String>(archetype, &mut batch);
maybe_clone_column::<i32>(archetype, &mut batch);

let batch = batch.build().expect("batch should be complete");

let handles = &cloned
.reserve_entities(archetype.ids().len() as u32)
.collect::<Vec<_>>();
cloned.flush();
cloned.spawn_column_batch_at(handles, batch);
}

cloned
}

pub fn main() {
let int0 = 0;
let int1 = 1;
let str0 = "Ada".to_owned();
let str1 = "Bob".to_owned();

let mut world0 = World::new();
let entity0 = world0.spawn((int0, str0));
let entity1 = world0.spawn((int1, str1));

let world1 = clone_world(&world0);

assert_eq!(
world0.len(),
world1.len(),
"cloned world should have same entity count as original world"
);

type AllComponentsQuery = (&'static i32, &'static String);

for entity in [entity0, entity1] {
let w0_e = world0.entity(entity).expect("w0 entity should exist");
let w1_e = world1.entity(entity).expect("w1 entity should exist");
assert!(w0_e.satisfies::<AllComponentsQuery>());
assert!(w1_e.satisfies::<AllComponentsQuery>());

assert_eq!(
w0_e.query::<AllComponentsQuery>().get().unwrap(),
w1_e.query::<AllComponentsQuery>().get().unwrap()
);
}
}

0 comments on commit aee1482

Please sign in to comment.