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.