Commit 799cf29c authored by Luke Jones's avatar Luke Jones

Expand the Entity macro

parent edf01499
Pipeline #45856464 passed with stages
in 5 minutes and 16 seconds
......@@ -31,81 +31,95 @@ pub mod physics;
use std::collections::HashMap;
const MAX_ENTS: usize = 10_000;
pub const EMPTY : u32 = 0;
pub const POSITION : u32 = 1<<0;
pub const VELOCITY : u32 = 1<<1;
pub const AABB : u32 = 1<<2;
pub const PHYSICS : u32 = 1<<3;
pub const INPUT : u32 = 1<<4;
pub const SPRITE : u32 = 1<<5;
pub const ANIMATION : u32 = 1<<6;
pub const PLAYER : u32 = 1<<7;
pub const AI : u32 = 1<<8;
pub const ITEM : u32 = 1<<11;
pub const CIRCLE : u32 = 1<<12;
macro_rules! Entities {
($([$bf_shift:expr, $bf_name:ident, $m_name:ident, $ty:ty]),+) => {
pub const EMPTY: u32 = 0;
$(pub const $bf_name: u32 = 1<<$bf_shift;)+
/// A struct of `HashMap` for each entity part type
///
/// The objects stored in each `HashMap` are keyed to the
/// entity ID number for quick loop up
#[derive(Default)]
pub struct Parts {
pub position : HashMap<u32, parts::Position>,
pub velocity : HashMap<u32, parts::Velocity>,
pub aabb : HashMap<u32, parts::AABB>,
pub physics : HashMap<u32, parts::Physics>,
pub input : HashMap<u32, parts::InputTypes>,
pub sprite : HashMap<u32, parts::Sprite>,
pub animation: HashMap<u32, parts::Animation>,
pub player : HashMap<u32, parts::Player>,
pub ai : HashMap<u32, parts::Ai>,
pub item : HashMap<u32, parts::Inventory>,
pub circle : HashMap<u32, parts::Circle>,
}
impl Parts {
pub fn remove_ent_parts(&mut self, ent: u32) {
self.position.remove(&ent);
self.velocity.remove(&ent);
self.aabb.remove(&ent);
self.physics.remove(&ent);
self.input.remove(&ent);
self.sprite.remove(&ent);
self.animation.remove(&ent);
self.player.remove(&ent);
self.ai.remove(&ent);
self.item.remove(&ent);
self.circle.remove(&ent);
}
}
/// Stores all entities
///
/// Enables ability to pass the required arrays to Systems. We can't do this if the
/// World struct contains them because of ownership conflicts in Rust.
pub struct Entities {
/// Used to keep track of which index number has which components. The
/// index number that the entity is created at is then used as the key
/// for the object hashmaps in `_entities`
///
/// Eg: POSITION + AABB (= 5, can be used for collidable object positions)
pub mask: [u32; MAX_ENTS],
/// The struct of HashMaps for each entity part type
pub parts: Parts,
/// `next_free` is used to keep track of how far the array has been used.
/// For example if only 42 entities have been created then when inserting a new entity
/// `create` will iterate through to find either first `EMPTY` or insert at `next_free`
/// and increment
pub next_free: u32
}
/// A struct of `HashMap` for each entity part type
///
/// The objects stored in each `HashMap` are keyed to the
/// entity ID number for quick loop up
pub struct Parts {
$(pub $m_name: HashMap<u32, $ty>,)+
impl Entities {
pub fn new() -> Entities {
Entities {
mask: [EMPTY; MAX_ENTS],
parts: Parts::default(),
next_free: 1
}
///
/// Stores all entities
///
/// Enables ability to pass the required arrays to Systems. We can't do this if the
/// World struct contains them because of ownership conflicts in Rust.
pub struct Entities {
/// Used to keep track of which index number has which components. The
/// index number that the entity is created at is then used as the key
/// for the object hashmaps in `_entities`
///
/// Eg: POSITION + AABB (= 5, can be used for collidable object positions)
pub mask: [u32; MAX_ENTS],
/// The struct of HashMaps for each entity part type
pub parts: Parts,
/// `next_free` is used to keep track of how far the array has been used.
/// For example if only 42 entities have been created then when inserting a new entity
/// `create` will iterate through to find either first `EMPTY` or insert at `next_free`
/// and increment
pub next_free: u32
}
/// Remove the specified entity index and set as `EMPTY`
pub fn remove(&mut self, ent: u32) {
if self.mask[ent as usize] != EMPTY as u32 {
self.parts.remove_ent_parts(ent);
}
impl Entities {
pub fn new() -> Entities {
Entities {
mask: [EMPTY; MAX_ENTS],
parts: Parts {
$($m_name: HashMap::new(),)+
},
next_free: 1
}
}
/// Remove the specified entity index and set as `EMPTY`
pub fn remove(&mut self, ent: u32) {
if self.mask[ent as usize] != EMPTY as u32 {
$(self.parts.$m_name.remove(&ent);)+
}
}
/// Find the first `EMPTY` ID number to use
pub fn get_free_slot(&mut self) -> Option<u32> {
for index in 0..self.next_free {
if self.mask[index as usize] == EMPTY as u32 {
self.next_free += 1;
return Some(index);
}
}
None
}
/// Find the first `EMPTY` ID number to use
pub fn get_free_slot(&mut self) -> Option<u32> {
for index in 0..self.next_free {
if self.mask[index as usize] == EMPTY as u32 {
self.next_free += 1;
return Some(index);
}
}
None
}
}
Entities!(
[0, POSITION, position, parts::Position],
[1, VELOCITY, velocity, parts::Velocity],
[2, AABB, aabb, parts::AABB],
[3, PHYSICS, physics, parts::Physics],
[4, INPUT, input, parts::InputTypes],
[5, SPRITE, sprite, parts::Sprite],
[6, ANIMATION, animation, parts::Animation],
[7, PLAYER, player, parts::Player],
[8, AI, ai, parts::Ai],
[9, HEALTH, health, parts::Health],
[10, ARMOUR, armour, parts::Armour],
[11, INVENTORY, inventory, parts::Inventory],
[12, CIRCLE, circle, parts::Circle]
);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment