shapes: use a builder pattern with helps in prelude.

This commit is contained in:
Bill Thiede 2021-07-23 20:56:32 -07:00
parent 958c4c3ee8
commit be2041285c

View File

@ -44,7 +44,7 @@ impl PartialEq for Geometry {
/// many different shapes based on the value of it's geometry field. Users chose the shape by /// many different shapes based on the value of it's geometry field. Users chose the shape by
/// calling the appropriate constructor, i.e. [Shape::sphere]. /// calling the appropriate constructor, i.e. [Shape::sphere].
#[derive(Builder, Debug, Clone, PartialEq)] #[derive(Builder, Debug, Clone, PartialEq)]
#[builder(default)] #[builder(default, pattern = "owned")]
pub struct Shape { pub struct Shape {
transform: Matrix4x4, transform: Matrix4x4,
#[builder(private, default = "self.default_inverse_transform()?")] #[builder(private, default = "self.default_inverse_transform()?")]
@ -53,41 +53,93 @@ pub struct Shape {
geometry: Geometry, geometry: Geometry,
} }
/// Short hand for creating a Shape with a plane geometry. /// Short hand for creating a ShapeBuilder with a plane geometry.
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use rtchallenge::shapes::{plane, Shape}; /// use rtchallenge::shapes::{plane, Shape};
/// /// # fn main() -> Result<(), Box<std::error::Error>> {
/// assert_eq!(plane(), Shape::plane()); /// assert_eq!(plane().build()?, Shape::plane());
/// # Ok(())
/// # }
/// ``` /// ```
pub fn plane() -> Shape { pub fn plane() -> ShapeBuilder {
Shape::plane() ShapeBuilder::plane()
} }
/// Short hand for creating a Shape with a sphere geometry. /// Short hand for creating a ShapeBuilder with a sphere geometry.
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use rtchallenge::shapes::{sphere, Shape}; /// use rtchallenge::shapes::{sphere, Shape};
/// ///
/// assert_eq!(sphere(), Shape::sphere()); /// # fn main() -> Result<(), Box<std::error::Error>> {
/// assert_eq!(sphere().build()?, Shape::sphere());
/// # Ok(())
/// # }
/// ``` /// ```
pub fn sphere() -> Shape { pub fn sphere() -> ShapeBuilder {
Shape::sphere() ShapeBuilder::sphere()
} }
/// Short hand for creating a Shape with a test shape geometry. /// Short hand for creating a ShapeBuilder with a test shape geometry.
/// ///
/// # Examples /// # Examples
/// ``` /// ```
/// use rtchallenge::shapes::{test_shape, Shape}; /// use rtchallenge::shapes::{test_shape, Shape};
/// ///
/// assert_eq!(test_shape(), Shape::test_shape()); /// # fn main() -> Result<(), Box<std::error::Error>> {
/// assert_eq!(test_shape().build()?, Shape::test_shape());
/// # Ok(())
/// # }
/// ``` /// ```
pub fn test_shape() -> Shape { pub fn test_shape() -> ShapeBuilder {
Shape::test_shape() ShapeBuilder::test_shape()
} }
impl ShapeBuilder { impl ShapeBuilder {
/// Short hand for creating a ShapeBuilder with a plane geometry.
///
/// # Examples
/// ```
/// use rtchallenge::shapes::{plane, Shape};
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// assert_eq!(plane().build()?, Shape::plane());
/// # Ok(())
/// # }
/// ```
pub fn plane() -> ShapeBuilder {
ShapeBuilder::default().geometry(Geometry::Plane)
}
/// Short hand for creating a ShapeBuilder with a sphere geometry.
///
/// # Examples
/// ```
/// use rtchallenge::shapes::{sphere, Shape};
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// assert_eq!(sphere().build()?, Shape::sphere());
/// # Ok(())
/// # }
/// ```
pub fn sphere() -> ShapeBuilder {
ShapeBuilder::default().geometry(Geometry::Sphere)
}
/// Short hand for creating a ShapeBuilder with a test shape geometry.
///
/// # Examples
/// ```
/// use rtchallenge::shapes::{test_shape, Shape};
///
/// # fn main() -> Result<(), Box<std::error::Error>> {
/// assert_eq!(test_shape().build()?, Shape::test_shape());
/// # Ok(())
/// # }
/// ```
pub fn test_shape() -> ShapeBuilder {
ShapeBuilder::default().geometry(Geometry::TestShape(Arc::new(Mutex::new(
TestData::default(),
))))
}
fn default_inverse_transform(&self) -> Result<Matrix4x4, String> { fn default_inverse_transform(&self) -> Result<Matrix4x4, String> {
Ok(self.transform.unwrap_or(Matrix4x4::identity()).inverse()) Ok(self.transform.unwrap_or(Matrix4x4::identity()).inverse())
} }