From 4286d7055df278b9e87305142ae6c5cadf44f3c2 Mon Sep 17 00:00:00 2001 From: Rico Riedel Date: Sat, 6 Aug 2022 18:43:47 +0200 Subject: [PATCH] Add comments --- src/convert/char.rs | 7 +++++++ src/convert/color.rs | 3 +++ src/convert/mod.rs | 6 ++++++ src/error.rs | 1 + src/main.rs | 21 +++++++++++++++++++-- src/pattern/circle.rs | 2 ++ src/pattern/line.rs | 2 ++ src/pattern/mod.rs | 19 +++++++++++++++++++ src/pattern/rhombus.rs | 2 ++ src/pattern/wheel.rs | 2 ++ src/printer.rs | 14 ++++++++++++++ src/renderer.rs | 7 +++++++ src/term.rs | 6 ++++++ src/timer.rs | 9 +++++++++ src/transform/invert.rs | 4 ++++ src/transform/mod.rs | 2 ++ src/transform/segment.rs | 2 ++ src/transform/shift.rs | 2 ++ src/transform/slice.rs | 2 ++ src/transform/swap.rs | 4 ++++ src/vec.rs | 9 +++++++++ 21 files changed, 124 insertions(+), 2 deletions(-) diff --git a/src/convert/char.rs b/src/convert/char.rs index 3747dce..61d7291 100644 --- a/src/convert/char.rs +++ b/src/convert/char.rs @@ -1,20 +1,27 @@ +/// A sample for a terminal cell. #[derive(Copy, Clone, PartialEq, Debug)] pub enum CharSample { + /// Keep the char. Keep, + /// Override the char. Draw(char), + /// Clear the char. Clear, } +/// A trait to convert a sample to a [CharSample]. #[cfg_attr(test, mockall::automock)] pub trait CharConverter { fn convert(&self, level: f32) -> CharSample; } +/// The implementation of [CharConverter]. pub struct CharConverterImpl { chars: Vec, } impl CharConverterImpl { + /// The chars used for mapping. pub fn new(chars: String) -> Self { let chars = chars.chars().collect(); diff --git a/src/convert/color.rs b/src/convert/color.rs index 09a1d66..b0c9545 100644 --- a/src/convert/color.rs +++ b/src/convert/color.rs @@ -1,15 +1,18 @@ use crossterm::style::Color; +/// A trait to convert a sample to a [Color]. #[cfg_attr(test, mockall::automock)] pub trait ColorConverter { fn convert(&self, level: f32) -> Color; } +/// The implementation of [ColorConverter]. pub struct ColorConverterImpl { colors: Vec, } impl ColorConverterImpl { + /// The colors used for mapping. pub fn new(colors: Vec) -> Self { Self { colors } } diff --git a/src/convert/mod.rs b/src/convert/mod.rs index a6fed3c..0476c36 100644 --- a/src/convert/mod.rs +++ b/src/convert/mod.rs @@ -1,3 +1,5 @@ +//! Contains structs for converting samples to concrete types. + mod char; mod color; @@ -6,12 +8,16 @@ pub use crate::convert::color::*; use crossterm::style::Color; +/// A trait to convert samples to concrete types. #[cfg_attr(test, mockall::automock)] pub trait Converter { + /// Converts a sample to a [CharSample]. fn char(&self, level: f32) -> CharSample; + /// Converts a sample to a [Color]. fn color(&self, level: f32) -> Color; } +/// The implementation of [Converter]. #[derive(derive_more::Constructor)] pub struct ConverterImpl { char: T1, diff --git a/src/error.rs b/src/error.rs index 8dd7f7b..f4048b9 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,5 +1,6 @@ use std::fmt::{Debug, Formatter}; +/// The error type. pub struct Error(String); impl Debug for Error { diff --git a/src/main.rs b/src/main.rs index 68716f7..28b822c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use rand::prelude::*; use std::io::stdout; use std::time::Duration; +/// The command line arguments. #[derive(Parser, Default)] #[clap( author = env!("CARGO_PKG_AUTHORS"), @@ -34,8 +35,13 @@ use std::time::Duration; about = env!("CARGO_PKG_DESCRIPTION"), )] struct Args { - /// Set the animation duration [milliseconds] - #[clap(long, default_value_t = 2000, value_parser = value_parser!(u64).range(0..=60_000))] + /// Set the duration as milliseconds + #[clap( + long, + default_value_t = 2000, + value_parser = value_parser!(u64).range(0..=60_000), + help = "Set the animation duration [milliseconds]" + )] duration: u64, /// Set the frames per second #[clap(long, default_value_t = 60, value_parser = value_parser!(u64).range(1..=480))] @@ -78,6 +84,7 @@ struct Args { color_slices: Option, } +/// All color pallets. #[derive(ValueEnum, Copy, Clone)] enum PalletEnum { Red, @@ -106,6 +113,7 @@ enum PalletEnum { Gray, } +/// All possible [Pattern]s. #[derive(ValueEnum, Copy, Clone, PartialEq, Debug)] enum PatternEnum { Circle, @@ -114,6 +122,7 @@ enum PatternEnum { Wheel, } +/// A configuration for a composed [Pattern]. #[derive(derive_more::Constructor)] struct PatternConfig { pattern: PatternEnum, @@ -125,6 +134,7 @@ struct PatternConfig { } impl Args { + /// Returns the configuration for the char [Pattern]. fn char_config(&self, rng: &mut impl Rng) -> PatternConfig { PatternConfig::new( choose(self.char_pattern, rng), @@ -136,6 +146,7 @@ impl Args { ) } + /// Returns the configuration for the color [Pattern]. fn color_config(&self, rng: &mut impl Rng) -> PatternConfig { PatternConfig::new( choose(self.color_pattern, rng), @@ -147,6 +158,7 @@ impl Args { ) } + /// Returns the colors for the [ColorConverter]. fn pallet(&self, rng: &mut impl Rng) -> Vec { match choose(self.colors, rng) { PalletEnum::Red => vec![DarkRed, Red, White], @@ -183,16 +195,19 @@ impl Args { } } + /// Returns the duration for the [Timer]. fn duration(&self) -> Duration { Duration::from_millis(self.duration) } + /// Returns the delay for the [Timer]. fn delay(&self) -> Duration { Duration::from_nanos(1_000_000_000 / self.fps) } } impl PatternConfig { + /// Creates a new base [Pattern]. fn create_base(&self) -> Box { match self.pattern { PatternEnum::Circle => Box::new(CircleFactory::new()), @@ -202,6 +217,7 @@ impl PatternConfig { } } + /// Creates a new composed [Pattern]. fn create(&self) -> Box { let mut pattern = self.create_base(); @@ -224,6 +240,7 @@ impl PatternConfig { } } +/// Returns the value of the [Option] or a random enum variant. fn choose(opt: Option, rng: &mut TRand) -> TValue { match opt { Some(value) => value.clone(), diff --git a/src/pattern/circle.rs b/src/pattern/circle.rs index 8726598..17e9a68 100644 --- a/src/pattern/circle.rs +++ b/src/pattern/circle.rs @@ -1,8 +1,10 @@ use crate::pattern::*; use crate::Vector; +/// A factory for [Circle]. #[derive(derive_more::Constructor)] pub struct CircleFactory; +/// A circular [Pattern]. pub struct Circle { center: Vector, radius: f32, diff --git a/src/pattern/line.rs b/src/pattern/line.rs index f20cf3d..2c50006 100644 --- a/src/pattern/line.rs +++ b/src/pattern/line.rs @@ -1,8 +1,10 @@ use crate::pattern::*; use crate::Vector; +/// A factory for [Line]. #[derive(derive_more::Constructor)] pub struct LineFactory; +/// A horizontal line [Pattern]. pub struct Line { width: f32, } diff --git a/src/pattern/mod.rs b/src/pattern/mod.rs index 6ea9489..1e95660 100644 --- a/src/pattern/mod.rs +++ b/src/pattern/mod.rs @@ -1,3 +1,5 @@ +//! Contains all pattern traits and base patterns. + mod circle; mod line; mod rhombus; @@ -10,42 +12,59 @@ pub use wheel::*; use crate::Vector; +/// A configuration for a [Pattern]. #[derive(Copy, Clone, Default, PartialEq, Debug)] pub struct Config { + /// The size of the terminal. pub size: Vector, + /// The current state of the animation. pub step: f32, } +/// A factory to create a [Pattern]. #[cfg_attr(test, mockall::automock)] pub trait PatternFactory { + /// Creates a new [Pattern] with the given configuration. fn create(&self, config: &Config) -> Box; } +/// A pattern for an animation. #[cfg_attr(test, mockall::automock)] pub trait Pattern { + /// Returns the level for a given coordinate. + /// If it is a base pattern, the start position of the + /// animation should by zero and the end position should be one. fn sample(&self, pos: Vector) -> f32; } +/// A factor for a [Sampler]. #[cfg_attr(test, mockall::automock(type Sampler = MockSampler;))] pub trait SamplerFactory { + /// The type of the [Sampler]. type Sampler: Sampler; + /// Creates a new [Sampler]. fn create(&self, config: &Config) -> Self::Sampler; } +/// A sampler for multiple values. #[cfg_attr(test, mockall::automock)] pub trait Sampler { + /// Returns the char level for a given position. fn char(&self, pos: Vector) -> f32; + /// Returns the color level for a given position. fn color(&self, pos: Vector) -> f32; } +/// The implementation of [SamplerFactory]. #[derive(derive_more::Constructor)] pub struct SamplerFactoryImpl { char: Box, color: Box, } +/// The implementation of [Sampler]. #[derive(derive_more::Constructor)] pub struct SamplerImpl { char: Box, diff --git a/src/pattern/rhombus.rs b/src/pattern/rhombus.rs index aa7c071..e727622 100644 --- a/src/pattern/rhombus.rs +++ b/src/pattern/rhombus.rs @@ -1,8 +1,10 @@ use crate::pattern::*; use crate::Vector; +/// A factory for [Rhombus]. #[derive(derive_more::Constructor)] pub struct RhombusFactory; +/// A rhombus shaped [Pattern]. pub struct Rhombus { center: Vector, distance: f32, diff --git a/src/pattern/wheel.rs b/src/pattern/wheel.rs index b833a79..c0504a6 100644 --- a/src/pattern/wheel.rs +++ b/src/pattern/wheel.rs @@ -2,8 +2,10 @@ use crate::pattern::*; use crate::Vector; use std::f32::consts::PI; +/// A factory for [Wheel]. #[derive(derive_more::Constructor)] pub struct WheelFactory; +/// A fortune wheel [Pattern]. pub struct Wheel { center: Vector, } diff --git a/src/printer.rs b/src/printer.rs index 4c621ef..8122e23 100644 --- a/src/printer.rs +++ b/src/printer.rs @@ -4,18 +4,32 @@ use crossterm::cursor::*; use crossterm::style::*; use crossterm::terminal::*; +/// A trait for performance optimized terminal output. +/// +/// All commands are queue and have to be executed using [Printer::flush]. #[cfg_attr(test, mockall::automock)] pub trait Printer { + /// Shows the cursor if it isn't visible. fn show_cursor(&mut self) -> Result<(), Error>; + /// Hides the cursor if it is visible. fn hide_cursor(&mut self) -> Result<(), Error>; + /// Prints a character. + /// # Panics + /// Panics if the character is a special character like `ESC`, `DEL` or `NEWLINE`. fn print(&mut self, char: char) -> Result<(), Error>; + /// Moves the cursor to the specified position if it isn't there already. fn move_to(&mut self, x: u16, y: u16) -> Result<(), Error>; + /// Returns the size of the terminal. fn size(&self) -> Result<(u16, u16), Error>; + /// Sets the foreground color of the terminal. fn set_foreground(&mut self, color: Color) -> Result<(), Error>; + /// Clears the terminal content. fn clear(&mut self) -> Result<(), Error>; + /// Flushes all queue commands. fn flush(&mut self) -> Result<(), Error>; } +/// The implementation of [Printer]. pub struct PrinterImpl { term: T, position: (u16, u16), diff --git a/src/renderer.rs b/src/renderer.rs index fde039c..50bfcae 100644 --- a/src/renderer.rs +++ b/src/renderer.rs @@ -4,13 +4,20 @@ use crate::Error; use crate::Printer; use crate::Vector; +/// A renderer for an animation. #[cfg_attr(test, mockall::automock)] pub trait Renderer { + /// Prepares the terminal for the animation. + /// Call once before rendering frames. fn begin(&mut self) -> Result<(), Error>; + /// Renders the current frame and flushes. fn render(&mut self, step: f32) -> Result<(), Error>; + /// Cleans up and resets the terminal. + /// Call once after rendering frames. fn end(&mut self) -> Result<(), Error>; } +/// The implementation of [Renderer]. #[derive(derive_more::Constructor)] pub struct RendererImpl { sampler: T1, diff --git a/src/term.rs b/src/term.rs index eddc9a5..6ad54f9 100644 --- a/src/term.rs +++ b/src/term.rs @@ -2,14 +2,20 @@ use crate::Error; use crossterm::{Command, QueueableCommand}; use std::io::Write; +/// A stub for OS calls and crossterm functions. #[cfg_attr(test, mockall::automock)] pub trait Terminal { + /// Queues a command for execution. fn queue(&mut self, cmd: T) -> Result<(), Error>; + /// Flushes all queued commands. fn flush(&mut self) -> Result<(), Error>; + /// Returns the current size of the terminal. fn size(&self) -> Result<(u16, u16), Error>; + /// Returns the current cursor position. fn position(&self) -> Result<(u16, u16), Error>; } +/// The implementation of [Terminal]. pub struct TerminalImpl { out: T, } diff --git a/src/timer.rs b/src/timer.rs index 23df202..facd600 100644 --- a/src/timer.rs +++ b/src/timer.rs @@ -3,12 +3,17 @@ use crate::Renderer; use std::thread; use std::time::{Duration, Instant}; +/// A stub for the system clock. #[cfg_attr(test, mockall::automock)] pub trait Clock { + /// Returns the current time. fn now(&self) -> Instant; + + /// Sleep for the given duration. fn sleep(&self, duration: Duration); } +/// The implementation of [Clock]. #[derive(derive_more::Constructor)] pub struct ClockImpl; @@ -22,6 +27,7 @@ impl Clock for ClockImpl { } } +/// A timer for rendering. #[derive(derive_more::Constructor)] pub struct Timer { clock: T, @@ -30,6 +36,7 @@ pub struct Timer { } impl Timer { + /// Runs the animation main loop. pub fn run(&self, mut renderer: impl Renderer) -> Result<(), Error> { let start = self.clock.now(); let mut now = start; @@ -45,6 +52,8 @@ impl Timer { renderer.end() } + /// Sleeps until the next frame starts. + /// Returns the current time. fn delay(&self, begin: Instant) -> Instant { let end = self.clock.now(); diff --git a/src/transform/invert.rs b/src/transform/invert.rs index 01cd310..065fea9 100644 --- a/src/transform/invert.rs +++ b/src/transform/invert.rs @@ -1,11 +1,15 @@ use crate::pattern::*; use crate::Vector; +/// A factory for [Invert]. +/// +/// Inverts the time of the [Config] for the child [Pattern]. #[derive(derive_more::Constructor)] pub struct InvertFactory { child: Box, } +/// Inverts the level of the [Pattern]. #[derive(derive_more::Constructor)] pub struct Invert { child: Box, diff --git a/src/transform/mod.rs b/src/transform/mod.rs index 204b941..1a1bad5 100644 --- a/src/transform/mod.rs +++ b/src/transform/mod.rs @@ -1,3 +1,5 @@ +//! Contains transformations to apply on top of patterns. + mod invert; mod segment; mod shift; diff --git a/src/transform/segment.rs b/src/transform/segment.rs index 3bfca2a..4342b48 100644 --- a/src/transform/segment.rs +++ b/src/transform/segment.rs @@ -1,12 +1,14 @@ use crate::pattern::*; use crate::Vector; +/// A factory for [Segments]. #[derive(derive_more::Constructor)] pub struct SegmentsFactory { child: Box, segments: f32, } +/// Converts a pattern to `n` segments each starting with zero and ending with one. #[derive(derive_more::Constructor)] pub struct Segments { child: Box, diff --git a/src/transform/shift.rs b/src/transform/shift.rs index 12b0d64..699ec66 100644 --- a/src/transform/shift.rs +++ b/src/transform/shift.rs @@ -1,11 +1,13 @@ use crate::pattern::*; use crate::Vector; +/// A factory for [Shift]. #[derive(derive_more::Constructor)] pub struct ShiftFactory { child: Box, } +/// Offsets the [Pattern] out of screen, then moves it inside and finally outside the visible area. #[derive(derive_more::Constructor)] pub struct Shift { child: Box, diff --git a/src/transform/slice.rs b/src/transform/slice.rs index a41b096..2bef835 100644 --- a/src/transform/slice.rs +++ b/src/transform/slice.rs @@ -1,12 +1,14 @@ use crate::pattern::*; use crate::Vector; +/// A factory for [Slice]. pub struct SliceFactory { child: Box, width: f32, rest: f32, } +/// Reduces the width of the child [Pattern] to one over `n`. #[derive(derive_more::Constructor)] pub struct Slice { child: Box, diff --git a/src/transform/swap.rs b/src/transform/swap.rs index 04b49f4..a504430 100644 --- a/src/transform/swap.rs +++ b/src/transform/swap.rs @@ -1,11 +1,15 @@ use crate::pattern::*; use crate::Vector; +/// A factory for [Swap]. +/// +/// Swaps the x-axis and y-axis of terminal size for the contained [Pattern]. #[derive(derive_more::Constructor)] pub struct SwapFactory { child: Box, } +/// Swaps the x-axis and y-axis. #[derive(derive_more::Constructor)] pub struct Swap { child: Box, diff --git a/src/vec.rs b/src/vec.rs index a1ff420..dc0d41c 100644 --- a/src/vec.rs +++ b/src/vec.rs @@ -1,3 +1,4 @@ +/// A vector with a x-axis and y-axis. #[derive(Copy, Clone, PartialEq, Debug, Default, derive_more::Sub)] pub struct Vector { pub x: f32, @@ -5,34 +6,42 @@ pub struct Vector { } impl Vector { + /// Creates a new vector. pub fn new(x: f32, y: f32) -> Self { Self { x, y } } + /// Creates a new vector from terminal coordinates. pub fn from_terminal(x: u16, y: u16) -> Self { Vector::new(x as f32, y as f32 * 2.0) } + /// Returns the length. pub fn len(&self) -> f32 { (self.x * self.x + self.y * self.y).sqrt() } + /// Returns a vector with absolute values. pub fn abs(&self) -> Vector { Self::new(self.x.abs(), self.y.abs()) } + /// Returns the sum of all axis. pub fn sum(&self) -> f32 { self.x + self.y } + /// Returns the center. pub fn center(&self) -> Vector { Self::new(self.x / 2.0, self.y / 2.0) } + /// Returns the angle. pub fn angle(&self) -> f32 { self.y.atan2(self.x) } + /// Returns a vector with x and y swapped. pub fn swap(&self) -> Vector { Self::new(self.y, self.x) }