mirror of
https://github.com/ricoriedel/wipe.git
synced 2024-11-16 04:56:43 +00:00
Add more comments
This commit is contained in:
parent
b6a2ae85f4
commit
35b555a04b
@ -4,6 +4,7 @@ use crate::vec::Vector;
|
||||
const THICKNESS: f32 = 0.2;
|
||||
const FINAL_RADIUS: f32 = 1.0 + THICKNESS * 2.0;
|
||||
|
||||
/// An animation of an expanding circle.
|
||||
pub struct CircleAnimation {
|
||||
center: Vector,
|
||||
thickness: f32,
|
||||
|
@ -7,7 +7,17 @@ use crate::vec::Vector;
|
||||
#[cfg(test)]
|
||||
use mockall::automock;
|
||||
|
||||
/// A sampler for an animation.
|
||||
#[cfg_attr(test, automock)]
|
||||
pub trait Animation {
|
||||
/// Returns the level (of brightness) for the
|
||||
/// given step of the animation an position on screen.
|
||||
/// # Arguments
|
||||
/// * `step`: `0 <= step` and `step <= 1`
|
||||
///
|
||||
/// # Return values
|
||||
/// * `1 < n` => Keep current character
|
||||
/// * `0 <= n` and `n < 1` => Draw some character
|
||||
/// * `n < 0` => Clear character
|
||||
fn sample(&self, step: f32, pos: Vector) -> f32;
|
||||
}
|
@ -4,6 +4,7 @@ use crate::vec::Vector;
|
||||
const THICKNESS: f32 = 0.2;
|
||||
const FINAL_DISTANCE: f32 = 1.0 + THICKNESS * 2.0;
|
||||
|
||||
/// An animation of an expanding rhombus.
|
||||
pub struct RhombusAnimation {
|
||||
center: Vector,
|
||||
thickness: f32,
|
||||
|
@ -1,10 +1,13 @@
|
||||
use rand::prelude::IteratorRandom;
|
||||
use rand::Rng;
|
||||
|
||||
/// A trait to get all values of an enum.
|
||||
pub trait Collection {
|
||||
/// Returns a list of all enum values.
|
||||
fn all() -> Vec<Self> where Self: Sized;
|
||||
}
|
||||
|
||||
/// Choose a enum from a list of options.
|
||||
pub struct Chooser<TRng> {
|
||||
rng: TRng
|
||||
}
|
||||
@ -14,6 +17,8 @@ impl<TRng: Rng> Chooser<TRng> {
|
||||
Self { rng }
|
||||
}
|
||||
|
||||
/// Choose an enum item from the provided [Vec].
|
||||
/// If none are provided, a random one of all enum values is chosen.
|
||||
pub fn choose<TValue: Collection>(&mut self, selection: Vec<TValue>) -> TValue {
|
||||
let options = if selection.is_empty() {
|
||||
TValue::all()
|
||||
|
@ -12,6 +12,7 @@ pub trait ColorSampler {
|
||||
fn sample(&self, fill: f32) -> Color;
|
||||
}
|
||||
|
||||
/// A simple color sampler which interpolates the color from a [Vec].
|
||||
pub struct SimpleColorSampler {
|
||||
values: Vec<Color>
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ use crate::vec::Vector;
|
||||
|
||||
const INTERVAL: f32 = 4.0;
|
||||
|
||||
/// Fill based on rings of a circle.
|
||||
pub struct CircleFillMode {
|
||||
center: Vector,
|
||||
interval: f32
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::fill::FillMode;
|
||||
use crate::vec::Vector;
|
||||
|
||||
/// Fill based on the level of brightness.
|
||||
pub struct LevelFillMode;
|
||||
|
||||
impl LevelFillMode {
|
||||
|
@ -11,5 +11,7 @@ use mockall::automock;
|
||||
#[cfg_attr(test, automock)]
|
||||
pub trait FillMode {
|
||||
/// Gets the color for this character.
|
||||
/// # Arguments
|
||||
/// * `step`: `0 <= step` and `step <= 1`
|
||||
fn sample(&self, level: f32, pos: Vector) -> f32;
|
||||
}
|
@ -3,6 +3,7 @@ use crate::vec::Vector;
|
||||
|
||||
const INTERVAL: f32 = 4.0;
|
||||
|
||||
/// Fill based on diagonal stripes.
|
||||
pub struct StripesFillMode {
|
||||
interval: f32
|
||||
}
|
||||
|
@ -35,6 +35,7 @@ mod timer;
|
||||
mod runner;
|
||||
mod choose;
|
||||
|
||||
/// Defines an enum and implements the [Collection] trait.
|
||||
macro_rules! options {
|
||||
($name:ident { $($opt:ident,)* }) => {
|
||||
#[derive(Copy, Clone, ArgEnum)]
|
||||
@ -74,6 +75,7 @@ options!(FillModeType {
|
||||
|
||||
const MAX_FPS: u64 = 480;
|
||||
|
||||
/// The program arguments.
|
||||
#[derive(Parser)]
|
||||
#[clap(author = env ! ("CARGO_PKG_AUTHORS"), version = env ! ("CARGO_PKG_VERSION"), about = env ! ("CARGO_PKG_DESCRIPTION"))]
|
||||
struct Args {
|
||||
@ -119,6 +121,7 @@ fn main() -> Result<(), Error> {
|
||||
runner.run()
|
||||
}
|
||||
|
||||
/// Validates the chars argument.
|
||||
fn validate_chars(text: &str) -> Result<String, Error> {
|
||||
if text.is_empty() {
|
||||
Err(anyhow!("can't be empty."))
|
||||
@ -127,6 +130,7 @@ fn validate_chars(text: &str) -> Result<String, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates the fps argument.
|
||||
fn validate_fps(text: &str) -> Result<u64, Error> {
|
||||
let value = text.parse()?;
|
||||
|
||||
@ -139,6 +143,7 @@ fn validate_fps(text: &str) -> Result<u64, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Validates the duration argument.
|
||||
fn validate_duration(text: &str) -> Result<u64, Error> {
|
||||
let value = text.parse()?;
|
||||
|
||||
@ -149,12 +154,14 @@ fn validate_duration(text: &str) -> Result<u64, Error> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the size to use based on the terminal size and width and height arguments.
|
||||
fn size(terminal: (u16, u16), width: Option<usize>, height: Option<usize>) -> (usize, usize) {
|
||||
let width = width.unwrap_or(terminal.0 as usize);
|
||||
let height = height.unwrap_or(terminal.1 as usize);
|
||||
(width, height)
|
||||
}
|
||||
|
||||
/// Calculates the delay between frames based on the fps.
|
||||
fn delay_of_fps(fps: u64) -> Duration {
|
||||
Duration::from_nanos(1_000_000_000 / fps)
|
||||
}
|
||||
|
@ -6,12 +6,17 @@ use crate::Vector;
|
||||
#[cfg(test)]
|
||||
use mockall::automock;
|
||||
|
||||
/// A trait for anything which performs some rendering.
|
||||
#[cfg_attr(test, automock)]
|
||||
pub trait Renderer {
|
||||
/// Render the frame.
|
||||
fn render(&mut self, step: f32);
|
||||
|
||||
/// Present the finished frame.
|
||||
fn present(&mut self) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
/// Fills its [Surface] with the values received from a [Sampler].
|
||||
pub struct SamplerRenderer<TSurface, TSampler> {
|
||||
surface: TSurface,
|
||||
sampler: TSampler,
|
||||
|
@ -3,6 +3,7 @@ use anyhow::Error;
|
||||
use crate::Renderer;
|
||||
use crate::timer::Timer;
|
||||
|
||||
/// Periodically calls [Renderer::render] and [Renderer::present].
|
||||
pub struct Runner<TTimer, TRenderer> {
|
||||
timer: TTimer,
|
||||
ticks: u128,
|
||||
|
@ -8,17 +8,23 @@ use crate::vec::Vector;
|
||||
#[cfg(test)]
|
||||
use mockall::automock;
|
||||
|
||||
/// The action to perform for the given values.
|
||||
pub enum Sample {
|
||||
Keep,
|
||||
Draw { char: char, color: Color },
|
||||
Clear,
|
||||
}
|
||||
|
||||
/// Provides a [Sample] for some values.
|
||||
#[cfg_attr(test, automock)]
|
||||
pub trait Sampler {
|
||||
/// Get a [Sample] for the step of the animation and position on screen.
|
||||
/// # Arguments
|
||||
/// * `step`: `0 <= step` and `step <= 1`
|
||||
fn sample(&self, step: f32, pos: Vector) -> Sample;
|
||||
}
|
||||
|
||||
/// Links primitive samplers into a full [Sampler].
|
||||
pub struct ComposedSampler {
|
||||
animation: Box<dyn Animation>,
|
||||
fill: Box<dyn FillMode>,
|
||||
|
@ -9,21 +9,28 @@ use crate::array::Array2D;
|
||||
#[cfg(test)]
|
||||
use mockall::automock;
|
||||
|
||||
/// A surface to draw characters on.
|
||||
#[cfg_attr(test, automock)]
|
||||
pub trait Surface {
|
||||
fn width(&self) -> usize;
|
||||
fn height(&self) -> usize;
|
||||
|
||||
/// Overwrite the character on screen with this value.
|
||||
fn draw(&mut self, x: usize, y: usize, char: char, color: Color);
|
||||
|
||||
/// Clear the character on screen.
|
||||
fn clear(&mut self, x: usize, y: usize);
|
||||
|
||||
/// Present the finished frame.
|
||||
fn present(&mut self) -> Result<(), Error>;
|
||||
}
|
||||
|
||||
/// Renders the frames into a [Write] struct.
|
||||
pub struct WriteSurface<T: Write> {
|
||||
out: T,
|
||||
array: Array2D<Cell>,
|
||||
}
|
||||
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
enum Cell {
|
||||
Keep,
|
||||
|
@ -4,13 +4,17 @@ use std::time::{Duration, Instant};
|
||||
#[cfg(test)]
|
||||
use mockall::automock;
|
||||
|
||||
/// Allows for periodic execution of code.
|
||||
#[cfg_attr(test, automock)]
|
||||
pub trait Timer {
|
||||
/// Sleep until the next tick starts.
|
||||
fn sleep(&mut self);
|
||||
|
||||
/// Get the delay between ticks.
|
||||
fn delay(&self) -> Duration;
|
||||
}
|
||||
|
||||
/// A simple [Timer] based on the system clock.
|
||||
pub struct SimpleTimer {
|
||||
delay: Duration,
|
||||
last: Instant
|
||||
|
@ -12,26 +12,32 @@ impl Vector {
|
||||
Self { x, y }
|
||||
}
|
||||
|
||||
/// Returns the halfway point.
|
||||
pub fn center(self) -> Self {
|
||||
Self::new(self.x / 2.0, self.y / 2.0)
|
||||
}
|
||||
|
||||
/// Returns the length.
|
||||
pub fn length(self) -> f32 {
|
||||
(self.x * self.x + self.y * self.y).sqrt()
|
||||
}
|
||||
|
||||
/// Returns the angle.
|
||||
pub fn angle(self) -> f32 {
|
||||
self.x.atan2(self.y)
|
||||
}
|
||||
|
||||
/// Returns the value of the smaller axis.
|
||||
pub fn smaller(self) -> f32 {
|
||||
self.x.min(self.y)
|
||||
}
|
||||
|
||||
/// Converts all axis into positive 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
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user