use super::*;
impl Entity {
pub fn generate_id() -> u64 {
NEXT_ENTITY_ID.fetch_add(1, Ordering::Relaxed)
}
pub fn create<N>(name: N) -> Entity
where
N: AsRef<str>,
{
Entity::new(
Self::generate_id(),
name.as_ref().to_string(),
Transform2D::identity(),
true,
Vec::new(),
Vec::new(),
)
}
pub fn create_at(position: Vector2D) -> Entity {
let mut entity: Entity = Self::create(DEFAULT_ENTITY_NAME);
entity.get_mut_transform().set_position(position);
entity
}
}
impl Entity {
pub fn add_component(&mut self, component: ComponentRc) {
component.get_mut().on_start();
self.get_mut_components().push(component);
}
pub fn remove_component_by_name<N>(&mut self, name: N) -> Option<ComponentRc>
where
N: AsRef<str>,
{
let target: &str = name.as_ref();
let position: Option<usize> = self
.get_components()
.iter()
.position(|component: &ComponentRc| component.get().name() == target);
let index: usize = position?;
let removed: ComponentRc = self.get_mut_components().remove(index);
removed.get_mut().on_destroy();
Some(removed)
}
pub fn get_component_by_name<N>(&self, name: N) -> Option<ComponentRc>
where
N: AsRef<str>,
{
let target: &str = name.as_ref();
self.get_components()
.iter()
.find(|component: &&ComponentRc| component.get().name() == target)
.cloned()
}
pub fn update(&mut self, delta_time: f64) {
if !self.get_active() {
return;
}
for component in self.get_components() {
component.get_mut().on_update(delta_time);
}
}
pub fn render(&self, draw_list: &mut DrawList) {
if !self.get_active() {
return;
}
let transform: Transform2D = self.get_transform();
for component in self.get_components() {
component.get_mut().on_render(draw_list, &transform);
}
}
pub fn destroy(&mut self) {
for component in self.get_components() {
component.get_mut().on_destroy();
}
self.get_mut_components().clear();
}
pub fn add_tag(&mut self, tag: String) {
if !self.get_tags().contains(&tag) {
self.get_mut_tags().push(tag);
}
}
pub fn has_tag<T>(&self, tag: T) -> bool
where
T: AsRef<str>,
{
let target: &str = tag.as_ref();
self.get_tags().iter().any(|t: &String| t == target)
}
}
impl Updatable for Entity {
fn update(&mut self, delta_time: f64) {
Entity::update(self, delta_time);
}
}
impl EventBus {
pub fn create() -> EventBus {
EventBus::new()
}
pub fn subscribe(&mut self, event_name: String, handler: EventHandler) {
self.get_mut_handlers()
.entry(event_name)
.or_default()
.push(handler);
}
pub fn emit(&self, event: &EntityEvent) {
let event_name: String = Self::event_name(event);
if let Some(handlers) = self.get_handlers().get(&event_name) {
for handler in handlers {
handler(event);
}
}
}
pub fn unsubscribe_all<E>(&mut self, event_name: E)
where
E: AsRef<str>,
{
self.get_mut_handlers().remove(event_name.as_ref());
}
pub fn handler_count<E>(&self, event_name: E) -> usize
where
E: AsRef<str>,
{
self.get_handlers()
.get(event_name.as_ref())
.map(|handlers: &Vec<EventHandler>| handlers.len())
.unwrap_or(0)
}
fn event_name(event: &EntityEvent) -> String {
match event {
EntityEvent::Collision { .. } => "collision".to_string(),
EntityEvent::TriggerEnter { .. } => "trigger_enter".to_string(),
EntityEvent::TriggerExit { .. } => "trigger_exit".to_string(),
EntityEvent::Spawn => "spawn".to_string(),
EntityEvent::Destroy => "destroy".to_string(),
EntityEvent::Custom { name, .. } => name.clone(),
}
}
}
impl Default for EventBus {
fn default() -> EventBus {
EventBus::create()
}
}