1use tokio::sync::broadcast;
10
11use super::core::TmaiCore;
12
13#[derive(Debug, Clone)]
18pub enum CoreEvent {
19 AgentsUpdated,
21
22 AgentStatusChanged {
24 target: String,
26 old_status: String,
28 new_status: String,
30 },
31
32 AgentAppeared {
34 target: String,
36 },
37
38 AgentDisappeared {
40 target: String,
42 },
43
44 TeamsUpdated,
46
47 TeammateIdle {
49 target: String,
51 team_name: String,
53 member_name: String,
55 },
56
57 TaskCompleted {
59 team_name: String,
61 task_id: String,
63 task_subject: String,
65 },
66}
67
68impl TmaiCore {
69 pub fn subscribe(&self) -> broadcast::Receiver<CoreEvent> {
74 self.event_sender().subscribe()
75 }
76
77 pub fn notify_agents_updated(&self) {
82 let _ = self.event_sender().send(CoreEvent::AgentsUpdated);
83 }
84
85 pub fn notify_teams_updated(&self) {
89 let _ = self.event_sender().send(CoreEvent::TeamsUpdated);
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96 use crate::api::builder::TmaiCoreBuilder;
97 use crate::config::Settings;
98
99 #[tokio::test]
100 async fn test_subscribe_receives_events() {
101 let core = TmaiCoreBuilder::new(Settings::default()).build();
102 let mut rx = core.subscribe();
103
104 let tx = core.event_sender();
106 tx.send(CoreEvent::AgentsUpdated).unwrap();
107
108 let event = rx.recv().await.unwrap();
109 assert!(matches!(event, CoreEvent::AgentsUpdated));
110 }
111
112 #[tokio::test]
113 async fn test_subscribe_multiple_receivers() {
114 let core = TmaiCoreBuilder::new(Settings::default()).build();
115 let mut rx1 = core.subscribe();
116 let mut rx2 = core.subscribe();
117
118 let tx = core.event_sender();
119 tx.send(CoreEvent::TeamsUpdated).unwrap();
120
121 let e1 = rx1.recv().await.unwrap();
122 let e2 = rx2.recv().await.unwrap();
123 assert!(matches!(e1, CoreEvent::TeamsUpdated));
124 assert!(matches!(e2, CoreEvent::TeamsUpdated));
125 }
126
127 #[tokio::test]
128 async fn test_notify_agents_updated() {
129 let core = TmaiCoreBuilder::new(Settings::default()).build();
130 let mut rx = core.subscribe();
131
132 core.notify_agents_updated();
133
134 let event = rx.recv().await.unwrap();
135 assert!(matches!(event, CoreEvent::AgentsUpdated));
136 }
137
138 #[tokio::test]
139 async fn test_notify_teams_updated() {
140 let core = TmaiCoreBuilder::new(Settings::default()).build();
141 let mut rx = core.subscribe();
142
143 core.notify_teams_updated();
144
145 let event = rx.recv().await.unwrap();
146 assert!(matches!(event, CoreEvent::TeamsUpdated));
147 }
148
149 #[test]
150 fn test_notify_no_subscribers() {
151 let core = TmaiCoreBuilder::new(Settings::default()).build();
152 core.notify_agents_updated();
154 core.notify_teams_updated();
155 }
156}