Skip to content

Instantly share code, notes, and snippets.

@copygirl
Created July 16, 2016 01:36
Show Gist options
  • Save copygirl/f63fa03d7ea1706564f863aeaad9b104 to your computer and use it in GitHub Desktop.
Save copygirl/f63fa03d7ea1706564f863aeaad9b104 to your computer and use it in GitHub Desktop.
Tiny ECS storage in Rust using hash maps (WIP)
use std::any::Any;
use std::any::TypeId;
use std::hash::Hash;
use std::collections::HashMap;
#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
pub struct Entity(i32);
pub trait Component: Any { }
impl<T: Any> Component for T { }
pub struct EntityComponentMap<E: Eq + Hash = Entity> {
map: HashMap<TypeId, HashMap<E, Box<Any>>>,
}
impl<E: Eq + Hash> EntityComponentMap<E> {
pub fn new() -> EntityComponentMap<E> {
EntityComponentMap { map: HashMap::new() }
}
pub fn borrow<C: Component>(&self, entity: E) -> Option<&C> {
self.map
.get(&TypeId::of::<C>())
.and_then(|m| m.get(&entity))
.map(|b| b.downcast_ref::<C>().expect("downcast to C"))
}
pub fn get<C: Component + Clone>(&self, entity: E) -> Option<C> {
self.borrow(entity).map(Clone::clone)
}
pub fn insert<C: Component>(&mut self, entity: E, value: C) -> Option<C> {
self.map
.entry(TypeId::of::<C>())
.or_insert_with(HashMap::new)
.insert(entity, Box::new(value))
.map(|b| *b.downcast::<C>().expect("downcast to C"))
}
pub fn remove<C: Component>(&mut self, entity: E) -> Option<C> {
self.map
.get_mut(&TypeId::of::<C>())
.and_then(|m| m.remove(&entity))
.map(|b| *b.downcast::<C>().expect("downcast to C"))
}
pub fn set<C: Component>(&mut self, entity: E, value: Option<C>) -> Option<C> {
match value {
Some(value) => self.insert(entity, value),
None => self.remove(entity),
}
}
}
#[test]
fn test() {
let entity = Entity(0);
let location = [ 0f32; 3 ];
let mut ec_map = EntityComponentMap::<Entity>::new();
ec_map.insert(entity, location);
assert_eq!(ec_map.borrow::<[f32;3]>(entity), Some(&[ 0f32; 3 ]));
assert_eq!(ec_map.get::<[f32;3]>(entity), Some([ 0f32; 3 ]));
assert_eq!(ec_map.get::<[f32;2]>(entity), None);
ec_map.remove::<[f32;3]>(entity);
assert_eq!(ec_map.get::<[f32;3]>(entity), None);
}
Copy link

ghost commented Jul 21, 2016

I skimmed though it once, my head started to hurt.
I read through it, I stopped at line 14 and decided it was time to go to sleep for the day...
I'm not a Rust person.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment