cyfs_util/util/
event.rs

1use cyfs_base::BuckyResult;
2use async_std::prelude::*;
3use async_trait::async_trait;
4
5use std::sync::{Arc, Mutex};
6
7#[async_trait]
8pub trait EventListenerAsyncRoutine<P, R>: Send + Sync + 'static
9where
10    P: Send + Sync + 'static,
11    R: 'static,
12{
13    async fn call(&self, param: &P) -> BuckyResult<R>;
14}
15
16#[async_trait]
17impl<F, Fut, P, R> EventListenerAsyncRoutine<P, R> for F
18where
19    P: Send + Sync + 'static,
20    R: 'static,
21    F: Send + Sync + 'static + Fn(&P) -> Fut,
22    Fut: Future<Output = BuckyResult<R>> + Send + 'static,
23{
24    async fn call(&self, param: &P) -> BuckyResult<R> {
25        (self)(param).await
26    }
27}
28
29#[async_trait]
30pub trait EventListenerSyncRoutine<P, R>: Send + Sync + 'static
31where
32    P: Send + Sync + 'static,
33    R: 'static,
34{
35    fn call(&self, param: &P) -> BuckyResult<R>;
36}
37
38#[async_trait]
39impl<F, P, R> EventListenerSyncRoutine<P, R> for F
40where
41    P: Send + Sync + 'static,
42    R: 'static,
43    F: Send + Sync + 'static + Fn(&P) -> BuckyResult<R>,
44{
45    fn call(&self, param: &P) -> BuckyResult<R> {
46        (self)(param)
47    }
48}
49
50pub struct SyncEventManager<P, R>
51where
52    P: Send + Sync + 'static,
53    R: 'static,
54{
55    next_cookie: u32,
56    listeners: Vec<(u32, Box<dyn EventListenerSyncRoutine<P, R>>)>,
57}
58
59impl<P, R> SyncEventManager<P, R>
60where
61    P: Send + Sync + 'static,
62    R: 'static,
63{
64    pub fn new() -> Self {
65        Self {
66            next_cookie: 1,
67            listeners: Vec::new(),
68        }
69    }
70
71    pub fn listener_count(&self) -> usize {
72        self.listeners.len()
73    }
74
75    pub fn is_empty(&self) -> bool {
76        self.listeners.is_empty()
77    }
78
79    pub fn on(&mut self, listener: Box<dyn EventListenerSyncRoutine<P, R>>) -> u32 {
80        let cookie = self.next_cookie;
81        self.next_cookie += 1;
82        if self.next_cookie == u32::MAX {
83            self.next_cookie = 1;
84        }
85
86        self.listeners.push((cookie, listener));
87
88        cookie
89    }
90
91    pub fn off(&mut self, cookie: u32) -> bool {
92        let ret = self.listeners.iter().enumerate().find(|v| v.1 .0 == cookie);
93
94        match ret {
95            Some((index, _)) => {
96                self.listeners.remove(index);
97                true
98            }
99            None => false,
100        }
101    }
102
103    pub fn emit(&self, param: &P) -> BuckyResult<Option<R>> {
104        let mut ret = None;
105        for item in &self.listeners {
106            ret = Some(item.1.call(param)?);
107        }
108
109        Ok(ret)
110    }
111}
112
113#[derive(Clone)]
114pub struct SyncEventManagerSync<P, R>(Arc<Mutex<SyncEventManager<P, R>>>)
115where
116    P: Send + Sync + 'static,
117    R: 'static;
118
119impl<P, R> SyncEventManagerSync<P, R>
120where
121    P: Send + Sync + 'static,
122    R: 'static,
123{
124    pub fn new() -> Self {
125        let inner = SyncEventManager::new();
126        Self(Arc::new(Mutex::new(inner)))
127    }
128
129    pub fn listener_count(&self) -> usize {
130        self.0.lock().unwrap().listeners.len()
131    }
132
133    pub fn is_empty(&self) -> bool {
134        self.0.lock().unwrap().is_empty()
135    }
136
137    pub fn on(&self, listener: Box<dyn EventListenerSyncRoutine<P, R>>) -> u32 {
138        self.0.lock().unwrap().on(listener)
139    }
140
141    pub fn off(&self, cookie: u32) -> bool {
142        self.0.lock().unwrap().off(cookie)
143    }
144
145    pub fn emit(&self, param: &P) -> BuckyResult<Option<R>> {
146        self.0.lock().unwrap().emit(param)
147    }
148}