Struct all_is_cubes::space::Space
source · pub struct Space { /* private fields */ }Expand description
Container for Blocks arranged in three-dimensional space. The main “game world”
data structure.
§Serialization stability warning
This type implements serde::Serialize and serde::Deserialize, but serialization
support is still experimental (as is the game data model in general). We do not guarantee that future versions of all-is-cubes
will be able to deserialize data which is serialized by this version.
Additionally, the serialization schema is designed with serde_json in mind. It is not
guaranteed that using a different data format crate, which may use a different subset of
the information exposed via serde::Serialize, will produce stable results.
Implementations§
source§impl Space
impl Space
sourcepub fn for_block(resolution: Resolution) -> SpaceBuilder<Vol<()>>
pub fn for_block(resolution: Resolution) -> SpaceBuilder<Vol<()>>
Returns a SpaceBuilder configured for a block,
which may be used to construct a new Space.
This means that its bounds are as per GridAab::for_block(), and its
physics is SpacePhysics::DEFAULT_FOR_BLOCK.
sourcepub fn builder(bounds: GridAab) -> SpaceBuilder<Vol<()>>
pub fn builder(bounds: GridAab) -> SpaceBuilder<Vol<()>>
Returns a SpaceBuilder 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.)
sourcepub fn empty_positive<S>(wx: S, wy: S, wz: S) -> Space
pub fn empty_positive<S>(wx: S, wy: S, wz: S) -> Space
Constructs a Space that is entirely empty and whose coordinate system
is in the +X+Y+Z octant. This is a shorthand intended mainly for tests.
Panics if the volume is greater than usize::MAX, if any dimension is greater than
i32::MAX.
sourcepub fn bounds(&self) -> GridAab
pub fn bounds(&self) -> GridAab
Returns the GridAab describing the bounds of this space; no blocks may exist
outside it.
sourcepub fn get_block_index(&self, position: impl Into<Cube>) -> Option<BlockIndex>
pub fn get_block_index(&self, position: impl Into<Cube>) -> Option<BlockIndex>
Returns the internal unstable numeric ID for the block at the given position,
which may be mapped to a Block by Space::block_data.
If you are looking for simple access, use space[position] (the
core::ops::Index trait) instead.
These IDs may be used to perform efficient processing of many blocks, but they may be renumbered after any mutation.
sourcepub fn extract<'s, C, V>(
&'s self,
bounds: GridAab,
extractor: impl FnMut(Extract<'s>) -> V,
) -> Vol<C>
pub fn extract<'s, C, V>( &'s self, bounds: GridAab, extractor: impl FnMut(Extract<'s>) -> V, ) -> Vol<C>
Copy data out of a portion of the space in a caller-chosen format.
The given bounds must be fully contained within self.bounds().
sourcepub fn get_evaluated(&self, position: impl Into<Cube>) -> &EvaluatedBlock
pub fn get_evaluated(&self, position: impl Into<Cube>) -> &EvaluatedBlock
Returns the EvaluatedBlock of the block in this space at the given position.
If out of bounds, returns the evaluation of AIR.
sourcepub fn get_lighting(&self, cube: impl Into<Cube>) -> PackedLight
pub fn get_lighting(&self, cube: impl Into<Cube>) -> PackedLight
Returns the light occupying the given cube.
This value may be considered as representing the average of the light reflecting off of all surfaces within, or immediately adjacent to and facing toward, this cube. If there are no such surfaces, or if the given position is out of bounds, the result is arbitrary. If the position is within an opaque block, the result is black.
Lighting is updated asynchronously after modifications, so all above claims about the meaning of this value are actually “will eventually be, if no more changes are made”.
sourcepub fn set<'a>(
&mut self,
position: impl Into<Cube>,
block: impl Into<Cow<'a, Block>>,
) -> Result<bool, SetCubeError>
pub fn set<'a>( &mut self, position: impl Into<Cube>, block: impl Into<Cow<'a, Block>>, ) -> Result<bool, SetCubeError>
Replace the block in this space at the given position.
If the position is out of bounds, there is no effect.
§Returns
Returns Ok(true) if the change was made, Ok(false) if the same block was
already present, and Err(_) if the replacement could not be made; see
SetCubeError for possible errors.
use all_is_cubes::block::*;
use all_is_cubes::math::Rgba;
use all_is_cubes::space::Space;
let mut space = Space::empty_positive(1, 1, 1);
let a_block = Block::builder().color(Rgba::new(1.0, 0.0, 0.0, 1.0)).build();
space.set([0, 0, 0], &a_block);
assert_eq!(space[[0, 0, 0]], a_block);sourcepub fn fill<F, B>(
&mut self,
region: GridAab,
function: F,
) -> Result<(), SetCubeError>
pub fn fill<F, B>( &mut self, region: GridAab, function: F, ) -> Result<(), SetCubeError>
Replace blocks in region with a block computed by the function.
The function may return a reference to a block or a block. If it returns None,
the existing block is left unchanged.
The operation will stop on the first error, potentially leaving some blocks
replaced. (Exception: If the region extends outside of
self.bounds(), that will always be rejected before any changes
are made.)
use all_is_cubes::block::{AIR, Block};
use all_is_cubes::math::{GridAab, Rgba};
use all_is_cubes::space::Space;
let mut space = Space::empty_positive(10, 10, 10);
let a_block: Block = Rgba::new(1.0, 0.0, 0.0, 1.0).into();
space.fill(GridAab::from_lower_size([0, 0, 0], [2, 1, 1]), |_point| Some(&a_block)).unwrap();
assert_eq!(space[[0, 0, 0]], a_block);
assert_eq!(space[[1, 0, 0]], a_block);
assert_eq!(space[[0, 1, 0]], AIR);TODO: Support providing the previous block as a parameter (take cues from extract).
See also Space::fill_uniform for filling a region with one block.
sourcepub fn fill_uniform(
&mut self,
region: GridAab,
block: &Block,
) -> Result<(), SetCubeError>
pub fn fill_uniform( &mut self, region: GridAab, block: &Block, ) -> Result<(), SetCubeError>
Replace blocks in region with the given block.
TODO: Document error behavior
use all_is_cubes::block::{AIR, Block};
use all_is_cubes::math::{GridAab, Rgba};
use all_is_cubes::space::Space;
let mut space = Space::empty_positive(10, 10, 10);
let a_block: Block = Rgba::new(1.0, 0.0, 0.0, 1.0).into();
space.fill_uniform(GridAab::from_lower_size([0, 0, 0], [2, 1, 1]), &a_block).unwrap();
assert_eq!(&space[[0, 0, 0]], &a_block);
assert_eq!(&space[[1, 0, 0]], &a_block);
assert_eq!(&space[[0, 1, 0]], &AIR);See also Space::fill for non-uniform fill and bulk copies.
sourcepub fn draw_target<C>(
&mut self,
transform: Gridgid,
) -> DrawingPlane<'_, Space, C>
pub fn draw_target<C>( &mut self, transform: Gridgid, ) -> DrawingPlane<'_, Space, C>
Provides an DrawTarget
adapter for 2.5D drawing.
For more information on how to use this, see
all_is_cubes::drawing.
sourcepub fn distinct_blocks(&self) -> Vec<Block>
pub fn distinct_blocks(&self) -> Vec<Block>
Returns all distinct block types found in the space.
TODO: This was invented for testing the indexing of blocks and should be replaced with something else if it only gets used for testing.
sourcepub fn block_data(&self) -> &[SpaceBlockData]
pub fn block_data(&self) -> &[SpaceBlockData]
Returns data about all the blocks assigned internal IDs (indices) in the space, as well as placeholder data for any deallocated indices.
The indices of this slice correspond to the results of Space::get_block_index.
sourcepub fn step<I: Instant>(
&mut self,
self_handle: Option<&Handle<Space>>,
tick: Tick,
deadline: Deadline<I>,
) -> (SpaceStepInfo, UniverseTransaction)
pub fn step<I: Instant>( &mut self, self_handle: Option<&Handle<Space>>, tick: Tick, deadline: Deadline<I>, ) -> (SpaceStepInfo, UniverseTransaction)
Advance time in the space.
tickis how much time is to pass in the simulation.deadlineis when to stop computing flexible things such as light transport.
sourcepub fn fluff(&self) -> impl Listen<Msg = SpaceFluff> + '_
pub fn fluff(&self) -> impl Listen<Msg = SpaceFluff> + '_
Returns the source of fluff occurring in this space.
sourcepub fn evaluate_light<I: Instant>(
&mut self,
epsilon: u8,
progress_callback: impl FnMut(LightUpdatesInfo),
) -> usize
pub fn evaluate_light<I: Instant>( &mut self, epsilon: u8, progress_callback: impl FnMut(LightUpdatesInfo), ) -> usize
Perform lighting updates until there are none left to do. Returns the number of updates performed.
This may take a while. It is appropriate for when the goal is to render a fully lit scene non-interactively.
epsilon specifies a threshold at which to stop doing updates.
Zero means to run to full completion; one is the smallest unit of light level
difference; and so on.
sourcepub fn physics(&self) -> &SpacePhysics
pub fn physics(&self) -> &SpacePhysics
Returns the current SpacePhysics data, which determines global characteristics
such as the behavior of light and gravity.
sourcepub fn set_physics(&mut self, physics: SpacePhysics)
pub fn set_physics(&mut self, physics: SpacePhysics)
Sets the physics parameters, as per physics.
This may cause immediate recomputation of lighting.
sourcepub fn behaviors(&self) -> &BehaviorSet<Space>
pub fn behaviors(&self) -> &BehaviorSet<Space>
Returns the BehaviorSet of behaviors attached to this space.
sourcepub fn fast_evaluate_light(&mut self)
pub fn fast_evaluate_light(&mut self)
Clear and recompute light data and update queue, in a way which gets fast approximate results suitable for flat landscapes mostly lit from above (the +Y axis).
TODO: Revisit whether this is a good public API.
Trait Implementations§
source§impl<'a> Arbitrary<'a> for Space
impl<'a> Arbitrary<'a> for Space
source§fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self>
fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self>
Self from the given unstructured data. Read moresource§fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self, Error>
fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self, Error>
Self from the entirety of the given
unstructured data. Read moresource§impl Behavior<Space> for ActivatableRegion
impl Behavior<Space> for ActivatableRegion
source§fn step(
&self,
_context: &BehaviorContext<'_, Space>,
) -> (UniverseTransaction, Then)
fn step( &self, _context: &BehaviorContext<'_, Space>, ) -> (UniverseTransaction, Then)
source§fn persistence(&self) -> Option<BehaviorPersistence>
fn persistence(&self) -> Option<BehaviorPersistence>
None, then the behavior should not be persisted/saved to disk, because it will be
reconstructed as needed (e.g. collision, occupancy, user interaction, particles). Read moresource§impl BehaviorHost for Space
impl BehaviorHost for Space
§type Attachment = SpaceBehaviorAttachment
type Attachment = SpaceBehaviorAttachment
source§impl<'de> Deserialize<'de> for Space
impl<'de> Deserialize<'de> for Space
source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
source§impl<T: Into<Cube>> Index<T> for Space
impl<T: Into<Cube>> Index<T> for Space
source§fn index(&self, position: T) -> &Self::Output
fn index(&self, position: T) -> &Self::Output
Gets a reference to the block in this space at the given position.
If the position is out of bounds, returns AIR.
Note that Space does not implement IndexMut;
use Space::set or Space::fill to modify blocks.
source§impl Listen for Space
impl Listen for Space
source§fn listen<L: Listener<SpaceChange> + 'static>(&self, listener: L)
fn listen<L: Listener<SpaceChange> + 'static>(&self, listener: L)
Registers a listener for mutations of this space.
§type Msg = SpaceChange
type Msg = SpaceChange
source§impl Transactional for Space
impl Transactional for Space
§type Transaction = SpaceTransaction
type Transaction = SpaceTransaction
Self.source§fn transact<F, O>(&mut self, f: F) -> Result<O, ExecuteError<Self::Transaction>>where
F: FnOnce(&mut Self::Transaction, &Self) -> Result<O, <Self::Transaction as Merge>::Conflict>,
Self::Transaction: Transaction<Target = Self, Output = NoOutput> + Default,
fn transact<F, O>(&mut self, f: F) -> Result<O, ExecuteError<Self::Transaction>>where
F: FnOnce(&mut Self::Transaction, &Self) -> Result<O, <Self::Transaction as Merge>::Conflict>,
Self::Transaction: Transaction<Target = Self, Output = NoOutput> + Default,
self,
equivalent to the following steps: Read moresource§impl UTransactional for Space
impl UTransactional for Space
source§fn bind(
target: Handle<Self>,
transaction: Self::Transaction,
) -> UniverseTransaction
fn bind( target: Handle<Self>, transaction: Self::Transaction, ) -> UniverseTransaction
source§impl VisitHandles for Space
impl VisitHandles for Space
source§fn visit_handles(&self, visitor: &mut dyn HandleVisitor)
fn visit_handles(&self, visitor: &mut dyn HandleVisitor)
Auto Trait Implementations§
impl !Freeze for Space
impl !RefUnwindSafe for Space
impl Send for Space
impl Sync for Space
impl Unpin for Space
impl !UnwindSafe for Space
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CheckedAs for T
impl<T> CheckedAs for T
source§fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
fn checked_as<Dst>(self) -> Option<Dst>where
T: CheckedCast<Dst>,
source§impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
impl<Src, Dst> CheckedCastFrom<Src> for Dstwhere
Src: CheckedCast<Dst>,
source§fn checked_cast_from(src: Src) -> Option<Dst>
fn checked_cast_from(src: Src) -> Option<Dst>
source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more