mirror of
https://github.com/ratatui/ratatui.git
synced 2025-10-03 07:45:59 +00:00
feat: Add frame count ✨ (#766)
This commit is contained in:
parent
06141900b4
commit
c50ff08a63
@ -26,6 +26,9 @@ pub struct Frame<'a> {
|
|||||||
|
|
||||||
/// The buffer that is used to draw the current frame
|
/// The buffer that is used to draw the current frame
|
||||||
pub(crate) buffer: &'a mut Buffer,
|
pub(crate) buffer: &'a mut Buffer,
|
||||||
|
|
||||||
|
/// The frame count indicating the sequence number of this frame.
|
||||||
|
pub(crate) count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `CompletedFrame` represents the state of the terminal after all changes performed in the last
|
/// `CompletedFrame` represents the state of the terminal after all changes performed in the last
|
||||||
@ -37,6 +40,8 @@ pub struct CompletedFrame<'a> {
|
|||||||
pub buffer: &'a Buffer,
|
pub buffer: &'a Buffer,
|
||||||
/// The size of the last frame.
|
/// The size of the last frame.
|
||||||
pub area: Rect,
|
pub area: Rect,
|
||||||
|
/// The frame count indicating the sequence number of this frame.
|
||||||
|
pub count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frame<'_> {
|
impl Frame<'_> {
|
||||||
@ -119,4 +124,32 @@ impl Frame<'_> {
|
|||||||
pub fn buffer_mut(&mut self) -> &mut Buffer {
|
pub fn buffer_mut(&mut self) -> &mut Buffer {
|
||||||
self.buffer
|
self.buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns the current frame count.
|
||||||
|
///
|
||||||
|
/// This method provides access to the frame count, which is a sequence number indicating
|
||||||
|
/// how many frames have been rendered up to (but not including) this one. It can be used
|
||||||
|
/// for purposes such as animation, performance tracking, or debugging.
|
||||||
|
///
|
||||||
|
/// Each time a frame has been rendered, this count is incremented,
|
||||||
|
/// providing a consistent way to reference the order and number of frames processed by the
|
||||||
|
/// terminal. When count reaches its maximum value (usize::MAX), it wraps around to zero.
|
||||||
|
///
|
||||||
|
/// This count is particularly useful when dealing with dynamic content or animations where the
|
||||||
|
/// state of the display changes over time. By tracking the frame count, developers can
|
||||||
|
/// synchronize updates or changes to the content with the rendering process.
|
||||||
|
///
|
||||||
|
/// # Examples
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use ratatui::{backend::TestBackend, prelude::*, widgets::*};
|
||||||
|
/// # let backend = TestBackend::new(5, 5);
|
||||||
|
/// # let mut terminal = Terminal::new(backend).unwrap();
|
||||||
|
/// # let mut frame = terminal.get_frame();
|
||||||
|
/// let current_count = frame.count();
|
||||||
|
/// println!("Current frame count: {}", current_count);
|
||||||
|
/// ```
|
||||||
|
pub fn count(&self) -> usize {
|
||||||
|
self.count
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,6 +71,8 @@ where
|
|||||||
/// Last known position of the cursor. Used to find the new area when the viewport is inlined
|
/// Last known position of the cursor. Used to find the new area when the viewport is inlined
|
||||||
/// and the terminal resized.
|
/// and the terminal resized.
|
||||||
last_known_cursor_pos: (u16, u16),
|
last_known_cursor_pos: (u16, u16),
|
||||||
|
/// Number of frames rendered up until current time.
|
||||||
|
frame_count: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Options to pass to [`Terminal::with_options`]
|
/// Options to pass to [`Terminal::with_options`]
|
||||||
@ -149,15 +151,18 @@ where
|
|||||||
viewport_area,
|
viewport_area,
|
||||||
last_known_size: size,
|
last_known_size: size,
|
||||||
last_known_cursor_pos: cursor_pos,
|
last_known_cursor_pos: cursor_pos,
|
||||||
|
frame_count: 0,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get a Frame object which provides a consistent view into the terminal state for rendering.
|
/// Get a Frame object which provides a consistent view into the terminal state for rendering.
|
||||||
pub fn get_frame(&mut self) -> Frame {
|
pub fn get_frame(&mut self) -> Frame {
|
||||||
|
let count = self.frame_count;
|
||||||
Frame {
|
Frame {
|
||||||
cursor_position: None,
|
cursor_position: None,
|
||||||
viewport_area: self.viewport_area,
|
viewport_area: self.viewport_area,
|
||||||
buffer: self.current_buffer_mut(),
|
buffer: self.current_buffer_mut(),
|
||||||
|
count,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,10 +284,16 @@ where
|
|||||||
// Flush
|
// Flush
|
||||||
self.backend.flush()?;
|
self.backend.flush()?;
|
||||||
|
|
||||||
Ok(CompletedFrame {
|
let completed_frame = CompletedFrame {
|
||||||
buffer: &self.buffers[1 - self.current],
|
buffer: &self.buffers[1 - self.current],
|
||||||
area: self.last_known_size,
|
area: self.last_known_size,
|
||||||
})
|
count: self.frame_count,
|
||||||
|
};
|
||||||
|
|
||||||
|
// increment frame count before returning from draw
|
||||||
|
self.frame_count = self.frame_count.wrapping_add(1);
|
||||||
|
|
||||||
|
Ok(completed_frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hides the cursor.
|
/// Hides the cursor.
|
||||||
|
@ -50,6 +50,31 @@ fn terminal_draw_returns_the_completed_frame() -> Result<(), Box<dyn Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn terminal_draw_increments_frame_count() -> Result<(), Box<dyn Error>> {
|
||||||
|
let backend = TestBackend::new(10, 10);
|
||||||
|
let mut terminal = Terminal::new(backend)?;
|
||||||
|
let frame = terminal.draw(|f| {
|
||||||
|
assert_eq!(f.count(), 0);
|
||||||
|
let paragraph = Paragraph::new("Test");
|
||||||
|
f.render_widget(paragraph, f.size());
|
||||||
|
})?;
|
||||||
|
assert_eq!(frame.count, 0);
|
||||||
|
let frame = terminal.draw(|f| {
|
||||||
|
assert_eq!(f.count(), 1);
|
||||||
|
let paragraph = Paragraph::new("test");
|
||||||
|
f.render_widget(paragraph, f.size());
|
||||||
|
})?;
|
||||||
|
assert_eq!(frame.count, 1);
|
||||||
|
let frame = terminal.draw(|f| {
|
||||||
|
assert_eq!(f.count(), 2);
|
||||||
|
let paragraph = Paragraph::new("test");
|
||||||
|
f.render_widget(paragraph, f.size());
|
||||||
|
})?;
|
||||||
|
assert_eq!(frame.count, 2);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn terminal_insert_before_moves_viewport() -> Result<(), Box<dyn Error>> {
|
fn terminal_insert_before_moves_viewport() -> Result<(), Box<dyn Error>> {
|
||||||
// When we have a terminal with 5 lines, and a single line viewport, if we insert a
|
// When we have a terminal with 5 lines, and a single line viewport, if we insert a
|
||||||
|
Loading…
x
Reference in New Issue
Block a user