free-rusty-maker/src/engine/math/mod.rs

104 lines
2.5 KiB
Rust

use std::ops::{Index, IndexMut};
use std::time::Duration;
/// Clamp a number between two boundaries.
pub fn clamp(number: f32, min: f32, max: f32) -> f32 {
if number < min {
min
} else if number > max {
max
} else {
number
}
}
/// Converts a duration into an animation frame number.
pub fn duration_as_frame(duration: &Duration, total: usize) -> i32 {
let secs = duration_as_f32(duration);
(secs * 10.0) as i32 % total as i32
}
/// Converts a duration into its number of seconds.
pub fn duration_as_f32(duration: &Duration) -> f32 {
duration.as_secs() as f32 + duration.subsec_nanos() as f32 / 1_000_000_000.0
}
/// A generic matrix type, useful for levels.
#[derive(Clone)]
pub struct Matrix<T> {
/// The number of rows of the matrix.
rows: usize,
/// The number of cols of the matrix.
cols: usize,
/// The contained data in the matrix.
data: Vec<T>,
}
impl<T> Matrix<T>
where
T: Clone,
{
/// Creates a matrix from an element and duplicates it.
pub fn from_size(rows: usize, cols: usize, element: T) -> Matrix<T> {
Matrix {
rows,
cols,
data: vec![element; rows * cols],
}
}
}
impl<T> Matrix<T> {
/// Converts an a pair corresponding to the row and columns into an integer.
pub fn to_usize(&self, (row, col): (usize, usize)) -> usize {
self.rows * col + row
}
/// Returns the number of rows.
pub fn rows(&self) -> usize {
self.rows
}
/// Returns the number of columns.
pub fn cols(&self) -> usize {
self.cols
}
/// Returns the tile if any, none otherwise.
pub fn get(&self, row: usize, col: usize) -> Option<&T> {
if row < self.rows && col < self.cols {
Some(&self[(row, col)])
} else {
None
}
}
/// Returns a mutable reference to the tile if any.
pub fn get_mut(&mut self, row: usize, col: usize) -> Option<&mut T> {
if row < self.rows && col < self.cols {
Some(&mut self[(row, col)])
} else {
None
}
}
}
impl<T> Index<(usize, usize)> for Matrix<T> {
type Output = T;
fn index(&self, index: (usize, usize)) -> &T {
let index = self.to_usize(index);
&self.data[index]
}
}
impl<T> IndexMut<(usize, usize)> for Matrix<T> {
fn index_mut(&mut self, index: (usize, usize)) -> &mut T {
let index = self.to_usize(index);
&mut self.data[index]
}
}