Skip to content

Commit 8697188

Browse files
authored
Merge pull request #16 from ckaznable/fps
feat: add `--show-fps` flags
2 parents fb6bd75 + bda08e4 commit 8697188

File tree

6 files changed

+60
-4
lines changed

6 files changed

+60
-4
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Usage: tenki [OPTIONS]
4545
Options:
4646
--mode <MODE> [default: rain] [rain, snow]
4747
--fps <FPS> [default: 60] [1-60]
48+
--show-fps Show fps at right-top in screen
4849
--timer-color <COLOR> Timer color [default: white] [red, green, blue, yellow, cyan, magenta, white, black]
4950
--wind <WIND> Decide on the direction of the rain/snow [defualt: random] [random, disable, only-right, only-left]
5051
-l, --level <LEVEL> Effect level, The lower, the stronger [default: 50] [4-1000]

src/app.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,19 @@ use crate::{
1111
cli::Args, state::{EachFrameImpl, State}, tui::{Event, Tui}, ui::ui, widget::AsWeatherWidget
1212
};
1313

14+
#[derive(Copy, Clone)]
15+
pub struct AppRuntimeInfo {
16+
pub fps: usize,
17+
}
18+
1419
pub struct App<T> {
1520
terminal: Terminal<CrosstermBackend<std::io::Stdout>>,
1621
tui: Tui,
1722
state: State<T>,
1823
should_quit: bool,
1924
args: Args,
25+
frame_in_second: usize,
26+
runtime_info: AppRuntimeInfo,
2027
}
2128

2229
impl<T> App<T>
@@ -39,6 +46,8 @@ where
3946
args,
4047
tui: Tui::new(args.fps as f64)?,
4148
should_quit: false,
49+
frame_in_second: 0,
50+
runtime_info: AppRuntimeInfo { fps: 0 },
4251
})
4352
}
4453

@@ -51,9 +60,9 @@ where
5160
match event {
5261
Init => (),
5362
Quit | Error => self.should_quit = true,
54-
Render => self.state.tick(),
63+
Render => self.on_render(),
5564
Key(key) => self.handle_keyboard(key),
56-
Timer => self.state.tick_timer(),
65+
Timer => self.on_timer(),
5766
Resize(columns, rows) => self.state.on_resize(columns, rows),
5867
};
5968
};
@@ -62,7 +71,7 @@ where
6271
break;
6372
}
6473

65-
self.terminal.draw(|f| ui(f, &mut self.state, self.args))?;
74+
self.terminal.draw(|f| ui(f, &mut self.state, self.args, self.runtime_info))?;
6675
}
6776

6877
Ok(())
@@ -74,6 +83,17 @@ where
7483
_ => {}
7584
}
7685
}
86+
87+
fn on_render(&mut self) {
88+
self.state.tick();
89+
self.frame_in_second = self.frame_in_second.saturating_add(1);
90+
}
91+
92+
fn on_timer(&mut self) {
93+
self.state.tick_timer();
94+
self.runtime_info.fps = self.frame_in_second;
95+
self.frame_in_second = 0;
96+
}
7797
}
7898

7999
impl<T> Drop for App<T> {

src/cli.rs

+4
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ pub struct Args {
2626
/// wind mode. [random, disable, only-right, only-left]
2727
#[arg(long, value_parser = WindMode::from_str, default_value = "random")]
2828
pub wind: WindMode,
29+
30+
/// show fps at right-top in screen
31+
#[arg(long)]
32+
pub show_fps: bool,
2933
}
3034

3135
fn fps_range(s: &str) -> Result<u8, String> {

src/ui.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
use ratatui::Frame;
2+
use crate::app::AppRuntimeInfo;
23
use crate::state::{EachFrameImpl, State};
34
use crate::cli::Args;
45

6+
use crate::widget::fps::FpsWidget;
57
use crate::widget::{AsWeatherWidget, WeatherWidget};
68
use crate::widget::timer::Timer;
79

8-
pub fn ui<T: EachFrameImpl + AsWeatherWidget>(f: &mut Frame, state: &mut State<T>, args: Args) {
10+
pub fn ui<T: EachFrameImpl + AsWeatherWidget>(f: &mut Frame, state: &mut State<T>, args: Args, runtime_info: AppRuntimeInfo) {
911
let area = f.size();
1012

1113
f.render_stateful_widget(WeatherWidget::new(state.weather.as_weather_widget()), area, &mut state.rb);
1214
f.render_widget(Timer(state.timer, args.timer_color), area);
15+
16+
if args.show_fps {
17+
f.render_widget(FpsWidget(runtime_info.fps), area)
18+
}
1319
}

src/widget/fps.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use ratatui::{
2+
layout::{Constraint, Direction, Layout},
3+
style::{Style, Stylize},
4+
text::Line,
5+
widgets::Widget,
6+
};
7+
8+
pub struct FpsWidget(pub usize);
9+
10+
impl Widget for FpsWidget {
11+
fn render(self, area: ratatui::prelude::Rect, buf: &mut ratatui::prelude::Buffer) {
12+
let [_, fps_area, _] = Layout::new(
13+
Direction::Horizontal,
14+
[
15+
Constraint::Min(0),
16+
Constraint::Length(3),
17+
Constraint::Length(2),
18+
],
19+
)
20+
.areas(area);
21+
22+
Line::styled(self.0.to_string(), Style::new().green()).render(fps_area, buf);
23+
}
24+
}

src/widget/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use ratatui::{
77

88
use crate::state::{buffer::RenderBuffer, DropCell, DropSpeed};
99

10+
pub mod fps;
1011
pub mod timer;
1112
pub mod weather;
1213

0 commit comments

Comments
 (0)