Skip to main content

rs_eda/event/
mod.rs

1use serde_json::Value;
2use std::{collections::HashMap, pin::Pin};
3use tokio::sync::mpsc::{self, Sender};
4
5pub struct Event {
6    name: String,        // 事件名
7    data: Option<Value>, // 数据使用Value格式
8}
9impl Event {
10    pub fn new(name: &str, data: Option<Value>) -> Self {
11        Self {
12            name: name.to_string(),
13            data,
14        }
15    }
16}
17
18type FnVal = Option<Value>;
19type ListenersMap = HashMap<String, Vec<Sender<FnVal>>>;
20type BoxedHandler = Box<dyn Fn(FnVal) -> BoxFuture + Send + Sync>;
21type BoxFuture = Pin<Box<dyn Future<Output = ()> + Send + Sync>>;
22
23#[derive(Debug, Clone)]
24pub struct EventDispatcher {
25    listeners: ListenersMap,
26}
27
28impl EventDispatcher {
29    pub fn new() -> Self {
30        Self {
31            listeners: HashMap::new(),
32        }
33    }
34    /**
35     * @description: 获取事件列表
36     * @author: tgy3300
37     * @Date: 2025-03-29 12:20:36
38     * @param {*} self
39     * @return {*}
40     */
41    pub fn get_listeners(&self) -> &ListenersMap {
42        &self.listeners
43    }
44    /**
45     * @description: 订阅事件
46     * @author: tgy3300
47     * @Date: 2025-03-29 12:20:08
48     * @param {*} name 事件名
49     * @param {Option} listener 事件方法
50     * @return {*}
51     */
52    pub fn add_event_listener(&mut self, name: &str, listener: BoxedHandler) {
53        let (tx, mut rx) = mpsc::channel(30);
54
55        self.listeners
56            .entry(name.to_string())
57            .or_insert(Vec::new())
58            .push(tx);
59
60        tokio::spawn(async move {
61            while let Some(data) = rx.recv().await {
62                (listener)(data).await;
63            }
64        });
65    }
66    /**
67     * @description: 判断事件名下指定事件方法是否存在,这里有问题,无法通过listener区分判断
68     * @author: tgy3300
69     * @Date: 2025-03-29 12:19:38
70     * @param {*} name
71     * @param {EventListener} listener
72     * @return {*}
73     */
74    pub fn has_event_listener(&self, name: &str, listener: BoxedHandler) -> bool {
75        if let Some(listeners) = self.listeners.get(name) {
76            // let func = &(listener);
77            // return listeners.contains(func);
78            return true;
79        }
80        false
81    }
82    /**
83     * @description: 判断事件是否存在
84     * @author: tgy3300
85     * @Date: 2025-03-29 12:19:11
86     * @param {*} name
87     * @return {*}
88     */
89    pub fn has_event(&self, name: &str) -> bool {
90        if let Some(_) = self.listeners.get(name) {
91            true
92        } else {
93            false
94        }
95    }
96    /**
97     * @description: 移除事件下指定事件方法(包括该事件对应的节流事件和防抖事件)
98     * @author: tgy3300
99     * @Date: 2025-03-29 12:17:39
100     * @param {*} name 事件名
101     * @param {EventListener} listener 事件方法
102     * @return {*}
103     */
104    pub fn remove_event_listener(&mut self, name: &str, listener: BoxedHandler) {
105        // if let Some(arr) = self.listeners.get_mut(name) {
106        //     // 删除节流事件
107        //     // 删除防抖事件
108
109        //     // 通过指针地址对比,过滤掉传入的事件
110        //     arr.retain(|x| format!("{:?}", x) != format!("{:?}", &(listener)));
111        // }
112    }
113    /**
114     * @description: 移除事件
115     * @author: tgy3300
116     * @Date: 2025-03-29 12:17:00
117     * @param {*} name 事件名
118     * @return {*}
119     */
120    pub fn remove_event(&mut self, name: &str) {
121        if self.listeners.contains_key(name) {
122            self.listeners.remove(name);
123        }
124    }
125    /**
126     * @description: 触发事件
127     * @author: tgy3300
128     * @Date: 2025-03-29 12:15:47
129     * @param {Event} event 事件数据
130     * @return {*}
131     */
132    pub fn dispatch_event(&self, event: Event) {
133        if let Some(listeners) = self.listeners.get(&event.name) {
134            for listener in listeners {
135                let listener_clone = listener.clone();
136                let data_clone = event.data.clone();
137                tokio::spawn(async move {
138                    let _x = listener_clone.send(data_clone).await.unwrap();
139                });
140            }
141        }
142    }
143    /**
144     * @description: 一次性触发,触发之后会自动移除,再次触发无效果
145     * @author: tgy3300
146     * @Date: 2025-03-29 12:13:34
147     * @param {*} self
148     * @param {*} _name
149     * @param {Option} _listener
150     * @return {*}
151     */
152    pub fn once(&self, _name: &str, _listener: BoxedHandler) {}
153    /**
154     * @description: 触发事件
155     * @author: tgy3300
156     * @Date: 2025-03-29 12:13:05
157     * @param {*} name 事件名
158     * @param {Option} params 事件参数
159     * @return {*}
160     */
161    pub fn emit(&self, name: &str, params: FnVal) {
162        self.dispatch_event(Event::new(name, params))
163    }
164    /**
165     * @description: 订阅事件
166     * @author: tgy3300
167     * @Date: 2025-03-29 12:12:40
168     * @param {*} name 事件名
169     * @param {Option} listener 事件方法
170     * @return {*}
171     */
172    pub fn on<F, Fut>(&mut self, name: &str, listener: F)
173    where
174        F: Fn(FnVal) -> Fut + Send + Sync + 'static,
175        Fut: Future<Output = ()> + Send + Sync + 'static,
176    {
177        let handler: BoxedHandler = Box::new(move |x| Box::pin(listener(x)));
178        self.add_event_listener(name, handler);
179    }
180    /**
181     * @description: 判断事件名、事件名下指定事件方法是否存在,通过listener区分判断
182     * @author: tgy3300
183     * @Date: 2025-03-29 12:10:06
184     * @param {*} name 事件名
185     * @param {Option} listener 事件方法
186     * @return {*}
187     */
188    pub fn has(&self, name: &str, listener: Option<BoxedHandler>) -> bool {
189        if let Some(x) = listener {
190            self.has_event_listener(name, x)
191        } else {
192            self.has_event(name)
193        }
194    }
195    /**
196     * @description: 移除事件,如果不传listener就会移除整个name事件
197     * @author: tgy3300
198     * @Date: 2025-03-29 12:09:22
199     * @param {*} name 事件名
200     * @param {Option} listener 事件方法
201     * @return {*}
202     */
203    pub fn off(&mut self, name: &str, listener: Option<BoxedHandler>) {
204        if let Some(func) = listener {
205            self.remove_event_listener(name, func);
206        } else {
207            self.remove_event(name);
208        }
209    }
210    /**
211     * @description: 获取该事件类型下的事件数量
212     * @author: tgy3300
213     * @Date: 2025-03-29 12:06:55
214     * @param {*} name 事件名
215     * @return {*}
216     */
217    pub fn event_count(&self, name: &str) -> usize {
218        if let Some(x) = self.listeners.get(name) {
219            x.len()
220        } else {
221            0
222        }
223    }
224    /**
225     * @description: 销毁该类型的最后一个事件
226     * @author: tgy3300
227     * @Date: 2025-03-29 12:05:38
228     * @param {*} name 事件名
229     * @return {*}
230     */
231    pub fn pop_latest_event(&mut self, name: &str) -> bool {
232        if let Some(arr) = self.listeners.get_mut(name) {
233            if let Some(_) = arr.pop() {
234                return true;
235            }
236        }
237        false
238    }
239    /**
240     * @description: 清空所有事件类型的事件
241     * @author: tgy3300
242     * @Date: 2025-03-29 12:05:14
243     * @return {*}
244     */
245    pub fn clear(&mut self) {
246        self.listeners.clear();
247    }
248    /**
249     * @description: 当前派发器是否使用
250     * @author: tgy3300
251     * @Date: 2025-03-29 12:04:43
252     * @return {*}
253     */
254    pub fn useful(&self) -> bool {
255        self.listeners.keys().len() > 0
256    }
257    /**
258     * @description: 节流触发
259     * @author: tgy3300
260     * @Date: 2025-03-29 12:06:04
261     * @param {*} name 事件名
262     * @param {Option} listener 事件方法
263     * @param {u64} time 节流时间
264     * @return {*}
265     */
266    pub fn on_throttle(&self, _name: &str, _listener: BoxedHandler, _time: u64) {}
267    /**
268     * @description: 防抖触发
269     * @author: tgy3300
270     * @Date: 2025-03-29 12:06:23
271     * @param {*} name 事件名
272     * @param {Option} listener 事件方法
273     * @param {u64} time 防抖时间
274     * @return {*}
275     */
276    pub fn on_anti_shake(&self, _name: &str, _listener: BoxedHandler, _time: u64) {}
277}