Added basic fps indicator
parent
3c582006ef
commit
91b82fbe3d
|
@ -214,20 +214,7 @@ impl GPUState {
|
|||
let mut starfield = Starfield::new();
|
||||
starfield.regenerate(&ct);
|
||||
|
||||
return Ok(Self {
|
||||
ui: UiManager::new(ct),
|
||||
device,
|
||||
config,
|
||||
surface,
|
||||
starfield,
|
||||
texture_array,
|
||||
object_pipeline,
|
||||
starfield_pipeline,
|
||||
ui_pipeline,
|
||||
radialbar_pipeline,
|
||||
scene: RenderScenes::Landed,
|
||||
|
||||
state: RenderState {
|
||||
let mut state = RenderState {
|
||||
queue,
|
||||
window,
|
||||
window_size,
|
||||
|
@ -238,7 +225,21 @@ impl GPUState {
|
|||
text_cache,
|
||||
text_font_system,
|
||||
text_renderer,
|
||||
},
|
||||
};
|
||||
|
||||
return Ok(Self {
|
||||
ui: UiManager::new(ct, &mut state),
|
||||
device,
|
||||
config,
|
||||
surface,
|
||||
starfield,
|
||||
texture_array,
|
||||
object_pipeline,
|
||||
starfield_pipeline,
|
||||
ui_pipeline,
|
||||
radialbar_pipeline,
|
||||
scene: RenderScenes::Landed,
|
||||
state,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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::*;
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue