obkrnl/event/
mod.rs

1pub use self::ty::*;
2
3use crate::lock::{Mutex, MutexGuard};
4use alloc::collections::btree_map::BTreeMap;
5
6mod ty;
7
8/// Encapsulate a set of [`Event`].
9///
10/// Usually there are only one [`EventSet`] per subsystem. The purpose of this struct is to prevent
11/// race condition during subscribing and triggering multiple events. In other words, this struct
12/// provide atomicity for subscription to multiple events in the set.
13pub struct EventSet<S>(Mutex<S>); // TODO: Change to RwLock.
14
15impl<S> EventSet<S> {
16    pub fn trigger(&self) -> EventTrigger<S> {
17        EventTrigger(self.0.lock())
18    }
19}
20
21impl<S: Default> Default for EventSet<S> {
22    fn default() -> Self {
23        Self(Mutex::default())
24    }
25}
26
27/// Implementation of `eventhandler_list` structure.
28///
29/// Our implementation is different from PS4 version to make it idomatic to Rust.
30pub struct Event<T: EventType> {
31    subscribers: BTreeMap<(u32, u64), T::Wrapper>, // el_entries
32}
33
34impl<T: EventType> Default for Event<T> {
35    fn default() -> Self {
36        Self {
37            subscribers: BTreeMap::new(),
38        }
39    }
40}
41
42/// Struct to trigger one or more events.
43///
44/// It is guarantee that no other handler in the current set will get registered until this struct
45/// has been dropped.
46pub struct EventTrigger<'a, S>(MutexGuard<'a, S>);
47
48impl<S> EventTrigger<'_, S> {
49    pub fn select<E, T>(&mut self, event: E) -> impl Iterator<Item = &T::Wrapper>
50    where
51        E: FnOnce(&S) -> &Event<T>,
52        T: EventType,
53    {
54        event(&self.0).subscribers.values()
55    }
56}