agentmux_cef\reducer/
panes.rs1use std::time::Instant;
8
9use crate::state::*;
10
11use super::{DispatchOutput, HostEvent, HostLifecyclePhase, HostState, RegisterResult, emit_error};
12
13pub(super) fn handle_enqueue_browser_pane_create(
16 state: &mut HostState,
17 block_id: String,
18 label: String,
19) -> DispatchOutput {
20 if state.lifecycle == HostLifecyclePhase::ShuttingDown {
21 return emit_error(state, format!("enqueue_browser_pane_create: shutting down (block_id={})", block_id));
22 }
23 if state.browser_panes.contains_key(&block_id) {
24 return emit_error(state, format!("enqueue_browser_pane_create: block_id {} already has a pane", block_id));
25 }
26 state.browser_panes.insert(
27 block_id.clone(),
28 BrowserPaneEntry {
29 block_id: block_id.clone(),
30 label: label.clone(),
31 lifecycle: BrowserPaneLifecycle::Live,
32 },
33 );
34 let v = state.bump_version();
35 DispatchOutput {
36 events: vec![HostEvent::BrowserPaneCreateRequested { block_id, label, version: v }],
37 ..Default::default()
38 }
39}
40
41pub(super) fn handle_complete_browser_pane_create(state: &mut HostState, block_id: String) -> DispatchOutput {
42 let entry = match state.browser_panes.get(&block_id) {
43 Some(e) => e.clone(),
44 None => return DispatchOutput::default(), };
46 let v = state.bump_version();
49 DispatchOutput {
50 events: vec![HostEvent::BrowserPaneLive { block_id, label: entry.label, version: v }],
51 ..Default::default()
52 }
53}
54
55pub(super) fn handle_enqueue_browser_pane_close(state: &mut HostState, block_id: String) -> DispatchOutput {
56 let entry = match state.browser_panes.get_mut(&block_id) {
57 Some(e) => e,
58 None => return DispatchOutput::default(), };
60 if matches!(entry.lifecycle, BrowserPaneLifecycle::Closing { .. }) {
61 return DispatchOutput::default(); }
63 entry.lifecycle = BrowserPaneLifecycle::Closing { since: Instant::now() };
64 let label = entry.label.clone();
65 let v = state.bump_version();
66 DispatchOutput {
67 events: vec![HostEvent::BrowserPaneClosing { block_id, version: v }],
68 closed_browser_pane_label: Some(label),
69 ..Default::default()
70 }
71}
72
73pub(super) fn handle_try_register_browser_pane_live(state: &mut HostState, block_id: String) -> DispatchOutput {
81 if state.lifecycle == HostLifecyclePhase::ShuttingDown {
82 return emit_error(
83 state,
84 format!("try_register_browser_pane_live: shutting down (block_id={})", block_id),
85 );
86 }
87 if let Some(entry) = state.browser_panes.get(&block_id) {
88 let result = match entry.lifecycle {
89 BrowserPaneLifecycle::Live => RegisterResult::AlreadyLive(entry.label.clone()),
90 BrowserPaneLifecycle::Closing { .. } => RegisterResult::Closing,
91 };
92 return DispatchOutput {
93 browser_pane_register_result: Some(result),
94 ..Default::default()
95 };
96 }
97 let label = super::next_browser_pane_label(&block_id);
98 state.browser_panes.insert(
99 block_id.clone(),
100 BrowserPaneEntry {
101 block_id: block_id.clone(),
102 label: label.clone(),
103 lifecycle: BrowserPaneLifecycle::Live,
104 },
105 );
106 let v = state.bump_version();
107 DispatchOutput {
108 events: vec![HostEvent::BrowserPaneCreateRequested {
109 block_id,
110 label: label.clone(),
111 version: v,
112 }],
113 browser_pane_register_result: Some(RegisterResult::Fresh(label)),
114 ..Default::default()
115 }
116}
117
118pub(super) fn handle_drain_browser_pane_by_label(state: &mut HostState, label: String) -> DispatchOutput {
126 let victim = state
127 .browser_panes
128 .iter()
129 .find(|(_, e)| e.label == label)
130 .map(|(k, _)| k.clone());
131 let block_id = match victim {
132 Some(b) => b,
133 None => return DispatchOutput::default(),
134 };
135 state.browser_panes.remove(&block_id);
136 let v = state.bump_version();
137 DispatchOutput {
138 events: vec![HostEvent::BrowserPaneClosed {
139 block_id: block_id.clone(),
140 version: v,
141 }],
142 drained_browser_pane_block_id: Some(block_id),
143 ..Default::default()
144 }
145}
146
147pub(super) fn handle_complete_browser_pane_close(state: &mut HostState, block_id: String) -> DispatchOutput {
148 if state.browser_panes.remove(&block_id).is_none() {
149 return DispatchOutput::default(); }
151 let v = state.bump_version();
152 DispatchOutput {
153 events: vec![HostEvent::BrowserPaneClosed { block_id, version: v }],
154 ..Default::default()
155 }
156}
157
158pub(super) fn handle_abort_browser_pane_create(
159 state: &mut HostState,
160 block_id: String,
161 reason: String,
162) -> DispatchOutput {
163 state.browser_panes.remove(&block_id);
164 let v = state.bump_version();
165 DispatchOutput {
166 events: vec![HostEvent::BrowserPaneCreationFailed { block_id, reason, version: v }],
167 ..Default::default()
168 }
169}
170