pub struct Block(/* private fields */);Expand description
A Block is something that can exist in the grid of a Space; it occupies one
unit cube of simulated physical space, and has a specified appearance and behavior.
A Block is made up of a Primitive and zero or more Modifiers.
In general, when a block appears multiple times from an in-game perspective, that may
or may not be the the same copy; Blocks are “by value” and any block Eq to
another will behave identically and should be treated identically. However, some
blocks are defined by reference to shared mutable data, and Block containers such
as Space must follow those changes.
To determine the concrete appearance and behavior of a block, use Block::evaluate()
or Block::evaluate_and_listen(), which will return an EvaluatedBlock value.
Additional operations for manipulating the block are available on EvaluatedBlock.
§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 Block
impl Block
Sourcepub const fn builder<'u>() -> Builder<'u, NeedsPrimitive, ()>
pub const fn builder<'u>() -> Builder<'u, NeedsPrimitive, ()>
Sourcepub fn from_primitive(p: Primitive) -> Self
pub fn from_primitive(p: Primitive) -> Self
Sourcepub fn primitive_mut(&mut self) -> &mut Primitive
pub fn primitive_mut(&mut self) -> &mut Primitive
Sourcepub fn modifiers(&self) -> &[Modifier]
pub fn modifiers(&self) -> &[Modifier]
Returns all the modifiers of this block.
Modifiers are arranged in order of their application to the primitive, or “innermost” to “outermost”.
Note that this does not necessarily return all modifiers involved in its
definition; modifiers on the far end of a Primitive::Indirect are
not reported here, even though they take effect when evaluated.
Sourcepub fn modifiers_mut(&mut self) -> &mut Vec<Modifier>
pub fn modifiers_mut(&mut self) -> &mut Vec<Modifier>
Returns a mutable reference to the vector of Modifiers on this block.
This may cause part or all of the block’s data to stop sharing storage with other blocks.
Sourcepub fn with_modifier(self, modifier: impl Into<Modifier>) -> Self
pub fn with_modifier(self, modifier: impl Into<Modifier>) -> Self
Add the given modifier to this block.
This is a convenience operation which is exactly equivalent to
doing block.modifiers_mut().push(modifier.into()). It does not do any of the
special case logic that, for example, Block::rotate() does.
Sourcepub fn rotate(self, rotation: GridRotation) -> Self
pub fn rotate(self, rotation: GridRotation) -> Self
Rotates this block by the specified rotation.
Compared to direct use of Modifier::Rotate, this will:
- Avoid constructing chains of redundant modifiers.
- Not rotate blocks that should never appear rotated (including atom blocks).
(TODO: This should be replaced with with_modifier() or similar having a general
rule set for combining modifiers.)
use all_is_cubes::block;
use all_is_cubes::content::make_some_voxel_blocks;
use all_is_cubes::math::{Face6, Rgba};
use all_is_cubes::universe::Universe;
let mut universe = Universe::new();
let [mut block] = make_some_voxel_blocks(&mut universe);
block.modifiers_mut().clear();
let clockwise = Face6::PY.clockwise();
// Basic rotation
let rotated = block.clone().rotate(clockwise);
assert_eq!(rotated.modifiers(), &[block::Modifier::Rotate(clockwise)]);
// Multiple rotations are combined
let double = rotated.clone().rotate(clockwise);
assert_eq!(double.modifiers(), &[block::Modifier::Rotate(clockwise * clockwise)]);
// Atoms and AIR are never rotated
let atom = block::from_color!(Rgba::WHITE);
assert_eq!(atom.clone().rotate(clockwise), atom);
assert_eq!(block::AIR.rotate(clockwise), block::AIR);Sourcepub fn unspecialize(&self) -> Vec<Block>
pub fn unspecialize(&self) -> Vec<Block>
Standardizes any characteristics of this block which may be presumed to be specific to its usage in its current location, so that it can be used elsewhere or compared with others. Specifically, it has the following effects:
- Removes
Modifier::Rotate. - Splits some
Modifier::Compositeinto their parts.
In future versions there may be additional changes or ones customizable per block.
§Examples
Removing rotation:
use all_is_cubes::block::Block;
use all_is_cubes::math::Face6;
use all_is_cubes::universe::Universe;
let mut universe = Universe::new();
let [block] = make_some_voxel_blocks(&mut universe);
let rotated = block.clone().rotate(Face6::PY.clockwise());
assert_ne!(&block, &rotated);
assert_eq!(vec![block], rotated.clone().unspecialize());Sourcepub fn find_inventory(&self) -> Option<(usize, &Inventory)>
pub fn find_inventory(&self) -> Option<(usize, &Inventory)>
If this block has an inventory, return it and its modifier index.
Sourcepub fn evaluate(
&self,
read_ticket: ReadTicket<'_>,
) -> Result<EvaluatedBlock, EvalBlockError>
pub fn evaluate( &self, read_ticket: ReadTicket<'_>, ) -> Result<EvaluatedBlock, EvalBlockError>
Converts this Block into a “flattened” and snapshotted form which contains all
information needed for rendering and physics, and does not require Handle access
to other objects.
Sourcepub fn evaluate_and_listen(
&self,
read_ticket: ReadTicket<'_>,
listener: impl IntoListener<DynListener<BlockChange>, BlockChange>,
) -> Result<EvaluatedBlock, EvalBlockError>
pub fn evaluate_and_listen( &self, read_ticket: ReadTicket<'_>, listener: impl IntoListener<DynListener<BlockChange>, BlockChange>, ) -> Result<EvaluatedBlock, EvalBlockError>
As Block::evaluate(), but also installs a listener which will be notified of
changes in all data sources that might affect the evaluation result.
Note that this does not listen for mutations of the Block value itself, in the
sense that none of the methods on Block will cause this listener to fire.
Rather, it listens for changes in by-reference-to-interior-mutable-data sources
such as the Space referred to by a Primitive::Recur or the BlockDef
referred to by a Primitive::Indirect.
§Errors
If an evaluation error is reported, the Listener may have been installed
incompletely or not at all. It should not be relied on.
Sourcepub fn color(&self) -> Rgba
pub fn color(&self) -> Rgba
Returns the single Rgba color of this block’s Primitive::Atom or
Primitive::Air, or panics if it has a different kind of primitive.
Intended for use in tests only.
Trait Implementations§
Source§impl<'a> Arbitrary<'a> for Block
impl<'a> Arbitrary<'a> for Block
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 size_hint(_depth: usize) -> (usize, Option<usize>)
fn size_hint(_depth: usize) -> (usize, Option<usize>)
Unstructured this type
needs to construct itself. 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§fn try_size_hint(
depth: usize,
) -> Result<(usize, Option<usize>), MaxRecursionReached>
fn try_size_hint( depth: usize, ) -> Result<(usize, Option<usize>), MaxRecursionReached>
Unstructured this type
needs to construct itself. Read moreSource§impl<'de> Deserialize<'de> for Block
impl<'de> Deserialize<'de> for Block
Source§fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
Source§impl<C: BuildPrimitive> From<Builder<'_, C, ()>> for Block
Allows implicitly converting Builder to the block it would build.
impl<C: BuildPrimitive> From<Builder<'_, C, ()>> for Block
Allows implicitly converting Builder to the block it would build.
Source§impl From<Handle<BlockDef>> for Block
impl From<Handle<BlockDef>> for Block
Source§fn from(block_def_handle: Handle<BlockDef>) -> Self
fn from(block_def_handle: Handle<BlockDef>) -> Self
Convert a Handle<BlockDef> into a block with Primitive::Indirect that refers to it.
The returned block will evaluate to the same EvaluatedBlock as the block contained
within the given BlockDef (except in case of errors).
Source§impl VisitHandles for Block
impl VisitHandles for Block
Source§fn visit_handles(&self, visitor: &mut dyn HandleVisitor)
fn visit_handles(&self, visitor: &mut dyn HandleVisitor)
Source§impl<'a> VoxelColor<'a> for &'a Block
impl<'a> VoxelColor<'a> for &'a Block
Source§fn into_blocks(self) -> VoxelBrush<'a>
fn into_blocks(self) -> VoxelBrush<'a>
VoxelBrush, the most general form of blocky drawing.impl Eq for Block
Auto Trait Implementations§
impl Freeze for Block
impl RefUnwindSafe for Block
impl Send for Block
impl Sync for Block
impl Unpin for Block
impl UnwindSafe for Block
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
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