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