use std::{cell::Cell, ops::Drop};
use crate::{
entity::{Entity, EntityBuilder, EntityComponentManager, EntityContainer, VecEntityContainer},
system::{EntitySystemBuilder, EntitySystemManager, System},
};
#[cfg(test)]
mod tests;
#[derive(Default)]
pub struct World<T>
where
T: EntityContainer,
{
entity_component_manager: EntityComponentManager,
entity_system_manager: EntitySystemManager<T>,
entity_counter: u32,
entity_sytem_counter: u32,
entity_container: T,
first_run: bool,
}
impl<T> Drop for World<T>
where
T: EntityContainer,
{
fn drop(&mut self) {
if let Some(cleanup_syste) = self.entity_system_manager.borrow_cleanup_system() {
cleanup_syste
.system
.run(&self.entity_container, &mut self.entity_component_manager);
}
}
}
unsafe impl<T> Send for World<T> where T: EntityContainer {}
impl<T> World<T>
where
T: EntityContainer,
{
pub fn new() -> World<VecEntityContainer> {
World::from_container(VecEntityContainer::default())
}
pub fn from_container(entity_container: T) -> Self {
World {
entity_component_manager: EntityComponentManager::new(),
entity_system_manager: EntitySystemManager::new(),
entity_counter: 0,
entity_sytem_counter: 0,
entity_container,
first_run: true,
}
}
pub fn entity_container(&mut self) -> &mut T {
&mut self.entity_container
}
pub fn create_entity(&mut self) -> EntityBuilder<'_, T> {
let entity = self.entity_counter;
self.entity_component_manager.register_entity(entity);
self.entity_counter += 1;
EntityBuilder {
entity,
entity_component_manager: &mut self.entity_component_manager,
entity_container: &mut self.entity_container,
}
}
pub fn remove_entity(&mut self, entity: Entity) {
self.entity_container.remove_entity(entity);
self.entity_component_manager.remove_entity(entity);
}
pub fn register_init_system(&mut self, init_system: impl System<T>) {
self.entity_system_manager.register_init_system(init_system);
}
pub fn register_cleanup_system(&mut self, cleanup_system: impl System<T>) {
self.entity_system_manager.register_cleanup_system(cleanup_system);
}
pub fn create_system(&mut self, system: impl System<T>) -> EntitySystemBuilder<'_, T> {
let entity_system_id = self.entity_sytem_counter;
self.entity_system_manager
.register_system(system, entity_system_id);
self.entity_sytem_counter += 1;
EntitySystemBuilder {
entity_system_manager: &mut self.entity_system_manager,
entity_system_id,
priority: Cell::new(0),
}
}
pub fn remove_system(&mut self, system_id: u32) {
self.entity_system_manager.remove_system(system_id);
}
pub fn entity_component_manager(&mut self) -> &mut EntityComponentManager {
&mut self.entity_component_manager
}
pub fn run(&mut self) {
if self.first_run {
if let Some(init_system) = self.entity_system_manager.borrow_init_system() {
init_system
.system
.run(&self.entity_container, &mut self.entity_component_manager);
}
self.first_run = false;
}
let priorities = &self.entity_system_manager.priorities;
for (_, prio) in priorities {
for system in prio {
self.entity_system_manager
.borrow_entity_system(*system)
.unwrap()
.system
.run(&self.entity_container, &mut self.entity_component_manager);
}
}
}
}