use crate::*;
impl Entity {
pub fn generate_id() -> u64 {
NEXT_ENTITY_ID.fetch_add(1, Ordering::Relaxed)
}
pub fn create(name: &str) -> Entity {
Entity::new(
Self::generate_id(),
name.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.borrow_mut().on_start();
self.get_mut_components().push(component);
}
pub fn remove_component_by_name(&mut self, name: &str) -> Option<ComponentRc> {
let position: Option<usize> = self
.get_components()
.iter()
.position(|component: &ComponentRc| component.borrow().name() == name);
let index: usize = position?;
let removed: ComponentRc = self.get_mut_components().remove(index);
removed.borrow_mut().on_destroy();
Some(removed)
}
pub fn get_component_by_name(&self, name: &str) -> Option<ComponentRc> {
self.get_components()
.iter()
.find(|component: &&ComponentRc| component.borrow().name() == name)
.cloned()
}
pub fn update(&mut self, delta_time: f64) {
if !self.get_active() {
return;
}
for component in self.get_components() {
component.borrow_mut().on_update(delta_time);
}
}
pub fn render(&self, context: &CanvasRenderingContext2d) {
if !self.get_active() {
return;
}
let transform: Transform2D = self.get_transform();
for component in self.get_components() {
component.borrow_mut().on_render(context, &transform);
}
}
pub fn destroy(&mut self) {
for component in self.get_components() {
component.borrow_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(&self, tag: &str) -> bool {
self.get_tags().iter().any(|t: &String| t == tag)
}
}
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(&mut self, event_name: &str) {
self.get_mut_handlers().remove(event_name);
}
pub fn handler_count(&self, event_name: &str) -> usize {
self.get_handlers()
.get(event_name)
.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()
}
}