1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
use std::{future::Future, rc::Rc};
use derivative::Derivative;
use crate::{
events::{self, EventSource},
Serial,
};
pub mod traits;
use traits::GlobalsUpdate;
#[derive(Derivative)]
#[derivative(Debug(bound = ""))]
pub struct GlobalStore<G> {
globals: crate::IdAlloc<Rc<G>>,
update_event: events::broadcast::Broadcast<GlobalsUpdate<G>>,
}
impl<G> FromIterator<G> for GlobalStore<G> {
fn from_iter<T: IntoIterator<Item = G>>(iter: T) -> Self {
let mut id_alloc = crate::IdAlloc::default();
for global in iter.into_iter() {
id_alloc.next_serial(Rc::new(global));
}
GlobalStore {
globals: id_alloc,
update_event: Default::default(),
}
}
}
impl<G: 'static> EventSource<GlobalsUpdate<G>> for GlobalStore<G> {
type Source =
<events::broadcast::Broadcast<GlobalsUpdate<G>> as EventSource<GlobalsUpdate<G>>>::Source;
fn subscribe(&self) -> Self::Source {
self.update_event.subscribe()
}
}
impl<G: 'static> traits::GlobalStore<G> for GlobalStore<G> {
type Iter<'a> = <&'a Self as IntoIterator>::IntoIter where Self: 'a, G: 'a;
type InsertFut<'a, I> = impl Future<Output = u32> + 'a where Self: 'a, I: 'a + Into<G>;
type RemoveFut<'a> = impl Future<Output = bool> + 'a where Self: 'a;
fn insert<'a, I: Into<G> + 'a>(&'a mut self, global: I) -> Self::InsertFut<'_, I> {
let global = Rc::new(global.into());
let id = self.globals.next_serial(global.clone());
async move {
self.update_event
.broadcast(GlobalsUpdate::Added(id, global))
.await;
id
}
}
fn get(&self, id: u32) -> Option<&Rc<G>> {
self.globals.get(id)
}
fn remove(&mut self, id: u32) -> Self::RemoveFut<'_> {
let removed = self.globals.expire(id);
async move {
if removed {
self.update_event
.broadcast(GlobalsUpdate::Removed(id))
.await;
}
removed
}
}
fn iter(&self) -> Self::Iter<'_> {
self.into_iter()
}
}
impl<'a, G> IntoIterator for &'a GlobalStore<G> {
type IntoIter = crate::IdIter<'a, Rc<G>>;
type Item = (u32, &'a Rc<G>);
fn into_iter(self) -> Self::IntoIter {
self.globals.iter()
}
}