116 lines
2.8 KiB
Rust
116 lines
2.8 KiB
Rust
use std::time::Duration;
|
|
use std::ops::{Index, IndexMut};
|
|
|
|
use serde::{Serialize, Deserialize};
|
|
|
|
/// 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 * 4.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(Serialize, Deserialize, 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, col): (usize, usize)) -> Option<&T> {
|
|
if row < self.rows && col < self.cols {
|
|
Some(&self[(row, col)])
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
|
|
/// Returns the tile if any, none otherwise.
|
|
pub fn get_isize(&self, row: isize, col: isize) -> Option<&T> {
|
|
if row >= 0 && col >= 0 && (row as usize) < self.rows && (col as usize) < self.cols {
|
|
Some(&self[(row as usize, col as usize)])
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
/// Returns a mutable reference to the tile if any.
|
|
pub fn get_mut(&mut self, (row, col): (usize, 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]
|
|
}
|
|
}
|