From dd2de9ee14ed90bdbb6b3ecb2f718c0248733f92 Mon Sep 17 00:00:00 2001 From: Adrien Burgun Date: Tue, 21 Jun 2022 06:16:39 +0200 Subject: [PATCH] :chart: Remove unnecessary `Rc` in `FullTile` --- stackline/src/context.rs | 21 ++++++++------------- stackline/src/lib.rs | 1 - stackline/src/pane.rs | 18 ++++++++---------- stackline/src/tile/mod.rs | 21 +++++++++------------ stackline/src/tile/wire.rs | 4 ++-- 5 files changed, 27 insertions(+), 38 deletions(-) diff --git a/stackline/src/context.rs b/stackline/src/context.rs index 43cb646..d0d90d1 100644 --- a/stackline/src/context.rs +++ b/stackline/src/context.rs @@ -1,5 +1,4 @@ use std::marker::PhantomData; -use std::rc::Rc; use super::*; /** An `UpdateContext` is created for every tile update during the "update" phase, @@ -48,7 +47,7 @@ impl Tile for MyTile { ctx.next_state(); // Become dormant } # -# fn transmit<'b>(&'b self, signal: std::rc::Rc, ctx: TransmitContext<'b>) {} +# fn transmit<'b>(&'b self, signal: Signal, ctx: TransmitContext<'b>) {} } ``` @@ -90,7 +89,7 @@ impl<'a> UpdateContext<'a> { /// Returns the [signal](crate::FullTile::signal) of the currently updated tile. #[inline] - pub fn signal<'b>(&'b self) -> Option<&'b Rc> where 'a: 'b { + pub fn signal<'b>(&'b self) -> Option<&'b Signal> where 'a: 'b { let pane = unsafe { self.pane() }; // SAFETY: `pane[position].signal` is not borrowed mutably @@ -170,7 +169,7 @@ pub struct TransmitContext<'a> { } impl<'a> TransmitContext<'a> { - pub(crate) fn new(pane: &'a mut Pane, position: (usize, usize)) -> Option<(Self, &'a AnyTile, Rc)> { + pub(crate) fn new(pane: &'a mut Pane, position: (usize, usize)) -> Option<(Self, &'a AnyTile, Signal)> { let ptr: *mut Pane = &mut *pane; // SAFETY: no mutable accesses to `∀x, pane[x].cell` are made by `TransmitContext` let tile: &AnyTile = unsafe { @@ -240,22 +239,18 @@ impl<'a> TransmitContext<'a> { /// Returns true if the signal was stored in a cell, false otherwise. /// The target cell's state will be set to `Active` if it received the signal. /// The signal's `position` will be set to `pos`. - pub fn send<'b>(&'b mut self, pos: (usize, usize), mut signal: Signal) -> Option> where 'a: 'b { + pub fn send<'b>(&'b mut self, pos: (usize, usize), mut signal: Signal) -> Option<()> where 'a: 'b { // SAFETY: we do not return any reference to any data borrowed in this function // SAFETY: we only access `pane[pos].signal`, `pane[pos].state` and `pane.signals` let pane = unsafe { self.pane_mut() }; signal.set_position(pos); - match pane.set_signal(pos, signal) { - Some(signal) => { - // SAFETY: we only access `pane[pos].state` - pane.get_mut(pos).unwrap_or_else(|| unreachable!()).set_state(State::Active); + pane.set_signal(pos, signal)?; + // SAFETY: we only access `pane[pos].state` + pane.get_mut(pos).unwrap_or_else(|| unreachable!()).set_state(State::Active); - Some(signal) - } - None => None - } + Some(()) } /// Returns `Some((position.x + Δx, position.y + Δy))` iff `(x + Δx, y + Δy)` is inside the pane diff --git a/stackline/src/lib.rs b/stackline/src/lib.rs index 7297f44..b1af5b9 100644 --- a/stackline/src/lib.rs +++ b/stackline/src/lib.rs @@ -1,5 +1,4 @@ use std::num::NonZeroUsize; -use std::rc::Weak; mod signal; pub use signal::*; diff --git a/stackline/src/pane.rs b/stackline/src/pane.rs index c45f846..62d3a36 100644 --- a/stackline/src/pane.rs +++ b/stackline/src/pane.rs @@ -6,7 +6,7 @@ pub struct Pane { width: NonZeroUsize, height: NonZeroUsize, - signals: Vec>, + signals: Vec<(usize, usize)>, } impl Pane { @@ -71,10 +71,11 @@ impl Pane { /// - the tile accepts a signal (ie. it isn't empty) // SAFETY: may only access `self[pos].signal` and `self.signals` #[inline] - pub fn set_signal(&mut self, position: (usize, usize), signal: Signal) -> Option> { - let signal = self.get_mut(position)?.set_signal(signal)?; - self.signals.push(signal.clone()); - Some(signal) + pub fn set_signal(&mut self, position: (usize, usize), mut signal: Signal) -> Option<()> { + signal.set_position(position); + self.get_mut(position)?.set_signal(signal)?; + self.signals.push(position); + Some(()) } #[inline] @@ -116,11 +117,8 @@ impl Pane { /// Calls [`Pane::transmit`] on all tiles with a signal fn transmit_all(&mut self) { // TODO: store a second buffer and perform swap reads - for signal in std::mem::replace(&mut self.signals, vec![]) { - if let Some(upgraded) = signal.upgrade() { - let position = upgraded.position(); - let _ = self.transmit(position); // May return None if the signal was aliased - } + for position in std::mem::replace(&mut self.signals, vec![]) { + let _ = self.transmit(position); // May return None if the signal was aliased } } diff --git a/stackline/src/tile/mod.rs b/stackline/src/tile/mod.rs index ecdc80e..a8423d5 100644 --- a/stackline/src/tile/mod.rs +++ b/stackline/src/tile/mod.rs @@ -1,6 +1,5 @@ use super::*; use dyn_clone::{clone_box, DynClone}; -use std::rc::Rc; mod wire; pub use wire::*; @@ -17,7 +16,7 @@ Cloning a `FullTile` results in a `FullTile` that does not have any signal. #[derive(Clone, Debug)] pub struct FullTile { cell: Option, - signal: Option>, + signal: Option, state: State, } @@ -40,12 +39,10 @@ impl FullTile { } /// Returns Some(signal) iff self.cell.is_some() - pub(crate) fn set_signal(&mut self, signal: Signal) -> Option> { + pub(crate) fn set_signal(&mut self, signal: Signal) -> Option<()> { if self.cell.is_some() { - let rc = Rc::new(signal); - let weak = Rc::downgrade(&rc); - self.signal = Some(rc); - Some(weak) + self.signal = Some(signal); + Some(()) } else { None } @@ -65,12 +62,12 @@ impl FullTile { /// Returns the signal of this tile #[inline] - pub fn signal<'b>(&'b self) -> Option<&'b Rc> { + pub fn signal<'b>(&'b self) -> Option<&'b Signal> { self.signal.as_ref() } #[inline] - pub fn take_signal(&mut self) -> Option> { + pub fn take_signal(&mut self) -> Option { std::mem::take(&mut self.signal) } @@ -91,7 +88,7 @@ impl FullTile { self.state = self.state.next(); } - pub fn into_raw_mut<'b>(&'b mut self) -> (&'b mut Option, &'b mut Option>, &'b mut State) { + pub fn into_raw_mut<'b>(&'b mut self) -> (&'b mut Option, &'b mut Option, &'b mut State) { (&mut self.cell, &mut self.signal, &mut self.state) } } @@ -126,7 +123,7 @@ pub trait Tile: DynClone + std::fmt::Debug { } /// Function that will be called if the tile has a signal. - fn transmit<'b>(&'b self, signal: Rc, context: TransmitContext<'b>); + fn transmit<'b>(&'b self, signal: Signal, context: TransmitContext<'b>); /// Should return true iff the tile accepts a signal travelling in `Direction` #[inline] @@ -151,7 +148,7 @@ impl AnyTile { } #[inline] - pub fn transmit<'b>(&'b self, signal: Rc, context: TransmitContext<'b>) { + pub fn transmit<'b>(&'b self, signal: Signal, context: TransmitContext<'b>) { self.0.transmit(signal, context) } diff --git a/stackline/src/tile/wire.rs b/stackline/src/tile/wire.rs index 6823f7b..1390ab0 100644 --- a/stackline/src/tile/wire.rs +++ b/stackline/src/tile/wire.rs @@ -12,7 +12,7 @@ impl Wire { } impl Tile for Wire { - fn transmit<'b>(&'b self, signal: Rc, mut context: TransmitContext<'b>) { + fn transmit<'b>(&'b self, signal: Signal, mut context: TransmitContext<'b>) { for &direction in self.0.into_directions() { if direction == signal.direction().opposite() { continue; @@ -41,7 +41,7 @@ impl Diode { } impl Tile for Diode { - fn transmit<'b>(&'b self, signal: Rc, mut context: TransmitContext<'b>) { + fn transmit<'b>(&'b self, signal: Signal, mut context: TransmitContext<'b>) { // Block signals coming from where the diode is looking if signal.direction().opposite() == self.0 { return;