Skip to content

Commit

Permalink
wip World API
Browse files Browse the repository at this point in the history
  • Loading branch information
toyboot4e committed Dec 22, 2021
1 parent f4e3db9 commit 0651328
Show file tree
Hide file tree
Showing 2 changed files with 166 additions and 1 deletion.
128 changes: 127 additions & 1 deletion src/lib.rs
Expand Up @@ -11,7 +11,23 @@ pub mod res;
pub mod sparse;
pub mod sys;

use crate::{comp::ComponentPoolMap, ent::EntityPool, res::ResourceMap};
pub mod prelude {
pub use crate::{
comp::{Comp, CompMut},
ent::Entity,
res::{Res, ResMut},
sys::System,
World,
};
}

use std::any;

use crate::{
comp::{Comp, CompMut, ComponentPoolMap},
ent::{Entity, EntityPool},
res::{Res, ResMut, ResourceMap},
};

/// In-memory central DB
#[derive(Debug, Default)]
Expand All @@ -20,3 +36,113 @@ pub struct World {
ents: EntityPool,
comp: ComponentPoolMap,
}

impl World {
/// Sets a resource, a unique instance of type `T`. Returns some old value if it's present.
pub fn set_res<T: 'static>(&mut self, res: T) -> Option<T> {
self.res.insert(res)
}

/// Tries to get an immutable access to a resource of type `T`
/// # Panics
/// Panics when breaking the aliaslng rules.
pub fn maybe_res<T: 'static>(&self) -> Option<Res<T>> {
self.res.borrow::<T>()
}

/// Tries to get a mutable access to a resource of type `T`
/// # Panics
/// Panics when breaking the aliaslng rules.
pub fn maybe_res_mut<T: 'static>(&self) -> Option<ResMut<T>> {
self.res.borrow_mut::<T>()
}

fn resource_panic<T: 'static>() -> ! {
panic!(
"Tried to get resource of type {}, but it was not present",
any::type_name::<T>()
)
}

/// Tries to get an immutable access to a resource of type `T`
/// # Panics
/// Panics when breaking the aliaslng rules. Panics when the resource is not set.
pub fn res<T: 'static>(&self) -> Res<T> {
self.maybe_res::<T>()
.unwrap_or_else(|| Self::resource_panic::<T>())
}

/// Tries to get a mutable access to a resource of type `T`
/// # Panics
/// Panics when breaking the aliaslng rules. Panics when the resource is not set.
pub fn res_mut<T: 'static>(&self) -> ResMut<T> {
self.maybe_res_mut::<T>()
.unwrap_or_else(|| Self::resource_panic::<T>())
}

/// Checks if we have a component pool for type `T`
pub fn is_registered<T: 'static>(&self) -> bool {
self.comp.is_registered::<T>()
}

/// Registers a component pool for type `T`. Returns true if it was already registered.
pub fn register<T: 'static>(&mut self) -> bool {
self.comp.register::<T>()
}

/// Spawns an [`Entity`]
pub fn spawn(&mut self) -> Entity {
self.ents.alloc()
}

/// Despawns an [`Entity`]. Returns if it was an active entity.
pub fn despawn(&mut self, ent: Entity) -> bool {
if !self.ents.dealloc(ent) {
// old entity
return false;
}

todo!("remove components on despawning an entity");

true
}

pub fn entities(&mut self) -> &[Entity] {
self.ents.slice()
}

/// Tries to get an immutable access to a component pool of type `T`
/// # Panics
/// Panics if the component pool is not registered. Panics when breaking the aliaslng rules.
pub fn comp<T: 'static>(&self) -> Comp<T> {
self.comp
.borrow::<T>()
.unwrap_or_else(|| Self::comp_panic::<T>())
}

/// Tries to get a mutable access to a coponent pool of type `Tn`
/// # Safety
/// Panics if the component pool is not registered. Panics when breaking the aliaslng rules.
pub fn comp_mut<T: 'static>(&self) -> CompMut<T> {
self.comp
.borrow_mut::<T>()
.unwrap_or_else(|| Self::comp_panic::<T>())
}

fn comp_panic<T: 'static>() -> ! {
panic!(
"Tried to get component pool of type {}, but it was not registered",
any::type_name::<T>()
)
}

/// Inserts a component to an entity. Returns some old component if it is present.
pub fn insert<T: 'static>(&mut self, ent: Entity, comp: T) -> Option<T> {
self.comp_mut::<T>().insert(ent, comp)
}

/// Removes a component to from entity.
pub fn remove<T: 'static>(&mut self, ent: Entity) -> Option<T> {
self.comp_mut::<T>().swap_remove(ent)
}
}
39 changes: 39 additions & 0 deletions tests/it/main.rs
@@ -0,0 +1,39 @@
//! The only integration test "crate"

use toecs::World;

#[test]
fn world_api() {
let mut world = World::default();

assert_eq!(world.set_res(1usize), None);
assert_eq!(world.set_res(100usize), Some(1));
world.set_res(-100isize);

world.register::<usize>();
world.register::<isize>();

let e1 = world.spawn();
let e2 = world.spawn();
let e3 = world.spawn();

// TODO: insert components with component set on spawn
world.insert(e1, 10usize);
world.insert(e1, -10isize);

world.insert(e2, 20usize);
world.insert(e2, -20isize);

world.insert(e3, 30usize);
world.insert(e3, -30isize);

assert_eq!(world.remove::<isize>(e1), Some(-10));

// TODO: despawn `e2`
// assert!(world.despawn(e2));
// assert!(!world.despawn(e2));
// let e2 = world.spawn();
// assert_eq!(world.entities().collect::<Vec<_>>(), [&e1, &e3, &e2]);

// TODO: iterate through components
}

0 comments on commit 0651328

Please sign in to comment.