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}
72