Skip to content

Commit

Permalink
Integrated MOPA and implemented entity deletion
Browse files Browse the repository at this point in the history
  • Loading branch information
kvark committed Apr 9, 2016
1 parent ef7e01c commit 2443833
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 11 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ license = "Apache-2.0"
authors = ["Dzmitry Malyshau"]

[dependencies]
mopa = "0.2"
pulse = "0.5"
threadpool = "1.0"
3 changes: 3 additions & 0 deletions examples/basic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@ fn main() {
parsec::Scheduler::new(w, 4)
};
scheduler.add_entity().with(CompInt(4)).with(CompBool(false)).build();
let e = scheduler.add_entity().with(CompInt(9)).with(CompBool(true)).build();
scheduler.add_entity().with(CompInt(-1)).with(CompBool(false)).build();

scheduler.run1w1r(|b: &mut CompBool, a: &CompInt| {
b.0 = a.0 > 0;
});
scheduler.del_entity(e);

scheduler.run(|warg| {
let (mut sa, sb, entities) = warg.fetch(|comp| {
(comp.write::<CompInt>(),
Expand Down
35 changes: 26 additions & 9 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
#[macro_use]
extern crate mopa;
extern crate pulse;
extern crate threadpool;

use std::any::{Any, TypeId};
use std::any::TypeId;
use std::cell::RefCell;
use std::collections::HashMap;
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
use mopa::Any;
use pulse::{Pulse, Signal};
use threadpool::ThreadPool;

pub use storage::{Storage, VecStorage, HashMapStorage};
pub use storage::{Storage, StorageBase, VecStorage, HashMapStorage};

mod storage;

Expand Down Expand Up @@ -52,16 +55,32 @@ impl<'a> Iterator for EntityIter<'a> {
}
}


pub trait Component: Any + Sized {
type Storage: Storage<Self> + Any + Send + Sync;
}

trait StorageLock: Any + Send + Sync {
fn del_slice(&self, &[Entity]);
}

mopafy!(StorageLock);

impl<S: StorageBase + Any + Send + Sync> StorageLock for RwLock<S> {
fn del_slice(&self, entities: &[Entity]) {
let mut guard = self.write().unwrap();
for &e in entities.iter() {
guard.del(e);
}
}
}


pub struct World {
generations: RwLock<Vec<Generation>>,
components: HashMap<TypeId, Box<Any+Send+Sync>>,
components: HashMap<TypeId, Box<StorageLock>>,
}


impl World {
pub fn new() -> World {
World {
Expand All @@ -74,9 +93,8 @@ impl World {
self.components.insert(TypeId::of::<T>(), Box::new(any));
}
fn lock<T: Component>(&self) -> &RwLock<T::Storage> {
use std::ops::Deref;
let boxed = self.components.get(&TypeId::of::<T>()).unwrap();
(boxed.deref() as &Any).downcast_ref().unwrap()
boxed.downcast_ref().unwrap()
}
pub fn read<'a, T: Component>(&'a self) -> RwLockReadGuard<'a, T::Storage> {
self.lock::<T>().read().unwrap()
Expand Down Expand Up @@ -172,9 +190,8 @@ impl Scheduler {
EntityBuilder(ent, &self.world)
}
pub fn del_entity(&mut self, entity: Entity) {
for _boxed in self.world.components.values() {
//TODO!
//let lock = (boxed.deref() as &Any).downcast_ref().unwrap();
for boxed in self.world.components.values() {
boxed.del_slice(&[entity]);
}
let mut gens = self.world.generations.write().unwrap();
let mut gen = &mut gens[entity.get_id() as usize];
Expand Down
23 changes: 21 additions & 2 deletions src/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@ use std::collections::HashMap;

use {Entity, Generation};

pub trait Storage<T>: Sized {

pub trait StorageBase {
fn del(&mut self, Entity);
}

pub trait Storage<T>: StorageBase + Sized {
fn new() -> Self;
fn get(&self, Entity) -> Option<&T>;
fn get_mut(&mut self, Entity) -> Option<&mut T>;
fn add(&mut self, Entity, T);
fn sub(&mut self, Entity) -> Option<T>;
}


#[derive(Debug)]
pub struct VecStorage<T>(pub Vec<Option<(Generation, T)>>);

impl<T> StorageBase for VecStorage<T> {
fn del(&mut self, entity: Entity) {
self.0[entity.get_id()] = None;
}
}
impl<T> Storage<T> for VecStorage<T> {
fn new() -> Self {
VecStorage(Vec::new())
Expand All @@ -36,13 +47,21 @@ impl<T> Storage<T> for VecStorage<T> {
self.0[entity.get_id()] = Some((entity.get_gen(), value));
}
fn sub(&mut self, entity: Entity) -> Option<T>{
self.0[entity.get_id()].take().map(|(_, v)| v)
self.0[entity.get_id()].take().map(|(g, v)| {
assert_eq!(g, entity.get_gen());
v
})
}
}

#[derive(Debug)]
pub struct HashMapStorage<T>(pub HashMap<Entity, T>);

impl<T> StorageBase for HashMapStorage<T> {
fn del(&mut self, entity: Entity) {
self.0.remove(&entity);
}
}
impl<T> Storage<T> for HashMapStorage<T> {
fn new() -> Self {
HashMapStorage(HashMap::new())
Expand Down

0 comments on commit 2443833

Please sign in to comment.