async_ui_web_core/combinators/utils/wakers/array/
readiness.rs1use async_ui_internal_utils::dummy_waker::dummy_waker;
2
3use core::task::Waker;
4
5pub(crate) struct ReadinessArray<const N: usize> {
6 awake_set: [bool; N],
8 awake_list: [usize; N],
10 awake_list_len: usize,
14 parent_waker: Waker,
15}
16
17impl<const N: usize> ReadinessArray<N> {
18 pub(crate) fn new() -> Self {
19 Self {
20 awake_set: [true; N],
21 awake_list: core::array::from_fn(core::convert::identity),
22 awake_list_len: N,
23 parent_waker: dummy_waker(), }
25 }
26 pub(crate) fn set_parent_waker(&mut self, waker: &Waker) {
27 if !self.parent_waker.will_wake(waker) {
29 self.parent_waker = waker.to_owned();
30 }
31 }
32 fn set_woken(&mut self, index: usize) -> bool {
33 let was_awake = std::mem::replace(&mut self.awake_set[index], true);
34 if !was_awake {
35 self.awake_list[self.awake_list_len] = index;
36 self.awake_list_len += 1;
37 }
38 was_awake
39 }
40 pub(crate) fn wake(&mut self, index: usize) {
41 if !self.set_woken(index) && self.awake_list_len == 1 {
42 self.parent_waker.wake_by_ref();
43 }
44 }
45 pub(crate) fn awake_list(&self) -> &[usize] {
46 &self.awake_list[..self.awake_list_len]
47 }
48 const TRESHOLD: usize = N / 64;
49 pub(crate) fn clear(&mut self) {
50 if self.awake_list_len < Self::TRESHOLD {
54 self.awake_set.fill(false);
55 } else {
56 let awake_set = &mut self.awake_set;
57 self.awake_list.iter().for_each(|&idx| {
58 awake_set[idx] = false;
59 });
60 }
61 self.awake_list_len = 0;
62 }
63}