1pub mod filter;
2pub mod listener;
3pub mod state;
4
5use std::any::Any;
7use std::sync::{Arc, Mutex, RwLock}; use uuid::Uuid; use crate::bot::Bot;
11use crate::command::CommandBuilder;
12use crate::context::{
13 filter::ContextFilter,
14 listener::{ListenerAction, ListenerHandle, ListenerId, RegisteredListener},
15 state::EventSystemSharedState,
16};
17use crate::session::Session;
18
19#[derive(Clone)]
21pub struct Context {
22 pub bots: Arc<Mutex<Vec<Arc<Bot>>>>,
24 pub current_filter: ContextFilter,
26 pub shared_state: Arc<RwLock<EventSystemSharedState>>,
28}
29
30impl Context {
31 pub fn new_root(shared_state: Arc<RwLock<EventSystemSharedState>>) -> Self {
32 Context {
33 bots: Arc::new(Mutex::new(Vec::new())),
34 current_filter: ContextFilter::new(), shared_state,
36 }
37 }
38
39 pub fn user(&self, user_id: &str) -> Self {
41 Context {
43 bots: self.bots.clone(),
44 current_filter: self.current_filter.clone().user(user_id),
45 shared_state: Arc::clone(&self.shared_state),
46 }
47 }
48 pub fn guild(&self, guild_id: &str) -> Self {
49 Context {
51 bots: self.bots.clone(),
52 current_filter: self.current_filter.clone().guild(guild_id),
53 shared_state: Arc::clone(&self.shared_state),
54 }
55 }
56 pub fn platform(&self, platform: &str) -> Self {
57 Context {
59 bots: self.bots.clone(),
60 current_filter: self.current_filter.clone().platform(platform),
61 shared_state: Arc::clone(&self.shared_state),
62 }
63 }
64 pub fn private(&self) -> Self {
65 Context {
67 bots: self.bots.clone(),
68 current_filter: self.current_filter.clone().private(),
69 shared_state: Arc::clone(&self.shared_state),
70 }
71 }
72 pub fn group(&self) -> Self {
73 Context {
75 bots: self.bots.clone(),
76 current_filter: self.current_filter.clone().group(),
77 shared_state: Arc::clone(&self.shared_state),
78 }
79 }
80 pub fn command(&self, name: &str) -> CommandBuilder {
98 let registry_arc = {
99 let state_guard = self.shared_state.read().unwrap();
100 Arc::clone(&state_guard.command_registry)
101 };
102 CommandBuilder::new(name.to_string(), self.current_filter.clone(), registry_arc)
103 }
104
105 fn register_listener_internal(
106 &self,
107 event_name: &str,
108 action: ListenerAction,
109 ) -> ListenerHandle {
110 let id = Uuid::new_v4(); let listener = Arc::new(RegisteredListener {
112 id,
113 filter: self.current_filter.clone(), action,
115 });
116 let mut state = self.shared_state.write().unwrap(); state.add_listener(event_name.to_string(), Arc::clone(&listener));
118 ListenerHandle {
119 id,
120 shared_state: Arc::clone(&self.shared_state),
121 }
122 }
123
124 pub fn on<F>(&self, event_name: &str, callback: F) -> ListenerHandle
126 where
127 F: FnMut(Option<&Session>, &[Box<dyn Any + Send + Sync>]) + Send + Sync + 'static,
128 {
129 self.register_listener_internal(
130 event_name,
131 ListenerAction::On(Mutex::new(Box::new(callback))),
132 )
133 }
134
135 pub fn once<F>(&self, event_name: &str, callback: F) -> ListenerHandle
137 where
138 F: FnMut(Option<&Session>, &[Box<dyn Any + Send + Sync>]) + Send + Sync + 'static,
139 {
140 self.register_listener_internal(
141 event_name,
142 ListenerAction::Once(Mutex::new(Some(Box::new(callback)))),
143 )
144 }
145
146 pub fn bail<F>(&self, event_name: &str, callback: F) -> ListenerHandle
148 where
149 F: FnMut(
150 Option<&Session>,
151 &[Box<dyn Any + Send + Sync>],
152 ) -> Option<Box<dyn Any + Send + Sync>>
153 + Send
154 + Sync
155 + 'static,
156 {
157 self.register_listener_internal(
158 event_name,
159 ListenerAction::Bail(Mutex::new(Box::new(callback))),
160 )
161 }
162
163 pub fn emit(
173 &self,
174 event_name: &str,
175 session_context: Option<&Session>,
176 args: &[Box<dyn Any + Send + Sync>],
177 ) -> Option<Box<dyn Any + Send + Sync>> {
178 let state_read_guard = self.shared_state.read().unwrap(); let listeners_for_event_arcs = match state_read_guard.listeners_by_event.get(event_name) {
180 Some(listeners) => listeners.clone(), None => return None, };
183 drop(state_read_guard); let mut ids_of_once_listeners_fired: Vec<ListenerId> = Vec::new(); for listener_arc in listeners_for_event_arcs {
188 let should_run = match session_context {
190 Some(s_ctx) => listener_arc.filter.matches_session(s_ctx),
191 None => listener_arc.filter.matches_generic(), };
193
194 if !should_run {
195 continue; }
197
198 match &listener_arc.action {
200 ListenerAction::On(cb_mutex) => {
201 if let Ok(mut cb_guard) = cb_mutex.try_lock() {
204 (*cb_guard)(session_context, args);
205 } else {
206 eprintln!(
208 "[事件系统警告] 无法获取 On 监听器 {} 的锁,可能存在重入或竞争。",
209 listener_arc.id
210 );
211 }
212 }
213 ListenerAction::Once(cb_mutex_opt) => {
214 let mut opt_cb_guard = cb_mutex_opt.lock().unwrap();
215 if let Some(mut cb) = opt_cb_guard.take() {
216 drop(opt_cb_guard); cb(session_context, args);
220 ids_of_once_listeners_fired.push(listener_arc.id); }
222 }
224 ListenerAction::Bail(cb_mutex) => {
225 if let Ok(mut cb_guard) = cb_mutex.try_lock() {
226 let bail_result = (*cb_guard)(session_context, args);
227 if bail_result.is_some() {
228 if !ids_of_once_listeners_fired.is_empty() {
231 let mut state_write_guard = self.shared_state.write().unwrap();
232 for id in &ids_of_once_listeners_fired {
233 state_write_guard.remove_listener(*id);
234 }
235 }
236 return bail_result; }
238 } else {
239 eprintln!(
240 "[事件系统警告] 无法获取 Bail 监听器 {} 的锁,可能存在重入或竞争。",
241 listener_arc.id
242 );
243 }
244 }
245 }
246 }
247
248 if !ids_of_once_listeners_fired.is_empty() {
250 let mut state_write_guard = self.shared_state.write().unwrap();
251 for id in ids_of_once_listeners_fired {
252 state_write_guard.remove_listener(id);
253 }
254 }
255
256 None }
258}