use core::ops::Div;
use rinia::{
Scalard, Scalarf,
numeric::{IsFinite, LossyCastFrom, One, Zero},
};
use crate::{Duration, Error, FrameRate, common};
impl<T> FrameRate<T> {
#[inline]
pub const fn new(fps: T) -> Self {
Self(fps)
}
#[inline]
pub fn try_from_fps(fps: T) -> Result<Self, Error>
where
T: Copy + IsFinite + PartialOrd + Zero,
{
if !fps.is_finite() {
return Err(Error::InvalidValue(
"FrameRate cannot be created from NaN or infinite values",
));
}
if fps <= T::ZERO {
return Err(Error::InvalidValue(
"FrameRate cannot be created from non-positive values",
));
}
Ok(Self(fps))
}
#[inline]
pub fn from_fps(fps: T) -> Self
where
T: Copy + IsFinite + PartialOrd + Zero,
{
Self::try_from_fps(fps).unwrap_or_else(|err| panic!("{err}"))
}
#[inline]
pub fn fps(&self) -> T
where
T: Copy,
{
self.0
}
#[inline]
pub fn into_fps(self) -> T {
self.0
}
#[inline]
pub fn seconds_per_frame(&self) -> T
where
T: Copy + One + Div<Output = T>,
{
T::ONE / self.0
}
#[inline]
pub fn into_seconds_per_frame(self) -> T
where
T: One + Div<Output = T>,
{
T::ONE / self.0
}
#[inline]
pub fn duration(&self) -> Duration<T>
where
T: Copy + One + Div<Output = T>,
{
Duration::new(self.seconds_per_frame())
}
#[inline]
pub fn into_duration(self) -> Duration<T>
where
T: One + Div<Output = T>,
{
Duration::new(self.into_seconds_per_frame())
}
#[inline]
pub fn ratio(&self, other: FrameRate<T>) -> T
where
T: Copy + Div<Output = T>,
{
*self / other
}
}
impl<T> Default for FrameRate<T>
where
T: LossyCastFrom<u16>,
{
#[inline]
fn default() -> Self {
Self::fps_60()
}
}
crate::frame_rate::impl_rate_fps!(24, 25, 30, 48, 50, 60, 120, 144, 240);
common::impl_approx_forwarding!(FrameRate<T>, 0);
common::impl_bytemuck_basic!(
[T],
FrameRate<T>,
item: T,
);
impl<T> From<T> for FrameRate<T> {
#[inline]
fn from(value: T) -> Self {
Self::new(value)
}
}
impl From<FrameRate<Scalarf>> for Scalarf {
#[inline]
fn from(frame_rate: FrameRate<Scalarf>) -> Self {
frame_rate.fps()
}
}
impl From<FrameRate<Scalard>> for Scalard {
#[inline]
fn from(frame_rate: FrameRate<Scalard>) -> Self {
frame_rate.fps()
}
}