diff --git a/crates/render/src/gpustate.rs b/crates/render/src/gpustate.rs index b57e538..d691ab5 100644 --- a/crates/render/src/gpustate.rs +++ b/crates/render/src/gpustate.rs @@ -214,8 +214,21 @@ impl GPUState { let mut starfield = Starfield::new(); starfield.regenerate(&ct); + let mut state = RenderState { + queue, + window, + window_size, + window_aspect, + global_uniform, + vertex_buffers, + text_atlas, + text_cache, + text_font_system, + text_renderer, + }; + return Ok(Self { - ui: UiManager::new(ct), + ui: UiManager::new(ct, &mut state), device, config, surface, @@ -226,19 +239,7 @@ impl GPUState { ui_pipeline, radialbar_pipeline, scene: RenderScenes::Landed, - - state: RenderState { - queue, - window, - window_size, - window_aspect, - global_uniform, - vertex_buffers, - text_atlas, - text_cache, - text_font_system, - text_renderer, - }, + state, }); } } diff --git a/crates/render/src/ui/manager.rs b/crates/render/src/ui/manager.rs index e400978..bf756fb 100644 --- a/crates/render/src/ui/manager.rs +++ b/crates/render/src/ui/manager.rs @@ -3,11 +3,13 @@ use galactica_content::Content; use glyphon::TextArea; use log::{debug, error, trace}; use rhai::{Array, Dynamic, Engine, Scope, AST}; -use std::{cell::RefCell, collections::HashSet, fmt::Debug, rc::Rc}; +use std::{collections::HashSet, rc::Rc}; use super::{ api::{self, SceneAction, SpriteElement, TextBoxBuilder}, - util::{RadialBar, TextBox}, + mouseevent::MouseEvent, + util::{FpsIndicator, RadialBar, TextBox}, + UiElement, UiScene, }; use crate::{ ui::{ @@ -17,99 +19,19 @@ use crate::{ RenderInput, RenderState, }; -#[derive(Debug, Copy, Clone)] -pub enum MouseEvent { - Click, - Release, - Enter, - Leave, - None, -} - -impl MouseEvent { - pub fn is_enter(&self) -> bool { - match self { - Self::Enter => true, - _ => false, - } - } - - pub fn is_click(&self) -> bool { - match self { - Self::Click => true, - _ => false, - } - } -} - -#[derive(Debug, Copy, Clone)] -pub(crate) enum UiScene { - Landed, - Flying, - Outfitter, -} - -impl ToString for UiScene { - fn to_string(&self) -> String { - match self { - Self::Flying => "flying".to_string(), - Self::Landed => "landed".to_string(), - Self::Outfitter => "outfitter".to_string(), - } - } -} - -enum UiElement { - Sprite(Rc>), - RadialBar(Rc>), - Text(TextBox), -} - -impl UiElement { - pub fn new_sprite(sprite: Sprite) -> Self { - Self::Sprite(Rc::new(RefCell::new(sprite))) - } - - pub fn new_radialbar(bar: RadialBar) -> Self { - Self::RadialBar(Rc::new(RefCell::new(bar))) - } - - pub fn new_text(text: TextBox) -> Self { - Self::Text(text) - } - - pub fn sprite(&self) -> Option>> { - match self { - Self::Sprite(s) => Some(s.clone()), - _ => None, - } - } - - pub fn text(&self) -> Option<&TextBox> { - match self { - Self::Text(t) => Some(t), - _ => None, - } - } - - pub fn radialbar(&self) -> Option>> { - match self { - Self::RadialBar(r) => Some(r.clone()), - _ => None, - } - } -} - pub(crate) struct UiManager { current_scene: UiScene, engine: Engine, scope: Scope<'static>, elements: Vec, ct: Rc, + + show_timings: bool, + fps_indicator: FpsIndicator, } impl UiManager { - pub fn new(ct: Rc) -> Self { + pub fn new(ct: Rc, state: &mut RenderState) -> Self { let scope = Scope::new(); let mut engine = Engine::new(); @@ -121,6 +43,8 @@ impl UiManager { engine, scope, elements: Vec::new(), + show_timings: true, + fps_indicator: FpsIndicator::new(state), } } @@ -227,6 +151,10 @@ impl UiManager { pub fn draw(&mut self, input: &RenderInput, state: &mut RenderState) -> Result<()> { let mut iter = self.elements.iter(); + if self.show_timings { + self.fps_indicator.step(input, state); + } + let action: SceneAction = loop { let e = match iter.next() { Some(e) => e, @@ -298,12 +226,22 @@ impl<'a> UiManager { input: &RenderInput, state: &RenderState, ) -> Vec> { - self.elements + let mut v = Vec::with_capacity(32); + if self.show_timings { + v.push(self.fps_indicator.get_textarea(state, input)) + } + + for t in self + .elements .iter() .map(|x| x.text()) .filter(|x| x.is_some()) .map(|x| x.unwrap()) .map(|x| x.get_textarea(state, input)) - .collect() + { + v.push(t) + } + + v } } diff --git a/crates/render/src/ui/mod.rs b/crates/render/src/ui/mod.rs index d9199cc..520a3e5 100644 --- a/crates/render/src/ui/mod.rs +++ b/crates/render/src/ui/mod.rs @@ -1,6 +1,10 @@ mod api; mod manager; +mod mouseevent; +mod uielement; +mod uiscene; mod util; pub(crate) use manager::UiManager; -pub(crate) use manager::UiScene; +pub(crate) use uielement::UiElement; +pub(crate) use uiscene::UiScene; diff --git a/crates/render/src/ui/mouseevent.rs b/crates/render/src/ui/mouseevent.rs new file mode 100644 index 0000000..997fdcc --- /dev/null +++ b/crates/render/src/ui/mouseevent.rs @@ -0,0 +1,24 @@ +#[derive(Debug, Copy, Clone)] +pub enum MouseEvent { + Click, + Release, + Enter, + Leave, + None, +} + +impl MouseEvent { + pub fn is_enter(&self) -> bool { + match self { + Self::Enter => true, + _ => false, + } + } + + pub fn is_click(&self) -> bool { + match self { + Self::Click => true, + _ => false, + } + } +} diff --git a/crates/render/src/ui/uielement.rs b/crates/render/src/ui/uielement.rs new file mode 100644 index 0000000..c5cd805 --- /dev/null +++ b/crates/render/src/ui/uielement.rs @@ -0,0 +1,44 @@ +use std::{cell::RefCell, rc::Rc}; + +use super::util::{RadialBar, Sprite, TextBox}; + +pub enum UiElement { + Sprite(Rc>), + RadialBar(Rc>), + Text(TextBox), +} + +impl UiElement { + pub fn new_sprite(sprite: Sprite) -> Self { + Self::Sprite(Rc::new(RefCell::new(sprite))) + } + + pub fn new_radialbar(bar: RadialBar) -> Self { + Self::RadialBar(Rc::new(RefCell::new(bar))) + } + + pub fn new_text(text: TextBox) -> Self { + Self::Text(text) + } + + pub fn sprite(&self) -> Option>> { + match self { + Self::Sprite(s) => Some(s.clone()), + _ => None, + } + } + + pub fn text(&self) -> Option<&TextBox> { + match self { + Self::Text(t) => Some(t), + _ => None, + } + } + + pub fn radialbar(&self) -> Option>> { + match self { + Self::RadialBar(r) => Some(r.clone()), + _ => None, + } + } +} diff --git a/crates/render/src/ui/uiscene.rs b/crates/render/src/ui/uiscene.rs new file mode 100644 index 0000000..19b62d6 --- /dev/null +++ b/crates/render/src/ui/uiscene.rs @@ -0,0 +1,16 @@ +#[derive(Debug, Copy, Clone)] +pub(crate) enum UiScene { + Landed, + Flying, + Outfitter, +} + +impl ToString for UiScene { + fn to_string(&self) -> String { + match self { + Self::Flying => "flying".to_string(), + Self::Landed => "landed".to_string(), + Self::Outfitter => "outfitter".to_string(), + } + } +} diff --git a/crates/render/src/ui/util/fpsindicator.rs b/crates/render/src/ui/util/fpsindicator.rs new file mode 100644 index 0000000..59c40c0 --- /dev/null +++ b/crates/render/src/ui/util/fpsindicator.rs @@ -0,0 +1,60 @@ +use glyphon::{Attrs, Buffer, Color, Family, Metrics, Shaping, TextArea, TextBounds}; + +use crate::{RenderInput, RenderState}; + +pub(crate) struct FpsIndicator { + buffer: Buffer, + update_counter: u32, +} + +impl FpsIndicator { + pub fn new(state: &mut RenderState) -> Self { + let mut buffer = Buffer::new(&mut state.text_font_system, Metrics::new(7.0, 8.0)); + buffer.set_size( + &mut state.text_font_system, + state.window_size.width as f32, + state.window_size.height as f32, + ); + + Self { + buffer, + update_counter: 0, + } + } +} + +impl FpsIndicator { + pub fn step(&mut self, input: &RenderInput, state: &mut RenderState) { + if self.update_counter > 0 { + self.update_counter -= 1; + return; + } + self.update_counter = 100; + + self.buffer.set_text( + &mut state.text_font_system, + &input.timing.get_string(), + Attrs::new().family(Family::Monospace), + Shaping::Basic, + ); + self.buffer.shape_until_scroll(&mut state.text_font_system); + } +} + +impl<'a, 'b: 'a> FpsIndicator { + pub fn get_textarea(&'b self, _state: &RenderState, input: &RenderInput) -> TextArea<'a> { + TextArea { + buffer: &self.buffer, + left: 10.0, + top: 400.0, + scale: input.ct.get_config().ui_scale, + bounds: TextBounds { + left: 10, + top: 400, + right: 300, + bottom: 800, + }, + default_color: Color::rgb(255, 255, 255), + } + } +} diff --git a/crates/render/src/ui/util/mod.rs b/crates/render/src/ui/util/mod.rs index 142a322..4e72c6a 100644 --- a/crates/render/src/ui/util/mod.rs +++ b/crates/render/src/ui/util/mod.rs @@ -1,7 +1,9 @@ +mod fpsindicator; mod radialbar; mod sprite; mod textbox; -pub use radialbar::*; -pub use sprite::*; -pub use textbox::*; +pub(super) use fpsindicator::*; +pub(super) use radialbar::*; +pub(super) use sprite::*; +pub(super) use textbox::*; diff --git a/crates/render/src/ui/util/sprite.rs b/crates/render/src/ui/util/sprite.rs index 7c16b09..89605ac 100644 --- a/crates/render/src/ui/util/sprite.rs +++ b/crates/render/src/ui/util/sprite.rs @@ -2,7 +2,9 @@ use galactica_content::{Content, SpriteAutomaton, SpriteHandle}; use galactica_util::to_radians; use super::super::api::Rect; -use crate::{ui::manager::MouseEvent, vertexbuffer::types::UiInstance, RenderInput, RenderState}; +use crate::{ + ui::mouseevent::MouseEvent, vertexbuffer::types::UiInstance, RenderInput, RenderState, +}; #[derive(Debug, Clone)] pub struct Sprite {