Skip to content

Instantly share code, notes, and snippets.

@rust-play
Created June 18, 2019 12:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rust-play/dc30943fc81ab854a9196635c4a72d7f to your computer and use it in GitHub Desktop.
Save rust-play/dc30943fc81ab854a9196635c4a72d7f to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
use std::any::{Any, TypeId};
use std::collections::HashMap;
use std::vec::Vec;
pub struct World {
components: HashMap<TypeId, Box<dyn Any>>,
next_entity_id: Entity,
entities: Vec<EntityData>,
}
impl World {
pub fn register_component_with_storage<C: 'static>(&mut self) {
self.components
.insert(TypeId::of::<C>(), Box::new(Vec::<C>::new()));
}
pub fn add_component_to_storage<C: 'static>(&mut self, component: C) -> usize {
let storage = self
.components
.get_mut(&TypeId::of::<C>())
.unwrap()
.downcast_mut::<Vec<C>>()
.unwrap();
storage.push(component);
return storage.len() - 1;
}
fn get_component<C: 'static>(&self, index: usize) -> &C {
let storage = self.components[&TypeId::of::<C>()]
.downcast_ref::<Vec<C>>()
.unwrap();
&storage[index]
}
pub fn create_entity(&mut self) -> Entity {
let e = self.next_entity_id;
self.entities.push(EntityData {
components: Vec::new(),
});
self.next_entity_id += 1;
return e;
}
pub fn add_component_to_entity<C: 'static>(&mut self, entity: Entity, component: C) {
let index = self.add_component_to_storage(component);
let entity_data = self.entities.get_mut(entity).unwrap();
let ec = EntityComponent {
component_type: TypeId::of::<C>(),
component_index: index,
};
entity_data.components.push(ec);
}
fn get_component_for_entity<C: 'static>(&self, entity: Entity) -> Option<&C> {
let entity_data = &self.entities[entity];
for entity_component in &entity_data.components {
if entity_component.component_type == TypeId::of::<C>() {
let index = entity_component.component_index;
return Some(self.get_component::<C>(index));
}
}
return None;
}
}
type Entity = usize;
pub struct EntityComponent {
component_type: TypeId,
component_index: usize,
}
pub struct EntityData {
components: Vec<EntityComponent>,
}
#[derive(Debug)]
pub struct ImageComponent {
x: f32,
y: f32,
}
#[derive(Debug)]
pub struct GravityComponent {
speed: f32,
}
fn main() {
println!("Starting up");
let mut world = World {
components: HashMap::new(),
next_entity_id: 0,
entities: Vec::new(),
};
world.register_component_with_storage::<ImageComponent>();
world.register_component_with_storage::<GravityComponent>();
let ic_1 = ImageComponent { x: 10.0, y: 10.0 };
let ic_2 = ImageComponent { x: 50.0, y: 50.0 };
let gc_1 = GravityComponent { speed: 9.8 };
//let ic_index = world.add_component_to_storage(ic);
//dbg!(world.get_component::<ImageComponent>(ic_index));
let entity_1 = world.create_entity();
world.add_component_to_entity(entity_1, ic_1);
let entity_2 = world.create_entity();
world.add_component_to_entity(entity_2, ic_2);
world.add_component_to_entity(entity_2, gc_1);
let e1_ic = world.get_component_for_entity::<ImageComponent>(entity_1);
dbg!(e1_ic);
let e1_gc = world.get_component_for_entity::<GravityComponent>(entity_1);
dbg!(e1_gc);
let e2_ic = world.get_component_for_entity::<ImageComponent>(entity_2);
dbg!(e2_ic);
let e2_gc = world.get_component_for_entity::<GravityComponent>(entity_2);
dbg!(e2_gc);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment