use crate::graphics::{GraphicsContext, Rectangle};
use anyhow::Result;
pub trait Component {
fn render(&self, graphics: &mut GraphicsContext) -> Result<()>;
fn bounds(&self) -> Rectangle;
fn update(&mut self, delta_time: f64) -> bool;
#[allow(dead_code)]
fn is_visible(&self) -> bool {
true
}
fn should_remove(&self) -> bool {
false
}
#[allow(dead_code)]
fn render_priority(&self) -> i32 {
0
}
#[allow(dead_code)]
fn calculate_bounds(&self) -> Rectangle {
self.bounds()
}
}
pub trait ComponentExt {
#[allow(dead_code)]
fn render_visible(&self, graphics: &mut GraphicsContext) -> Result<()>;
fn update_all(&mut self, delta_time: f64) -> bool;
fn remove_expired(&mut self) -> usize;
#[allow(dead_code)]
fn sort_by_priority(&mut self);
}
impl ComponentExt for Vec<Box<dyn Component>> {
fn render_visible(&self, graphics: &mut GraphicsContext) -> Result<()> {
self.iter()
.filter(|component| component.is_visible())
.try_for_each(|component| component.render(graphics))
}
fn update_all(&mut self, delta_time: f64) -> bool {
self.iter_mut()
.any(|component| component.update(delta_time))
}
fn remove_expired(&mut self) -> usize {
let original_len = self.len();
self.retain(|component| !component.should_remove());
original_len - self.len()
}
fn sort_by_priority(&mut self) {
self.sort_by_key(|component| component.render_priority());
}
}