use crate::{section::general::GameMode, util::Pos};
use super::{
curve::{BorrowedCurve, Curve, CurveBuffers},
path_type::PathType,
};
#[derive(Clone, Debug)]
pub struct SliderPath {
mode: GameMode,
control_points: Vec<PathControlPoint>,
expected_dist: Option<f64>,
curve: Option<Curve>,
}
impl SliderPath {
pub const fn new(
mode: GameMode,
control_points: Vec<PathControlPoint>,
expected_dist: Option<f64>,
) -> Self {
Self {
mode,
control_points,
expected_dist,
curve: None,
}
}
pub fn control_points(&self) -> &[PathControlPoint] {
&self.control_points
}
pub const fn expected_dist(&self) -> Option<f64> {
self.expected_dist
}
pub fn curve(&mut self) -> &Curve {
if let Some(ref curve) = self.curve {
curve
} else {
let curve = self.calculate_curve();
self.curve.insert(curve)
}
}
pub fn curve_with_bufs(&mut self, bufs: &mut CurveBuffers) -> &Curve {
if let Some(ref curve) = self.curve {
curve
} else {
let curve = self.calculate_curve_with_bufs(bufs);
self.curve.insert(curve)
}
}
pub fn borrowed_curve<'a, 'b: 'a>(&'a self, bufs: &'b mut CurveBuffers) -> BorrowedCurve<'a> {
if let Some(ref curve) = self.curve {
curve.as_borrowed_curve()
} else {
BorrowedCurve::new(self.mode, &self.control_points, self.expected_dist, bufs)
}
}
pub fn control_points_mut(&mut self) -> &mut Vec<PathControlPoint> {
self.clear_curve();
&mut self.control_points
}
pub fn expected_dist_mut(&mut self) -> &mut Option<f64> {
self.clear_curve();
&mut self.expected_dist
}
pub fn clear_curve(&mut self) {
self.curve = None;
}
fn calculate_curve(&self) -> Curve {
self.calculate_curve_with_bufs(&mut CurveBuffers::default())
}
fn calculate_curve_with_bufs(&self, bufs: &mut CurveBuffers) -> Curve {
Curve::new(self.mode, &self.control_points, self.expected_dist, bufs)
}
}
impl PartialEq for SliderPath {
fn eq(&self, other: &Self) -> bool {
self.control_points == other.control_points
}
}
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct PathControlPoint {
pub pos: Pos,
pub path_type: Option<PathType>,
}
impl PathControlPoint {
pub const fn new(pos: Pos) -> Self {
Self {
pos,
path_type: None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn borrowed_curve() {
let mut bufs = CurveBuffers::default();
let mut path = SliderPath::new(GameMode::Osu, Vec::new(), None);
let borrowed_curve = path.borrowed_curve(&mut bufs);
let _ = borrowed_curve.dist();
let _ = path.curve_with_bufs(&mut bufs);
let borrowed_curve = path.borrowed_curve(&mut bufs);
let _ = borrowed_curve.dist();
}
}