1use crate::Range;
2
3pub struct IndexEmitter<'a> {
22 range: Range,
23 last: Option<usize>,
24 emit: &'a mut dyn FnMut(usize),
25}
26
27impl<'a> IndexEmitter<'a> {
28 pub fn new(range: Range, emit: &'a mut dyn FnMut(usize)) -> Self {
29 Self {
30 range,
31 last: None,
32 emit,
33 }
34 }
35
36 pub fn range(&self) -> Range {
37 self.range
38 }
39
40 pub fn emit(&mut self, index: usize) {
41 if index >= self.range.count {
42 vwarn!(
43 index,
44 count = self.range.count,
45 "IndexEmitter: out-of-bounds index"
46 );
47 debug_assert!(
48 index < self.range.count,
49 "IndexEmitter: out-of-bounds index (i={index}, count={})",
50 self.range.count
51 );
52 return;
53 }
54
55 if let Some(prev) = self.last {
56 if index == prev {
57 return;
58 }
59 if index < prev {
60 vwarn!(
61 prev,
62 next = index,
63 "IndexEmitter: indexes must be emitted in ascending order"
64 );
65 debug_assert!(
66 index > prev,
67 "IndexEmitter: indexes must be emitted in ascending order (prev={prev}, next={index})"
68 );
69 return;
70 }
71 }
72
73 self.last = Some(index);
74 (self.emit)(index);
75 }
76
77 pub fn emit_pinned(&mut self, index: usize) {
78 self.emit(index);
79 }
80
81 pub fn emit_range(&mut self, start_index: usize, end_index: usize) {
82 let end = end_index.min(self.range.count);
83 for i in start_index..end {
84 self.emit(i);
85 }
86 }
87
88 pub fn emit_visible(&mut self) {
89 self.emit_range(self.range.start_index, self.range.end_index);
90 }
91
92 pub fn emit_overscanned(&mut self) {
93 let start = self.range.start_index.saturating_sub(self.range.overscan);
94 let end = self
95 .range
96 .end_index
97 .saturating_add(self.range.overscan)
98 .min(self.range.count);
99 self.emit_range(start, end);
100 }
101}