📝 Document context.rs a bit

main
Shad Amethyst 2 years ago
parent 4b60d13943
commit d61650316a
Signed by: amethyst
GPG Key ID: D970C8DD1D6DEE36

@ -2,16 +2,57 @@ use std::marker::PhantomData;
use std::rc::Rc;
use super::*;
/// An UpdateContext is created for every tile update during the "update" phase,
/// and it contains the necessary data for a tile to update its internal state.
///
/// During the update phase, a tile may only access itself mutably, through the mutable
/// reference it was initially passed through its [`update`](Tile::update) method.
/// All accesses to other tiles and all signals must be done immutably.
///
/// It thus *cannot* access itself through this context structure, although it may read its
/// signal here.
/// It *can* access the other tiles and their signals immutably.
/** An `UpdateContext` is created for every tile update during the "update" phase,
and it contains the necessary data for a tile to update its internal state.
During the update phase, a tile may only access itself mutably, through the mutable
reference it was initially passed through its [`update`](Tile::update) method.
All accesses to other tiles and all signals must be done immutably.
It thus *cannot* access itself through this context structure, although it may read its
signal here.
It *can* access the other tiles and their signals immutably.
## Examples
This type is most commonly found when implementing [`Tile::update`]:
```
# use stackline::{*, tile::Tile, utils::State, context::*};
#
#[derive(Clone, Debug)]
struct MyTile(u8);
impl Tile for MyTile {
fn update<'b>(&'b mut self, ctx: UpdateContext<'b>) {
// Counts the number of active neighbors
let mut active_neighbors = 0;
for dy in -1..1 {
for dx in -1..1 {
let offset = (dx, dy);
if offset == (0, 0) {
continue;
}
// Get tile next to us:
if let Some((_position, tile)) = ctx.get_offset(offset) {
if tile.state() == State::Active {
active_neighbors += 1;
}
}
}
}
self.0 = active_neighbors;
ctx.next_state(); // Go dormant
}
#
# fn transmit<'b>(&'b self, signal: std::rc::Rc<Signal>, ctx: TransmitContext<'b>) {}
}
```
**/
// SAFETY: `pane[position].cell` is borrow mutably, while a pointer to the original Pane is kept;
// thus, no other reference to `pane[position].cell` may be done
@ -24,6 +65,7 @@ pub struct UpdateContext<'a> {
}
impl<'a> UpdateContext<'a> {
/// Creates a new context, returning the only mutable reference to `pane[position].cell` and the `UpdateContext`.
#[inline]
pub(crate) fn new(pane: &'a mut Pane, position: (usize, usize)) -> Option<(Self, &'a mut AnyTile)> {
@ -40,11 +82,13 @@ impl<'a> UpdateContext<'a> {
Some((res, tile.as_mut()?))
}
/// Returns the position of the currently updated tile.
#[inline]
pub fn position(&self) -> (usize, usize) {
self.position
}
/// Returns the [signal](crate::FullTile::signal) of the currently updated tile.
#[inline]
pub fn signal<'b>(&'b self) -> Option<&'b Rc<Signal>> where 'a: 'b {
let pane = unsafe { self.pane() };
@ -53,16 +97,19 @@ impl<'a> UpdateContext<'a> {
pane.get(self.position).unwrap().signal()
}
/// Returns the state of the current tile.
#[inline]
pub fn state(&self) -> State {
*self.state
}
/// Sets the state of the current tile to `state`.
#[inline]
pub fn set_state(&mut self, state: State) {
*self.state = state;
}
/// Sets the state of the current tile to `state.next()`
#[inline]
pub fn next_state(&mut self) {
*self.state = self.state.next();
@ -110,8 +157,8 @@ impl<'a> UpdateContext<'a> {
/// and it contains the necessary data for a tile to transmit its internal signal to other tiles.
///
/// During this phase, the tile may access itself through an immutable borrow and its signal through an owned reference.
/// It may access the other tiles immutably, but it cannot access the other signals.
/// It can read and modify any tile's state.
/// It *can* access the other tiles immutably, but it *cannot* access the other signals.
/// It *can* read and modify any tile's state.
// SAFETY: this structures ensures that it has exlusive, mutable access to `∀x, pane[x].signal, pane[x].state` and `pane.signals`.
// Other parts of `pane` may be accessed and returned immutably.
@ -141,6 +188,7 @@ impl<'a> TransmitContext<'a> {
Some((res, tile, signal))
}
/// Returns the position of the current tile
#[inline]
pub fn position(&self) -> (usize, usize) {
self.position

@ -130,7 +130,7 @@ pub trait Tile: DynClone + std::fmt::Debug {
/// Should return true iff the tile accepts a signal travelling in `Direction`
#[inline]
fn accepts_signal(&self, _direction: Direction) -> bool {
fn accepts_signal(&self, direction: Direction) -> bool {
true
}
}

@ -1,4 +1,5 @@
/// Represents one or many undirected orientation(s), since we are in a 2D grid, this may either be [Horizontal], [Vertical] or both ([Any])
/// Represents one or many undirected orientation(s), since we are in a 2D grid,
/// this may either be [Horizontal](Orientation::Horizontal), [Vertical](Orientation::Vertical) or both ([Any](Orientation::Any))
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum Orientation {
@ -18,7 +19,7 @@ pub enum Direction {
}
/// Represents the state that a cell may be in. The usual state transition schema is `Idle → Active → Dormant → Idle`.
/// A tile will only be [`update`d](Tile::update) if it is in the `Active` or `Dormant` state.
/// A tile will only be [`update`d](crate::Tile::update) if it is in the `Active` or `Dormant` state.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum State {
@ -62,7 +63,7 @@ impl Orientation {
}
impl Direction {
/// Converts a [Direction] in a pair `(Δx, Δy)`, with [Up] being equal to `(0, -1)`
/// Converts a [Direction] in a pair `(Δx, Δy)`, with [Up](Direction::Up) being equal to `(0, -1)`
#[inline]
pub fn into_offset(self) -> (i8, i8) {
match self {

Loading…
Cancel
Save