//! Contains APIs for accessing game resources.

use std::{cell::RefCell, rc::Rc};
use super::{
    entity::Entities,
    event::{Events, EventHandler},
};

/// Contains game resources.
#[derive(Default)]
pub struct World {
    entities: Entities,

    // This has to be a celled Rc as this struct must be in world while also depending on it.
    events: Rc<RefCell<Events>>,
}

impl World {
    /// Retrieves an immutable reference to the engines entity store.
    pub fn entities_ref(&self) -> &Entities {
        &self.entities
    }

    /// Retrieves a mutable reference to the engines entity store.
    pub fn entities_mut(&mut self) -> &mut Entities {
        &mut self.entities
    }

    pub fn register<TEvent, TEventHandler>(&mut self, handler: TEventHandler)
        where
            TEvent: 'static,
            TEventHandler: EventHandler<TEvent> + 'static,
    {
        self.events
            .borrow_mut()
            .register(handler);
    }

    pub fn trigger<TEvent>(&mut self, event: &TEvent)
        where
            TEvent: 'static,
    {
        self.events
            .clone()
            .borrow()
            .trigger(event, self);
    }
}

