Struct all_is_cubes::space::Space
source · pub struct Space { /* private fields */ }
Expand description
Container for Block
s 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
Methods on Space that specifically implement the lighting algorithm.
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.
source§impl Space
impl Space
sourcepub fn for_block(resolution: Resolution) -> SpaceBuilder<GridAab>
pub fn for_block(resolution: Resolution) -> SpaceBuilder<GridAab>
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<GridAab>
pub fn builder(bounds: GridAab) -> SpaceBuilder<GridAab>
Returns a SpaceBuilder
with the given bounds and all default values,
which may be used to construct a new Space
.
sourcepub fn empty_positive(
wx: GridCoordinate,
wy: GridCoordinate,
wz: GridCoordinate
) -> Space
pub fn empty_positive( wx: GridCoordinate, wy: GridCoordinate, wz: GridCoordinate ) -> 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.
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<GridPoint>
) -> Option<BlockIndex>
pub fn get_block_index( &self, position: impl Into<GridPoint> ) -> 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
std::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, V>(
&'s self,
bounds: GridAab,
extractor: impl FnMut(Extract<'s>) -> V
) -> GridArray<V>
pub fn extract<'s, V>( &'s self, bounds: GridAab, extractor: impl FnMut(Extract<'s>) -> V ) -> GridArray<V>
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<GridPoint>) -> &EvaluatedBlock
pub fn get_evaluated(&self, position: impl Into<GridPoint>) -> &EvaluatedBlock
Gets the EvaluatedBlock
of the block in this space at the given position.
sourcepub fn get_lighting(&self, position: impl Into<GridPoint>) -> PackedLight
pub fn get_lighting(&self, position: impl Into<GridPoint>) -> 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<GridPoint>,
block: impl Into<Cow<'a, Block>>
) -> Result<bool, SetCubeError>
pub fn set<'a>( &mut self, position: impl Into<GridPoint>, 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>where
F: FnMut(GridPoint) -> Option<B>,
B: Borrow<Block>,
pub fn fill<F, B>( &mut self, region: GridAab, function: F ) -> Result<(), SetCubeError>where F: FnMut(GridPoint) -> Option<B>, B: Borrow<Block>,
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<'b>(
&mut self,
region: GridAab,
block: impl Into<Cow<'b, Block>>
) -> Result<(), SetCubeError>
pub fn fill_uniform<'b>( &mut self, region: GridAab, block: impl Into<Cow<'b, 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: GridMatrix
) -> DrawingPlane<'_, Space, C>
pub fn draw_target<C>( &mut self, transform: GridMatrix ) -> 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(
&mut self,
self_ref: Option<&URef<Space>>,
tick: Tick,
deadline: Instant
) -> (SpaceStepInfo, UniverseTransaction)
pub fn step( &mut self, self_ref: Option<&URef<Space>>, tick: Tick, deadline: Instant ) -> (SpaceStepInfo, UniverseTransaction)
Advance time in the space.
tick
is how much time is to pass in the simulation.deadline
is when to stop computing flexible things such as light transport.
sourcepub fn evaluate_light(
&mut self,
epsilon: u8,
progress_callback: impl FnMut(LightUpdatesInfo)
) -> usize
pub fn evaluate_light( &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 recomputation of lighting.
sourcepub fn behaviors(&self) -> &BehaviorSet<Space>
pub fn behaviors(&self) -> &BehaviorSet<Space>
Returns the BehaviorSet
of behaviors attached to this space.
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 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§fn step(
&self,
_context: &BehaviorContext<'_, H>,
_tick: Tick
) -> UniverseTransaction
fn step( &self, _context: &BehaviorContext<'_, H>, _tick: Tick ) -> UniverseTransaction
source§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<GridPoint>> Index<T> for Space
impl<T: Into<GridPoint>> 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> + Send + Sync + 'static>(&self, listener: L)
fn listen<L: Listener<SpaceChange> + Send + Sync + 'static>(&self, listener: L)
Registers a listener for mutations of this space.
§type Msg = SpaceChange
type Msg = SpaceChange
source§impl Transaction<Space> for SpaceTransaction
impl Transaction<Space> for SpaceTransaction
§type CommitCheck = <BehaviorSetTransaction<Space> as Transaction<BehaviorSet<Space>>>::CommitCheck
type CommitCheck = <BehaviorSetTransaction<Space> as Transaction<BehaviorSet<Space>>>::CommitCheck
Transaction::check
to Transaction::commit
.
This may be used to pass precalculated values to speed up the commit phase,
or even lock guards or similar, but also makes it slightly harder to accidentally
call commit
without check
.§type Output = Infallible
type Output = Infallible
Transaction::commit()
or Transaction::execute()
.
Each commit may produce any number of these messages. Read moresource§fn check(&self, space: &Space) -> Result<Self::CommitCheck, PreconditionFailed>
fn check(&self, space: &Space) -> Result<Self::CommitCheck, PreconditionFailed>
source§fn commit(
&self,
space: &mut Space,
check: Self::CommitCheck,
_outputs: &mut dyn FnMut(Self::Output)
) -> Result<(), CommitError>
fn commit( &self, space: &mut Space, check: Self::CommitCheck, _outputs: &mut dyn FnMut(Self::Output) ) -> Result<(), CommitError>
check
value should have
been created by a prior call to Transaction::commit
. Read moresource§fn execute(
&self,
target: &mut T,
outputs: &mut dyn FnMut(Self::Output)
) -> Result<(), ExecuteError>
fn execute( &self, target: &mut T, outputs: &mut dyn FnMut(Self::Output) ) -> Result<(), ExecuteError>
source§fn bind(self, target: URef<T>) -> UniverseTransactionwhere
Self: Sized,
T: UTransactional<Transaction = Self>,
fn bind(self, target: URef<T>) -> UniverseTransactionwhere Self: Sized, T: UTransactional<Transaction = Self>,
source§impl Transactional for Space
impl Transactional for Space
§type Transaction = SpaceTransaction
type Transaction = SpaceTransaction
Self
.source§impl UTransactional for Space
impl UTransactional for Space
source§fn bind(
target: URef<Self>,
transaction: Self::Transaction
) -> UniverseTransaction
fn bind( target: URef<Self>, transaction: Self::Transaction ) -> UniverseTransaction
source§impl VisitRefs for Space
impl VisitRefs for Space
source§fn visit_refs(&self, visitor: &mut dyn RefVisitor)
fn visit_refs(&self, visitor: &mut dyn RefVisitor)
Auto Trait Implementations§
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, Global>) -> Box<dyn Any, Global>
fn into_any(self: Box<T, Global>) -> Box<dyn Any, Global>
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, Global>) -> Rc<dyn Any, Global>
fn into_any_rc(self: Rc<T, Global>) -> Rc<dyn Any, Global>
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.