diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a5c3e37c..da0a8bce0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,8 @@ - Renamed `behavior::BehaviorHost` to `behavior::Host`. - Renamed `behavior::BehaviorPersistence` to `behavior::Persistence`. + - Renamed `space::SpaceBuilder` to `space::Builder`. + - `all-is-cubes-gpu` library: - `in_wgpu::SurfaceRenderer::new()` requires `wgpu::Adapter` instead of `&wgpu::Adapter`. diff --git a/all-is-cubes-content/src/city.rs b/all-is-cubes-content/src/city.rs index 17efecb12..220f34b3f 100644 --- a/all-is-cubes-content/src/city.rs +++ b/all-is-cubes-content/src/city.rs @@ -20,7 +20,7 @@ use all_is_cubes::math::{ GridSizeCoord, GridVector, Gridgid, VectorOps, }; use all_is_cubes::op::Operation; -use all_is_cubes::space::{LightPhysics, Space, SpaceBuilder, SpacePhysics}; +use all_is_cubes::space::{self, LightPhysics, Space, SpacePhysics}; use all_is_cubes::time::Instant; use all_is_cubes::transaction::{self, Transaction}; use all_is_cubes::universe::Universe; @@ -581,7 +581,7 @@ fn place_one_exhibit( // Install the signboard-and-text widgets in a space. let info_sign_space = info_voxels_widget .to_space( - SpaceBuilder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), + space::Builder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), vui::Gravity::new(vui::Align::Center, vui::Align::Center, vui::Align::Low), ) .unwrap(); @@ -832,7 +832,7 @@ fn draw_exhibit_info(exhibit: &Exhibit) -> Result { // TODO: give it a maximum size, instead of what we currently do which is truncating later let space = info_widgets.to_space( - SpaceBuilder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), + space::Builder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), vui::Gravity::new(vui::Align::Low, vui::Align::Low, vui::Align::Low), )?; Ok(space) diff --git a/all-is-cubes-content/src/city/exhibits.rs b/all-is-cubes-content/src/city/exhibits.rs index 2be041fd2..7b6094aaf 100644 --- a/all-is-cubes-content/src/city/exhibits.rs +++ b/all-is-cubes-content/src/city/exhibits.rs @@ -33,7 +33,7 @@ use all_is_cubes::math::{ GridPoint, GridRotation, GridSize, GridVector, Gridgid, NotNan, Rgb, Rgba, }; use all_is_cubes::op::Operation; -use all_is_cubes::space::{SetCubeError, Space, SpaceBuilder, SpacePhysics, SpaceTransaction}; +use all_is_cubes::space::{self, SetCubeError, Space, SpacePhysics, SpaceTransaction}; use all_is_cubes::transaction::{self, Transaction as _}; use all_is_cubes::{color_block, include_image}; @@ -1503,7 +1503,7 @@ fn UI_PROGRESS_BAR(ctx: Context<'_>) { }); let space = tree.to_space( - SpaceBuilder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), + space::Builder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), vui::Gravity::new(vui::Align::Center, vui::Align::Low, vui::Align::Center), )?; diff --git a/all-is-cubes-content/src/menu.rs b/all-is-cubes-content/src/menu.rs index f27a80f1b..8c92803c4 100644 --- a/all-is-cubes-content/src/menu.rs +++ b/all-is-cubes-content/src/menu.rs @@ -74,7 +74,7 @@ fn template_menu_widget_tree( // TODO: the scaled-down logo should exist as a widget itself let logo_text_space = vui::leaf_widget(logo_text()).to_space( - space::SpaceBuilder::default().physics(space::SpacePhysics::DEFAULT_FOR_BLOCK), + space::Builder::default().physics(space::SpacePhysics::DEFAULT_FOR_BLOCK), Vector3D::new(Align::Center, Align::Center, Align::Low), )?; let logo_text_bounds = logo_text_space.bounds(); diff --git a/all-is-cubes-ui/src/vui/layout.rs b/all-is-cubes-ui/src/vui/layout.rs index af9f7fe90..55432e4bd 100644 --- a/all-is-cubes-ui/src/vui/layout.rs +++ b/all-is-cubes-ui/src/vui/layout.rs @@ -9,7 +9,7 @@ use core::fmt; use all_is_cubes::euclid::{self, size3, Size3D, Vector3D}; use all_is_cubes::math::{Axis, Cube, Face6, FaceMap, GridAab, GridPoint, GridSize}; -use all_is_cubes::space::{Space, SpaceBuilder, SpaceTransaction}; +use all_is_cubes::space::{self, Space, SpaceTransaction}; use all_is_cubes::transaction::{self, Merge as _, Transaction as _}; use all_is_cubes::util::{ConciseDebug, Fmt}; @@ -432,9 +432,9 @@ impl LayoutTree> { /// /// Note that the widgets will not actually appear as blocks until the first time the /// space is stepped. - pub fn to_space( + pub fn to_space( self: &Arc, - builder: SpaceBuilder, + builder: space::Builder, gravity: Gravity, ) -> Result { let mut space = builder diff --git a/all-is-cubes-ui/src/vui/page.rs b/all-is-cubes-ui/src/vui/page.rs index a60ec724b..84597ca78 100644 --- a/all-is-cubes-ui/src/vui/page.rs +++ b/all-is-cubes-ui/src/vui/page.rs @@ -9,7 +9,7 @@ use all_is_cubes::euclid::{size2, Size2D}; use all_is_cubes::math::{ Cube, Face6, FreeCoordinate, FreeVector, GridAab, GridCoordinate, GridSize, GridSizeCoord, Rgba, }; -use all_is_cubes::space::{self, Space, SpaceBuilder, SpacePhysics}; +use all_is_cubes::space::{self, Space, SpacePhysics}; use all_is_cubes::time; use all_is_cubes::universe::{Handle, Universe}; use all_is_cubes_render::camera::{self, ViewTransform}; @@ -305,7 +305,7 @@ pub(crate) mod parts { large: &WidgetTree, ) -> Result, InstallVuiError> { let space = large.to_space( - SpaceBuilder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), + space::Builder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), Gravity::new(Align::Center, Align::Center, Align::Low), )?; Ok(Arc::new(widgets::Voxels::new( diff --git a/all-is-cubes-ui/src/vui/widgets/progress_bar.rs b/all-is-cubes-ui/src/vui/widgets/progress_bar.rs index b04d42d90..42f772fd6 100644 --- a/all-is-cubes-ui/src/vui/widgets/progress_bar.rs +++ b/all-is-cubes-ui/src/vui/widgets/progress_bar.rs @@ -205,7 +205,7 @@ impl vui::WidgetController for ProgressBarController { #[cfg(test)] mod tests { use super::*; - use all_is_cubes::space::{SpaceBuilder, SpacePhysics}; + use all_is_cubes::space::{self, SpacePhysics}; use all_is_cubes::transaction::Transaction as _; use all_is_cubes::util::yield_progress_for_testing; use all_is_cubes::{transaction, universe}; @@ -231,7 +231,7 @@ mod tests { ListenableSource::constant(ProgressBarState::new(fraction)), )); - let mut space = SpaceBuilder::default() + let mut space = space::Builder::default() .physics(SpacePhysics::DEFAULT_FOR_BLOCK) .bounds(bounds) .build(); diff --git a/all-is-cubes-ui/src/vui/widgets/text.rs b/all-is-cubes-ui/src/vui/widgets/text.rs index b0bc11872..1a9d5710d 100644 --- a/all-is-cubes-ui/src/vui/widgets/text.rs +++ b/all-is-cubes-ui/src/vui/widgets/text.rs @@ -251,7 +251,7 @@ mod tests { use all_is_cubes::color_block; use all_is_cubes::euclid::size3; use all_is_cubes::math::{GridSizeCoord, Rgba}; - use all_is_cubes::space::{SpaceBuilder, SpacePhysics}; + use all_is_cubes::space::{self, SpacePhysics}; #[test] fn large_text_size() { @@ -276,7 +276,7 @@ mod tests { // to_space() serves as a widget building sanity check. TODO: make a proper widget tester tree.to_space( - SpaceBuilder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), + space::Builder::default().physics(SpacePhysics::DEFAULT_FOR_BLOCK), vui::Gravity::new(vui::Align::Center, vui::Align::Center, vui::Align::Low), ) .unwrap(); diff --git a/all-is-cubes/src/block/builder.rs b/all-is-cubes/src/block/builder.rs index 0be1d911c..42dcd167a 100644 --- a/all-is-cubes/src/block/builder.rs +++ b/all-is-cubes/src/block/builder.rs @@ -192,7 +192,7 @@ impl BlockBuilder { B: Into>, { // This is a worldgen convenience, not the most efficient possible path (which would be - // `SpaceBuilder::palette_and_contents()`), so save quite a lot of code generation + // `Builder::palette_and_contents()`), so save quite a lot of code generation // by keeping it monomorphic and not inlined. #[inline(never)] fn voxels_fn_impl<'a>( @@ -204,7 +204,7 @@ impl BlockBuilder { let mut not_air_bounds: Option = None; let mut space = Space::for_block(resolution).build(); - // TODO: Teach the SpaceBuilder to accept a function in the same way? + // TODO: Teach the Space Builder to accept a function in the same way? space.fill(space.bounds(), |cube| { let block = function(cube); diff --git a/all-is-cubes/src/content/load_image.rs b/all-is-cubes/src/content/load_image.rs index 408adc3f6..86cb537c9 100644 --- a/all-is-cubes/src/content/load_image.rs +++ b/all-is-cubes/src/content/load_image.rs @@ -135,7 +135,7 @@ impl embedded_graphics::geometry::OriginDimensions for &'_ PngAdapter<'_> { /// /// The `block_function` will be memoized. /// -/// TODO: Allow `SpaceBuilder` controls somehow. Maybe this belongs as a method on SpaceBuilder. +/// TODO: Allow `space::Builder` controls somehow. Maybe this belongs as a method on it. /// TODO: pixel_function should have a Result return #[doc(hidden)] // still experimental API #[inline(never)] diff --git a/all-is-cubes/src/space.rs b/all-is-cubes/src/space.rs index 1ad4846df..4eb68c933 100644 --- a/all-is-cubes/src/space.rs +++ b/all-is-cubes/src/space.rs @@ -31,9 +31,8 @@ use crate::transaction::{self, Merge, Transaction as _}; use crate::universe::{Handle, HandleVisitor, UniverseTransaction, VisitHandles}; use crate::util::{ConciseDebug, Refmt as _, StatusText, TimeStats}; -mod builder; -#[allow(clippy::module_name_repetitions)] // TODO: rename to Builder? -pub use builder::{SpaceBuilder, SpaceBuilderBounds}; +pub mod builder; +pub use builder::Builder; mod light; #[doc(hidden)] // pub only for visualization by all-is-cubes-gpu @@ -113,24 +112,26 @@ impl fmt::Debug for Space { pub type BlockIndex = u16; impl Space { - /// Returns a [`SpaceBuilder`] configured for a block, + /// Returns a space [`Builder`] configured for a [recursive] block, /// which may be used to construct a new [`Space`]. /// /// This means that its bounds are as per [`GridAab::for_block()`], and its /// [`physics`](Self::physics) is [`SpacePhysics::DEFAULT_FOR_BLOCK`]. - pub fn for_block(resolution: Resolution) -> SpaceBuilder> { - SpaceBuilder::new() + /// + /// [recursive]: crate::block::Primitive::Recur + pub fn for_block(resolution: Resolution) -> Builder> { + Builder::new() .bounds(GridAab::for_block(resolution)) .physics(SpacePhysics::DEFAULT_FOR_BLOCK) } - /// Returns a [`SpaceBuilder`] with the given bounds and all default values, + /// Returns a [`space::Builder`](Builder) with the given bounds and all default values, /// which may be used to construct a new [`Space`]. /// /// Panics if `bounds` has a volume exceeding `usize::MAX`. /// (But there will likely be a memory allocation failure well below that point.) - pub fn builder(bounds: GridAab) -> SpaceBuilder> { - SpaceBuilder::new().bounds(bounds) + pub fn builder(bounds: GridAab) -> Builder> { + Builder::new().bounds(bounds) } /// Constructs a [`Space`] that is entirely filled with [`AIR`]. @@ -140,9 +141,9 @@ impl Space { Space::builder(bounds).build() } - /// Implementation of [`SpaceBuilder`]'s terminal methods. - fn new_from_builder(builder: SpaceBuilder>) -> Self { - let SpaceBuilder { + /// Implementation of [`Builder`]'s terminal methods. + fn new_from_builder(builder: Builder>) -> Self { + let Builder { bounds, spawn, physics, diff --git a/all-is-cubes/src/space/builder.rs b/all-is-cubes/src/space/builder.rs index 7ad90f2c9..a07462d18 100644 --- a/all-is-cubes/src/space/builder.rs +++ b/all-is-cubes/src/space/builder.rs @@ -1,3 +1,5 @@ +//! Lesser-used helpers for [`Builder`]. + use alloc::boxed::Box; use crate::behavior::BehaviorSet; @@ -8,19 +10,16 @@ use crate::space::{ BlockIndex, GridAab, LightPhysics, PackedLight, Palette, PaletteError, Sky, Space, SpacePhysics, }; -/// Tool for constructing new [`Space`]s. -/// -/// To create one, call [`Space::builder()`](Space::builder). +/// Builder of [`Space`]s. /// -/// TODO: Allow specifying behaviors. +/// To create one, call [`Space::builder()`](Space::builder) or [`Builder::default()`]. /// /// # Type parameters /// /// * `B` is either `()` or `Vol<()>` according to whether the bounds have been specified. #[derive(Clone, Debug)] #[must_use] -#[allow(clippy::module_name_repetitions)] -pub struct SpaceBuilder { +pub struct Builder { pub(super) bounds: B, pub(super) spawn: Option, pub(super) physics: SpacePhysics, @@ -39,7 +38,7 @@ pub(super) enum Fill { }, } -impl SpaceBuilder { +impl Builder { /// Sets the [`Block`] that the space's volume will be filled with. /// /// Calling this method will replace any previous specification of the contents, @@ -92,16 +91,16 @@ impl SpaceBuilder { } } -impl SpaceBuilder { +impl Builder { /// Set the bounds unless they have already been set. - pub fn bounds_if_not_set(self, bounds_fn: impl FnOnce() -> GridAab) -> SpaceBuilder> { + pub fn bounds_if_not_set(self, bounds_fn: impl FnOnce() -> GridAab) -> Builder> { // Delegate to the trait. (This method exists so the trait need not be imported.) - SpaceBuilderBounds::bounds_if_not_set(self, bounds_fn) + Bounds::bounds_if_not_set(self, bounds_fn) } } -impl SpaceBuilder<()> { - /// Use [`SpaceBuilder::default()`] as the public way to call this. +impl Builder<()> { + /// Use [`Builder::default()`] as the public way to call this. pub(super) fn new() -> Self { Self { bounds: (), @@ -116,8 +115,8 @@ impl SpaceBuilder<()> { /// /// Panics if `bounds` has a volume exceeding `usize::MAX`. /// (But there will likely be a memory allocation failure well below that point.) - pub fn bounds(self, bounds: GridAab) -> SpaceBuilder> { - SpaceBuilder { + pub fn bounds(self, bounds: GridAab) -> Builder> { + Builder { bounds: bounds.to_vol().unwrap(), spawn: self.spawn, physics: self.physics, @@ -127,7 +126,7 @@ impl SpaceBuilder<()> { } } -impl SpaceBuilder> { +impl Builder> { /// Sets the default spawn location of new characters. /// /// Panics if any of the given coordinates is infinite or NaN. @@ -238,52 +237,52 @@ impl SpaceBuilder> { } } -impl Default for SpaceBuilder<()> { +impl Default for Builder<()> { fn default() -> Self { Self::new() } } -/// Helper for [`SpaceBuilder::bounds_if_not_set()`]. Do not call or implement this trait. -pub trait SpaceBuilderBounds: sbb::SbbSealed + Sized { +/// Helper for [`Builder::bounds_if_not_set()`]. Do not call or implement this trait. +pub trait Bounds: sealed::Sealed + Sized { /// Set the bounds unless they have already been set. /// /// This function is an implementation detail; call - /// [`SpaceBuilder::bounds_if_not_set()`] instead. + /// [`Builder::bounds_if_not_set()`] instead. #[doc(hidden)] fn bounds_if_not_set( - builder: SpaceBuilder, + builder: Builder, bounds_fn: impl FnOnce() -> GridAab, - ) -> SpaceBuilder>; + ) -> Builder>; } -impl SpaceBuilderBounds for () { +impl Bounds for () { fn bounds_if_not_set( - builder: SpaceBuilder, + builder: Builder, bounds_fn: impl FnOnce() -> GridAab, - ) -> SpaceBuilder> { + ) -> Builder> { builder.bounds(bounds_fn()) } } -impl SpaceBuilderBounds for Vol<()> { +impl Bounds for Vol<()> { fn bounds_if_not_set( - builder: SpaceBuilder, + builder: Builder, _bounds_fn: impl FnOnce() -> GridAab, - ) -> SpaceBuilder> { + ) -> Builder> { builder } } /// Module for sealed trait -mod sbb { +mod sealed { #![expect(clippy::module_name_repetitions)] use super::*; #[doc(hidden)] #[expect(unnameable_types)] - pub trait SbbSealed {} - impl SbbSealed for () {} - impl SbbSealed for Vol<()> {} + pub trait Sealed {} + impl Sealed for () {} + impl Sealed for Vol<()> {} } #[cfg(feature = "arbitrary")] @@ -363,10 +362,7 @@ mod tests { fn bounds_if_not_set_when_not_set() { let bounds = GridAab::from_lower_size([1, 2, 3], [1, 1, 1]); assert_eq!( - SpaceBuilder::new() - .bounds_if_not_set(|| bounds) - .build() - .bounds(), + Builder::new().bounds_if_not_set(|| bounds).build().bounds(), bounds ); } diff --git a/all-is-cubes/src/space/light/data.rs b/all-is-cubes/src/space/light/data.rs index 744d361c0..5b3f15288 100644 --- a/all-is-cubes/src/space/light/data.rs +++ b/all-is-cubes/src/space/light/data.rs @@ -15,7 +15,7 @@ use num_traits::float::Float as _; use crate::math::{NotNan, Rgb}; #[cfg(doc)] -use crate::space::Space; +use crate::space::{self, Space}; /// One component of a `PackedLight`. pub(crate) type PackedLightScalar = u8; @@ -33,7 +33,7 @@ pub(crate) enum LightStatus { /// /// This value may appear when: /// - /// * [`SpaceBuilder::palette_and_contents()`] was called without including light data. + /// * [`space::Builder::palette_and_contents()`] was called without including light data. /// * The light updater is speculatively copying from neighboring cubes. Uninitialized = 0, /// The cube has no surfaces to catch light and therefore the light value is not tracked. diff --git a/all-is-cubes/src/space/palette.rs b/all-is-cubes/src/space/palette.rs index 304a0d397..430ee0c4e 100644 --- a/all-is-cubes/src/space/palette.rs +++ b/all-is-cubes/src/space/palette.rs @@ -18,6 +18,9 @@ use crate::time::Instant; use crate::util::maybe_sync::Mutex; use crate::util::TimeStats; +#[cfg(doc)] +use crate::space; + cfg_if::cfg_if! { if #[cfg(feature = "std")] { // HashDoS-resistant @@ -541,11 +544,9 @@ impl listen::Listener for BlockListener { } /// Errors that can occur in palette-and-indices data, such as that provided to -/// [`SpaceBuilder::palette_and_contents()`]. -/// -/// [`SpaceBuilder::palette_and_contents()`]: crate::space::SpaceBuilder::palette_and_contents() +/// [`space::Builder::palette_and_contents()`]. // -// TODO: `SpaceBuilder` doesn't actually use `Palette` directly yet; this is here because +// TODO: `space::Builder` doesn't actually use `Palette` directly yet; this is here because // we plan that it *will*, and then `Palette` will be returning some of these errors. #[derive(Clone, Debug, PartialEq)] #[allow(missing_docs)] @@ -663,5 +664,5 @@ mod tests { } // TODO: test Palette::from_blocks(), especially around remapping. - // It has tests via `SpaceBuilder`, but not much. + // It has tests via `space::Builder`, but not much. } diff --git a/test-renderers/src/test_cases.rs b/test-renderers/src/test_cases.rs index 87a623ddd..b255c845a 100644 --- a/test-renderers/src/test_cases.rs +++ b/test-renderers/src/test_cases.rs @@ -18,7 +18,7 @@ use all_is_cubes::math::{ notnan, rgb_const, rgba_const, Axis, Cube, Face6, FreeCoordinate, GridAab, GridCoordinate, GridPoint, GridRotation, GridVector, NotNan, Rgb, Rgba, Vol, }; -use all_is_cubes::space::{self, LightPhysics, Space, SpaceBuilder}; +use all_is_cubes::space::{self, LightPhysics, Space}; use all_is_cubes::time; use all_is_cubes::transaction::{self, Transaction as _}; use all_is_cubes::universe::{Handle, HandleError, Universe, UniverseTransaction}; @@ -622,7 +622,7 @@ async fn icons(mut context: RenderTestContext) { fn block_from_widget(w: &vui::WidgetTree) -> Block { let space = w .to_space( - SpaceBuilder::default(), + space::Builder::default(), Vector3D::new(Align::Low, Align::Low, Align::Low), ) .unwrap(); diff --git a/test-renderers/tests/ui.rs b/test-renderers/tests/ui.rs index 1af51e266..2fde4fa0d 100644 --- a/test-renderers/tests/ui.rs +++ b/test-renderers/tests/ui.rs @@ -214,7 +214,7 @@ fn render_widget(widget: &vui::WidgetTree, gravity: vui::Gravity) -> Rendering { let space_handle = Handle::new_pending( Name::Pending, widget - .to_space(space::SpaceBuilder::default(), gravity) + .to_space(space::Builder::default(), gravity) .unwrap(), ); let space_to_render_time = Instant::now();