Added basic fps indicator

master
Mark 2024-02-03 07:47:19 -08:00
parent 3c582006ef
commit 91b82fbe3d
Signed by: Mark
GPG Key ID: C6D63995FE72FD80
9 changed files with 198 additions and 107 deletions

View File

@ -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,
});
}
}

View File

@ -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<RefCell<Sprite>>),
RadialBar(Rc<RefCell<RadialBar>>),
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<Rc<RefCell<Sprite>>> {
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<Rc<RefCell<RadialBar>>> {
match self {
Self::RadialBar(r) => Some(r.clone()),
_ => None,
}
}
}
pub(crate) struct UiManager {
current_scene: UiScene,
engine: Engine,
scope: Scope<'static>,
elements: Vec<UiElement>,
ct: Rc<Content>,
show_timings: bool,
fps_indicator: FpsIndicator,
}
impl UiManager {
pub fn new(ct: Rc<Content>) -> Self {
pub fn new(ct: Rc<Content>, 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<TextArea<'a>> {
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
}
}

View File

@ -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;

View File

@ -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,
}
}
}

View File

@ -0,0 +1,44 @@
use std::{cell::RefCell, rc::Rc};
use super::util::{RadialBar, Sprite, TextBox};
pub enum UiElement {
Sprite(Rc<RefCell<Sprite>>),
RadialBar(Rc<RefCell<RadialBar>>),
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<Rc<RefCell<Sprite>>> {
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<Rc<RefCell<RadialBar>>> {
match self {
Self::RadialBar(r) => Some(r.clone()),
_ => None,
}
}
}

View File

@ -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(),
}
}
}

View File

@ -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),
}
}
}

View File

@ -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::*;

View File

@ -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 {