calloop/
list.rs

1use std::rc::Rc;
2
3use crate::sources::EventDispatcher;
4use crate::token::TokenInner;
5
6pub(crate) struct SourceEntry<'l, Data> {
7    pub(crate) token: TokenInner,
8    pub(crate) source: Option<Rc<dyn EventDispatcher<Data> + 'l>>,
9}
10
11pub(crate) struct SourceList<'l, Data> {
12    sources: Vec<SourceEntry<'l, Data>>,
13}
14
15impl<'l, Data> SourceList<'l, Data> {
16    pub(crate) fn new() -> Self {
17        SourceList {
18            sources: Vec::new(),
19        }
20    }
21
22    pub(crate) fn vacant_entry(&mut self) -> &mut SourceEntry<'l, Data> {
23        let opt_id = self.sources.iter().position(|slot| slot.source.is_none());
24        match opt_id {
25            Some(id) => {
26                // we are reusing a slot
27                let slot = &mut self.sources[id];
28                // increment the slot version
29                slot.token = slot.token.increment_version();
30                slot
31            }
32            None => {
33                // we are inserting a new slot
34                let next_id = self.sources.len();
35                self.sources.push(SourceEntry {
36                    token: TokenInner::new(self.sources.len())
37                        .expect("Trying to insert too many sources in an event loop."),
38                    source: None,
39                });
40                &mut self.sources[next_id]
41            }
42        }
43    }
44
45    pub(crate) fn get(&self, token: TokenInner) -> crate::Result<&SourceEntry<'l, Data>> {
46        let entry = self
47            .sources
48            .get(token.get_id())
49            .ok_or(crate::Error::InvalidToken)?;
50        if entry.token.same_source_as(token) {
51            Ok(entry)
52        } else {
53            Err(crate::Error::InvalidToken)
54        }
55    }
56
57    pub(crate) fn get_mut(
58        &mut self,
59        token: TokenInner,
60    ) -> crate::Result<&mut SourceEntry<'l, Data>> {
61        let entry = self
62            .sources
63            .get_mut(token.get_id())
64            .ok_or(crate::Error::InvalidToken)?;
65        if entry.token.same_source_as(token) {
66            Ok(entry)
67        } else {
68            Err(crate::Error::InvalidToken)
69        }
70    }
71}