Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 18 additions & 1 deletion kinematics/src/hand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,9 @@ impl Tracker {
}
}

if in_band.len() < self.config.min_zones {
// The band must hold at least one zone whatever `min_zones` says: at 0 the length
// check passes on an empty band, and the percentile index below would panic on it.
if in_band.len() < self.config.min_zones.max(1) {
// Hold the last hand briefly. This is the whole anti-chop mechanism: the note
// rides over a dropout, and stops when one lasts.
return match self.last {
Expand Down Expand Up @@ -318,6 +320,21 @@ mod tests {
assert!(tracker.track(&distance, &status, Instant::now()).is_some());
}

/// `min_zones = 0` is a legal config, and an empty band then passes the length check —
/// straight into a percentile index that has nothing to index. No zones is no hand,
/// whatever the floor is.
#[test]
fn an_empty_band_is_not_a_hand_even_with_min_zones_zero() {
let mut tracker = Tracker::new(Config {
min_zones: 0,
..Config::default()
});
assert_eq!(tracker.track(&[], &[], Instant::now()), None);
// But a single usable zone still is one: the floor is on emptiness, not on count.
let (distance, status) = frame(0.25, 5, 1);
assert!(tracker.track(&distance, &status, Instant::now()).is_some());
}

/// A negative distance under a believed status is a failed convergence, and a frame
/// shorter than the grid must not panic or read past its end — the wire carries vectors,
/// and a peer from another release can send fewer.
Expand Down
Loading