mirror of
https://github.com/lisk77/comet.git
synced 2025-10-23 21:38:50 +00:00
feat: moved the ECS related functions to the App to remove unnecessary calling of the World struct inside App.
This commit is contained in:
parent
f07b829b7d
commit
ee3d0bdb9e
7 changed files with 258 additions and 81 deletions
|
|
@ -8,6 +8,7 @@ use crate::math::{
|
|||
Vec3
|
||||
};
|
||||
use component_derive::Component;
|
||||
use crate::Entity;
|
||||
|
||||
// ##################################################
|
||||
// # BASIC #
|
||||
|
|
@ -48,6 +49,17 @@ pub struct Render2D {
|
|||
scale: Vec2
|
||||
}
|
||||
|
||||
#[derive(Component)]
|
||||
pub struct Camera2D {
|
||||
left: f32,
|
||||
right: f32,
|
||||
bottom: f32,
|
||||
top: f32,
|
||||
near: f32,
|
||||
far: f32,
|
||||
zoom: f32
|
||||
}
|
||||
|
||||
// ##################################################
|
||||
// # BUNDLES #
|
||||
// ##################################################
|
||||
|
|
@ -91,6 +103,10 @@ pub trait Render {
|
|||
fn set_texture(&mut self, texture: &'static str);
|
||||
}
|
||||
|
||||
pub trait Camera {
|
||||
fn get_visible_entities(&self) -> Vec<Entity>;
|
||||
}
|
||||
|
||||
// ##################################################
|
||||
// # IMPLS #
|
||||
// ##################################################
|
||||
|
|
@ -170,11 +186,9 @@ impl Rectangle2D {
|
|||
pub fn position(&self) -> Position2D {
|
||||
self.position
|
||||
}
|
||||
|
||||
pub fn set_position(&mut self, position: Position2D) {
|
||||
self.position = position;
|
||||
}
|
||||
|
||||
pub fn size(&self) -> Vec2 {
|
||||
self.size
|
||||
}
|
||||
|
|
@ -261,4 +275,33 @@ impl Transform3D {
|
|||
pub fn rotation_mut(&mut self) -> &mut Rotation3D {
|
||||
&mut self.rotation
|
||||
}
|
||||
}
|
||||
|
||||
impl Camera2D {
|
||||
pub fn new(left: f32, right: f32, bottom: f32, top: f32, near: f32, far: f32, zoom: f32) -> Self {
|
||||
Self {
|
||||
left,
|
||||
right,
|
||||
bottom,
|
||||
top,
|
||||
near,
|
||||
far,
|
||||
zoom
|
||||
}
|
||||
}
|
||||
|
||||
fn in_view_frustum(&self, camera_pos: Position2D, entity: Position2D) -> bool {
|
||||
let left = camera_pos.x() - self.zoom;
|
||||
let right = camera_pos.x() + self.zoom;
|
||||
let bottom = camera_pos.y() - self.zoom;
|
||||
let top = camera_pos.y() + self.zoom;
|
||||
|
||||
entity.x() < right && entity.x() > left && entity.y() < top && entity.y() > bottom
|
||||
}
|
||||
}
|
||||
|
||||
impl Camera for Camera2D {
|
||||
fn get_visible_entities(&self) -> Vec<Entity> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
|
@ -193,6 +193,9 @@ impl Drop for BlobVec {
|
|||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for BlobVec {}
|
||||
unsafe impl Sync for BlobVec {}
|
||||
|
||||
fn array_layout(layout: &Layout, n: usize) -> Option<Layout> {
|
||||
let (array_layout, offset) = repeat_layout(layout, n)?;
|
||||
debug_assert_eq!(layout.size(), offset);
|
||||
|
|
@ -538,7 +541,7 @@ impl Hash for ComponentSet {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Archetypes {
|
||||
archetypes: HashMap<ComponentSet, Vec<u32>>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ use crate::{
|
|||
};
|
||||
use comet_log::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct World {
|
||||
id_queue: IdQueue,
|
||||
next_id: u32,
|
||||
|
|
@ -23,17 +24,16 @@ pub struct World {
|
|||
|
||||
impl World {
|
||||
pub fn new() -> Self {
|
||||
let mut component_storage = ComponentStorage::new();
|
||||
|
||||
Self {
|
||||
id_queue: IdQueue::new(),
|
||||
next_id: 0,
|
||||
entities: Vec::new(),
|
||||
components: component_storage,
|
||||
components: ComponentStorage::new(),
|
||||
archetypes: Archetypes::new()
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of how many entities exist in the current World.
|
||||
pub fn active_entities(&self) -> u32 {
|
||||
self.entities.len() as u32 - self.id_queue.size()
|
||||
}
|
||||
|
|
@ -48,48 +48,42 @@ impl World {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn id_queue(&self) -> &IdQueue {
|
||||
&self.id_queue
|
||||
}
|
||||
|
||||
/// Retuns the `Vec` of `Option<Entity>` which contains all the entities in the current World.
|
||||
pub fn entities(&self) -> &Vec<Option<Entity>> {
|
||||
&self.entities
|
||||
}
|
||||
|
||||
pub fn components(&self) -> &ComponentStorage {
|
||||
&self.components
|
||||
}
|
||||
|
||||
pub fn components_mut(&mut self) -> &mut ComponentStorage {
|
||||
&mut self.components
|
||||
}
|
||||
|
||||
/// Creates a new entity and returns its ID.
|
||||
pub fn new_entity(&mut self) -> u32 {
|
||||
let id = self.next_id;
|
||||
if (self.next_id as usize) >= self.entities.len() {
|
||||
self.entities.push(Some(Entity::new(self.next_id)));
|
||||
self.get_next_id();
|
||||
info!("Created entity! ID: {}", id);
|
||||
return id;
|
||||
}
|
||||
self.entities[self.next_id as usize] = Some(Entity::new(self.next_id));
|
||||
self.get_next_id();
|
||||
info!("Created entity! ID: {}", id);
|
||||
id
|
||||
}
|
||||
|
||||
pub fn get_entity(&self, entity_id: usize) -> &Entity {
|
||||
assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||
self.entities.get(entity_id).unwrap().as_ref().unwrap()
|
||||
/// Gets an immutable reference to an entity by its ID.
|
||||
pub fn get_entity(&self, entity_id: usize) -> Option<&Entity> {
|
||||
//assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||
self.entities.get(entity_id).unwrap().as_ref()
|
||||
}
|
||||
|
||||
pub fn get_entity_mut(&mut self, entity_id: usize) -> &mut Entity {
|
||||
assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||
self.entities.get_mut(entity_id).unwrap().as_mut().unwrap()
|
||||
/// Gets a mutable reference to an entity by its ID.
|
||||
pub fn get_entity_mut(&mut self, entity_id: usize) -> Option<&mut Entity> {
|
||||
//assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||
self.entities.get_mut(entity_id).unwrap().as_mut()
|
||||
//self.entities.get_mut(id).unwrap()
|
||||
}
|
||||
|
||||
/// Deletes an entity by its ID.
|
||||
pub fn delete_entity(&mut self, entity_id: usize) {
|
||||
self.entities[entity_id] = None;
|
||||
//self.get_entity(id);
|
||||
for (key, value) in self.components.iter_mut() {
|
||||
value.remove::<u8>(entity_id);
|
||||
}
|
||||
|
|
@ -154,55 +148,59 @@ impl World {
|
|||
ComponentSet::from_ids(type_ids)
|
||||
}
|
||||
|
||||
pub fn register_component<T: Component + 'static>(&mut self) {
|
||||
self.components.register_component::<T>(self.entities.len());
|
||||
self.create_archetype(ComponentSet::from_ids(vec![T::type_id()]));
|
||||
info!("Registered component: {}", T::type_name());
|
||||
/// Registers a new component in the world.
|
||||
pub fn register_component<C: Component + 'static>(&mut self) {
|
||||
self.components.register_component::<C>(self.entities.len());
|
||||
self.create_archetype(ComponentSet::from_ids(vec![C::type_id()]));
|
||||
info!("Registered component: {}", C::type_name());
|
||||
}
|
||||
|
||||
pub fn deregister_component<T: Component + 'static>(&mut self) {
|
||||
self.components.deregister_component::<T>();
|
||||
info!("Deregistered component: {}", T::type_name());
|
||||
/// Deregisters a component from the world.
|
||||
pub fn deregister_component<C: Component + 'static>(&mut self) {
|
||||
self.components.deregister_component::<C>();
|
||||
info!("Deregistered component: {}", C::type_name());
|
||||
}
|
||||
|
||||
pub fn add_component<T: Component + 'static>(&mut self, entity_id: usize, component: T) {
|
||||
/// Adds a component to an entity by its ID and an instance of the component.
|
||||
pub fn add_component<C: Component + 'static>(&mut self, entity_id: usize, component: C) {
|
||||
assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||
self.components.set_component(entity_id, component);
|
||||
let component_index = self.components.keys.iter_mut().position(|x| *x == T::type_id()).unwrap();
|
||||
let component_index = self.components.keys.iter_mut().position(|x| *x == C::type_id()).unwrap();
|
||||
|
||||
self.get_entity_mut(entity_id).add_component(component_index);
|
||||
self.get_entity_mut(entity_id).unwrap().add_component(component_index);
|
||||
|
||||
if !self.archetypes.contains_archetype(&self.get_component_set(entity_id)) {
|
||||
self.create_archetype(self.get_component_set(entity_id));
|
||||
}
|
||||
self.add_entity_to_archetype(entity_id as u32, ComponentSet::from_ids(vec![T::type_id()]));
|
||||
if self.get_component_set(entity_id) != ComponentSet::from_ids(vec![T::type_id()]) {
|
||||
self.add_entity_to_archetype(entity_id as u32, ComponentSet::from_ids(vec![C::type_id()]));
|
||||
if self.get_component_set(entity_id) != ComponentSet::from_ids(vec![C::type_id()]) {
|
||||
self.add_entity_to_archetype(entity_id as u32, self.get_component_set(entity_id));
|
||||
}
|
||||
info!("Added component {} to entity {}", T::type_name(), entity_id);
|
||||
info!("Added component {} to entity {}", C::type_name(), entity_id);
|
||||
}
|
||||
|
||||
pub fn remove_component<T: Component + 'static>(&mut self, entity_id: usize) {
|
||||
self.components.remove_component::<T>(entity_id);
|
||||
/// Removes a component from an entity by its ID.
|
||||
pub fn remove_component<C: Component + 'static>(&mut self, entity_id: usize) {
|
||||
self.components.remove_component::<C>(entity_id);
|
||||
self.remove_entity_from_archetype_subsets(entity_id as u32, self.get_component_set(entity_id));
|
||||
info!("Removed component {} from entity {}", T::type_name(), entity_id);
|
||||
info!("Removed component {} from entity {}", C::type_name(), entity_id);
|
||||
}
|
||||
|
||||
pub fn get_component<T: Component + 'static>(&self, entity_id: usize) -> &T {
|
||||
/// Returns a reference to a component of an entity by its ID.
|
||||
pub fn get_component<C: Component + 'static>(&self, entity_id: usize) -> Option<&C> {
|
||||
//assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||
self.components.get_component::<C>(entity_id)
|
||||
}
|
||||
|
||||
pub fn get_component_mut<C: Component + 'static>(&mut self, entity_id: usize) -> Option<&mut C> {
|
||||
assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||
//assert_ne!(self.components.get_component::<T>(entity_id), None, "There is no component {} bound to the entity {} in the world!", T::type_name(), entity_id);
|
||||
self.components.get_component::<T>(entity_id).unwrap()
|
||||
}
|
||||
|
||||
pub fn get_component_mut<T: Component + 'static>(&mut self, entity_id: usize) -> &mut T {
|
||||
assert_ne!(self.entities.get(entity_id), None, "There is no entity with this ID ({}) in the world!", entity_id);
|
||||
assert!(self.components.get_component::<T>(entity_id) != None, "There is no component {} bound to the entity {} in the world!", T::type_name(), entity_id);
|
||||
self.components.get_component_mut::<T>(entity_id).unwrap()
|
||||
assert!(self.components.get_component::<C>(entity_id) != None, "There is no component {} bound to the entity {} in the world!", C::type_name(), entity_id);
|
||||
self.components.get_component_mut::<C>(entity_id)
|
||||
}
|
||||
|
||||
/// Returns a list of entities that have the given components.
|
||||
pub fn get_entities_with(&self, components: ComponentSet) -> Vec<u32> {
|
||||
assert!(self.archetypes.contains_archetype(&components), "The given components {:?} are not registered in the world!", components);
|
||||
//debug!(format!("Querying entities with components: {:?}", components));
|
||||
self.archetypes.get_archetype(&components).unwrap().clone()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue