Created
July 16, 2016 01:36
-
-
Save copygirl/f63fa03d7ea1706564f863aeaad9b104 to your computer and use it in GitHub Desktop.
Tiny ECS storage in Rust using hash maps (WIP)
This file contains hidden or 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
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); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.