Skip to main content

NeedsBus

Struct NeedsBus 

Source
pub struct NeedsBus { /* private fields */ }
Expand description

Proof that a step needs the bus, produced only by Audio::tick_without_bus and consumed only by Audio::tick_with_bus.

The two halves exist for a caller that cannot lend this struct out without first moving it, and so needs to know whether the step will touch RDRAM before paying for the move. At a typical ~32 kHz that is about one step in 1,950. (In this workspace that caller is the Bus, which owns every chip.)

The fields are private and the type has no constructor, so it cannot be forged. It carries the DAC period as well as the proof, which keeps the 64-bit divide that produced it from being repeated in the second half.

Copy and Clone are deliberately not derived, and it is taken by value: either would let a caller keep a token past the step it authorized and present it again once next_sample_tick had moved on. Debug is derived because it cannot duplicate the value.

Dropping a token loses the samples that were due, unlike the RDP’s equivalent: tick_without_bus has already stamped last_tick, and the while in the second half is what advances next_sample_tick, so a dropped token leaves those samples unemitted and the schedule behind now — the next call then emits them late in a burst.

What makes ignoring one loud is the #[must_use] on Audio::tick_without_bus itself, not the one on this type: an attribute on T does not propagate through Option<T>, and Option — unlike Result — is not #[must_use] either.

The attribute here is dormant, and kept only for the day the return type is not wrapped — it does not catch a caller who binds the token and drops it. That was proposed in review and probed rather than assumed: with if let Some(_proof) = ai.tick_without_bus(1) {}, cargo clippy --all-targets reports zero warnings both with and without it. A type-level #[must_use] fires on an unused expression, not on a binding; a bound-then-dropped value is unused_variables, which the leading underscore silences either way.

Trait Implementations§

Source§

impl Debug for NeedsBus

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.