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}