use std::collections::HashMap;
use std::sync::Arc;
use crate::core::{Entity, EntityId, SystemError, InputState};
use crate::systems::RenderSystem;
use super::scheduler::SystemScheduler;
use super::camera::Camera;
use super::asset::AssetManager;
pub struct World {
entities: Vec<Entity>,
entity_indices: HashMap<EntityId, usize>,
next_entity_id: u64,
scheduler: SystemScheduler,
entities_to_remove: Vec<EntityId>,
pub camera: Camera,
}
impl World {
pub fn new() -> Self {
Self {
entities: Vec::new(),
entity_indices: HashMap::new(),
next_entity_id: 1,
scheduler: SystemScheduler::new(),
entities_to_remove: Vec::new(),
camera: Camera::new(),
}
}
pub fn create_entity(&mut self) -> EntityId {
let id = EntityId::new(self.next_entity_id);
self.next_entity_id += 1;
let entity = Entity::new(id);
let index = self.entities.len();
self.entities.push(entity);
self.entity_indices.insert(id, index);
id
}
pub fn get_entity_mut(&mut self, entity_id: EntityId) -> Option<&mut Entity> {
self.entity_indices.get(&entity_id)
.and_then(|&index| self.entities.get_mut(index))
}
pub fn destroy_entity(&mut self, entity_id: EntityId) {
if self.entity_indices.contains_key(&entity_id) {
self.entities_to_remove.push(entity_id);
}
}
pub fn entities(&self) -> &[Entity] {
&self.entities
}
pub fn entities_mut(&mut self) -> &mut Vec<Entity> {
&mut self.entities
}
pub async fn initialize(&mut self, window: Arc<winit::window::Window>) -> Result<(), SystemError> {
let mut render_system = RenderSystem::new();
render_system.initialize(window).await?;
self.scheduler.register_system(render_system)?;
self.scheduler.initialize()
}
pub fn update(&mut self, delta_time: f32, input: &InputState, asset_manager: &mut AssetManager) -> Result<(), SystemError> {
self.camera.update(delta_time, input);
self.scheduler.update(delta_time, &mut self.entities, input, &self.camera, asset_manager)?;
self.process_entity_removals();
Ok(())
}
pub fn shutdown(&mut self) -> Result<(), SystemError> {
self.scheduler.shutdown()
}
pub fn camera(&self) -> &Camera {
&self.camera
}
pub fn camera_mut(&mut self) -> &mut Camera {
&mut self.camera
}
fn process_entity_removals(&mut self) {
for entity_id in self.entities_to_remove.drain(..) {
if let Some(&index) = self.entity_indices.get(&entity_id) {
self.entities.remove(index);
self.entity_indices.remove(&entity_id);
for (_, stored_index) in self.entity_indices.iter_mut() {
if *stored_index > index {
*stored_index -= 1;
}
}
}
}
}
}
impl Default for World {
fn default() -> Self {
Self::new()
}
}