use std::string::ToString; use space_crush_common::{misc::LogResult, resources::Global}; use specs::{prelude::*, Entities, ReadExpect, System}; use crate::{ misc::{Text, TextCache, TextManager}, resources::State, Error, }; /* Summary */ pub struct Summary { cache: TextCache, text: Text, fps: usize, resolution: (u32, u32), mouse_pos: (f32, f32), entity_count: usize, } impl Summary { pub fn new(text_manager: &TextManager) -> Result { let cache = text_manager.create_cache()?; let text = cache .new_text() .scale(12.0) .font("resources/fonts/DroidSansMono.ttf") .color(0.7, 0.7, 0.7, 1.0) .position(5.0, 5.0) .text(format!("Space Crush v{}\n", env!("CARGO_PKG_VERSION"))) .text("\nfps: ") .text("-") .text("\nresolution: ") .text("1280 | 720") .text("\nmouse_pos: ") .text("0.00 | 0.00") .text("\nentities: ") .text("0") .build()?; Ok(Self { cache, text, fps: 0, resolution: (0, 0), mouse_pos: (0.0, 0.0), entity_count: 0, }) } } #[derive(SystemData)] pub struct SummaryData<'a> { entities: Entities<'a>, global: ReadExpect<'a, Global>, state: ReadExpect<'a, State>, } impl<'a> System<'a> for Summary { type SystemData = SummaryData<'a>; fn run(&mut self, data: Self::SystemData) { let SummaryData { entities, global, state, } = data; let entity_count = entities.par_join().count(); let guard = self.cache.begin_update(); update_text( &mut self.text, 2, &mut self.fps, &global.fps, ToString::to_string, ); update_text( &mut self.text, 4, &mut self.resolution, &state.resolution, |(w, h)| format!("{} | {}", w, h), ); update_text( &mut self.text, 6, &mut self.mouse_pos, &state.mouse_pos, |(x, y)| format!("{:.2} | {:.2}", x, y), ); update_text( &mut self.text, 8, &mut self.entity_count, &entity_count, |x| format!("{}", x), ); drop(guard); self.text.render(true); } } fn update_text(text: &mut Text, pos: usize, old: &mut T, new: &T, update: F) where T: PartialEq + Copy, F: FnOnce(&T) -> String, { if old != new { *old = *new; let s = update(old); text.update(pos, s).error("Unable to update debug text"); } }