agentmux_cef\reducer/
pool.rs1use crate::state::*;
9
10use super::{DispatchOutput, HostEvent, HostState, PoolLeaveReason};
11
12pub(super) fn handle_pool_spawn_start(state: &mut HostState, label: String) -> DispatchOutput {
15 if state.quit_state != QuitState::Running {
20 return DispatchOutput {
21 pool_spawn_proceeding: false,
22 ..Default::default()
23 };
24 }
25 if state.pool.respawn_in_flight {
26 return DispatchOutput {
27 pool_spawn_proceeding: false,
28 ..Default::default()
29 };
30 }
31 state.pool.unpromoted.insert(label);
32 state.pool.respawn_in_flight = true;
33 DispatchOutput {
34 pool_spawn_proceeding: true,
35 ..Default::default()
36 }
37}
38
39pub(super) fn handle_pool_ready(state: &mut HostState, label: String) -> DispatchOutput {
40 if !state.pool.unpromoted.remove(&label) {
41 return DispatchOutput {
43 pool_size_after: Some(state.pool.queue.len()),
44 ..Default::default()
45 };
46 }
47 if !state.pool.queue.iter().any(|l| l == &label) {
48 state.pool.queue.push_back(label.clone());
49 }
50 state.pool.respawn_in_flight = false;
51 let queue_len_after = state.pool.queue.len();
52 let v = state.bump_version();
53 DispatchOutput {
54 events: vec![HostEvent::PoolWindowEntered {
55 label,
56 queue_len_after,
57 version: v,
58 }],
59 pool_size_after: Some(queue_len_after),
60 ..Default::default()
61 }
62}
63
64pub(super) fn handle_pool_destroyed_before_promote(state: &mut HostState, label: String) -> DispatchOutput {
65 let was_unpromoted = state.pool.unpromoted.remove(&label);
72 let queue_len_before = state.pool.queue.len();
73 state.pool.queue.retain(|l| l != &label);
74 let was_in_queue = state.pool.queue.len() < queue_len_before;
75 state.pool.respawn_in_flight = false;
76 let queue_len_after = state.pool.queue.len();
77 if !was_unpromoted && !was_in_queue {
78 return DispatchOutput {
79 pool_size_after: Some(queue_len_after),
80 ..Default::default()
81 };
82 }
83 let v = state.bump_version();
84 DispatchOutput {
85 events: vec![HostEvent::PoolWindowLeft {
86 label,
87 queue_len_after,
88 reason: PoolLeaveReason::DestroyedBeforePromote,
89 version: v,
90 }],
91 pool_destroyed_was_unpromoted: was_unpromoted,
92 pool_size_after: Some(queue_len_after),
93 ..Default::default()
94 }
95}
96
97pub(super) fn handle_pop_and_promote_front_pool_window(state: &mut HostState) -> DispatchOutput {
98 let label = match state.pool.queue.pop_front() {
99 Some(l) => l,
100 None => return DispatchOutput::default(),
101 };
102 state.pool.unpromoted.remove(&label);
103 if let Some(handle) = state.browsers.get_mut(&label) {
104 if let BrowserKind::TopLevel { is_pool } = &mut handle.kind {
105 *is_pool = false;
106 }
107 }
108 let queue_len_after = state.pool.queue.len();
109 let v = state.bump_version();
110 DispatchOutput {
111 events: vec![HostEvent::PoolWindowLeft {
112 label: label.clone(),
113 queue_len_after,
114 reason: PoolLeaveReason::Promoted,
115 version: v,
116 }],
117 promoted_pool_label: Some(label),
118 pool_size_after: Some(queue_len_after),
119 ..Default::default()
120 }
121}
122
123pub(super) fn handle_promote_pool_window(state: &mut HostState, label: String) -> DispatchOutput {
124 let queue_len_before = state.pool.queue.len();
131 state.pool.queue.retain(|l| l != &label);
132 let was_in_queue = state.pool.queue.len() < queue_len_before;
133 let was_in_unpromoted = state.pool.unpromoted.remove(&label);
134 if !was_in_queue && !was_in_unpromoted {
135 return DispatchOutput::default();
136 }
137 if let Some(handle) = state.browsers.get_mut(&label) {
139 if let BrowserKind::TopLevel { is_pool } = &mut handle.kind {
140 *is_pool = false;
141 }
142 }
143 let v = state.bump_version();
144 DispatchOutput {
145 events: vec![HostEvent::PoolWindowLeft {
146 label,
147 queue_len_after: state.pool.queue.len(),
148 reason: PoolLeaveReason::Promoted,
149 version: v,
150 }],
151 ..Default::default()
152 }
153}
154
155pub(super) fn handle_pool_drain_all(state: &mut HostState) -> DispatchOutput {
156 let drained: Vec<String> = state
157 .pool
158 .queue
159 .drain(..)
160 .chain(state.pool.unpromoted.drain())
161 .collect();
162 state.pool.respawn_in_flight = false;
163 let mut events = Vec::new();
164 for label in drained {
165 let v = state.bump_version();
166 events.push(HostEvent::PoolWindowLeft {
167 label,
168 queue_len_after: 0,
169 reason: PoolLeaveReason::DrainedOnShutdown,
170 version: v,
171 });
172 }
173 let v = state.bump_version();
174 events.push(HostEvent::PoolEmpty { version: v });
175 DispatchOutput {
176 events,
177 ..Default::default()
178 }
179}
180