140 lines
4.7 KiB
Rust
140 lines
4.7 KiB
Rust
|
|
use super::BgResult;
|
||
|
|
|
||
|
|
#[cfg(target_arch = "wasm32")]
|
||
|
|
use eframe::egui;
|
||
|
|
|
||
|
|
impl super::KaSeApp {
|
||
|
|
// ---- Connection helpers ----
|
||
|
|
|
||
|
|
#[cfg(not(target_arch = "wasm32"))]
|
||
|
|
pub(super) fn is_connected(&self) -> bool {
|
||
|
|
// Utilise le cache — PAS de serial.lock() ici !
|
||
|
|
// Sinon le thread UI bloque quand un thread background
|
||
|
|
// (OTA, query batch) tient le lock.
|
||
|
|
self.connected_cache
|
||
|
|
}
|
||
|
|
|
||
|
|
#[cfg(target_arch = "wasm32")]
|
||
|
|
pub(super) fn is_connected(&self) -> bool {
|
||
|
|
let ser = self.serial.borrow();
|
||
|
|
ser.connected
|
||
|
|
}
|
||
|
|
|
||
|
|
#[cfg(not(target_arch = "wasm32"))]
|
||
|
|
pub(super) fn connect(&mut self) {
|
||
|
|
let serial = self.serial.clone();
|
||
|
|
let tx = self.bg_tx.clone();
|
||
|
|
self.busy = true;
|
||
|
|
self.status_msg = "Scanning ports...".into();
|
||
|
|
|
||
|
|
std::thread::spawn(move || {
|
||
|
|
let mut ser = match serial.lock() {
|
||
|
|
Ok(g) => g,
|
||
|
|
Err(poisoned) => poisoned.into_inner(),
|
||
|
|
};
|
||
|
|
|
||
|
|
match ser.auto_connect() {
|
||
|
|
Ok(port_name) => {
|
||
|
|
let fw = ser.get_firmware_version().unwrap_or_default();
|
||
|
|
let names = ser.get_layer_names().unwrap_or_default();
|
||
|
|
let km = ser.get_keymap(0).unwrap_or_default();
|
||
|
|
let _ = tx.send(BgResult::Connected(port_name, fw, names, km));
|
||
|
|
|
||
|
|
// Try to fetch physical layout from firmware
|
||
|
|
let layout = ser.get_layout_json()
|
||
|
|
.ok()
|
||
|
|
.and_then(|json| crate::layout::parse_json(&json).ok());
|
||
|
|
if let Some(keys) = layout {
|
||
|
|
let _ = tx.send(BgResult::LayoutJson(keys));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Err(e) => {
|
||
|
|
let _ = tx.send(BgResult::ConnectError(e));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
#[cfg(target_arch = "wasm32")]
|
||
|
|
pub(super) fn connect_web(&mut self, ctx: &egui::Context) {
|
||
|
|
self.busy = true;
|
||
|
|
self.web_busy.set(true);
|
||
|
|
self.status_msg = "Selecting port...".into();
|
||
|
|
let serial = self.serial.clone();
|
||
|
|
let tx = self.bg_tx.clone();
|
||
|
|
let web_busy = self.web_busy.clone();
|
||
|
|
let ctx = ctx.clone();
|
||
|
|
|
||
|
|
wasm_bindgen_futures::spawn_local(async move {
|
||
|
|
// Step 1: async port selection (no borrow held)
|
||
|
|
let conn = match crate::serial::request_port().await {
|
||
|
|
Ok(c) => c,
|
||
|
|
Err(e) => {
|
||
|
|
let _ = tx.send(BgResult::ConnectError(e));
|
||
|
|
web_busy.set(false);
|
||
|
|
ctx.request_repaint();
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
// Step 2: extract handles before moving conn
|
||
|
|
let reader = conn.reader.clone();
|
||
|
|
let writer = conn.writer.clone();
|
||
|
|
let v2 = conn.v2;
|
||
|
|
|
||
|
|
// Step 3: store connection
|
||
|
|
serial.borrow_mut().apply_connection(conn);
|
||
|
|
|
||
|
|
// Step 4: async queries (no borrow held)
|
||
|
|
let fw = crate::serial::get_firmware_version(&reader, &writer, v2)
|
||
|
|
.await
|
||
|
|
.unwrap_or_default();
|
||
|
|
let names = crate::serial::get_layer_names(&reader, &writer, v2)
|
||
|
|
.await
|
||
|
|
.unwrap_or_default();
|
||
|
|
let km = crate::serial::get_keymap(&reader, &writer, 0, v2)
|
||
|
|
.await
|
||
|
|
.unwrap_or_default();
|
||
|
|
|
||
|
|
let _ = tx.send(BgResult::Connected("WebSerial".into(), fw, names, km));
|
||
|
|
|
||
|
|
// Try to fetch physical layout from firmware
|
||
|
|
let layout_json = crate::serial::get_layout_json(&reader, &writer, v2).await;
|
||
|
|
if let Ok(json) = layout_json {
|
||
|
|
if let Ok(keys) = crate::layout::parse_json(&json) {
|
||
|
|
let _ = tx.send(BgResult::LayoutJson(keys));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
web_busy.set(false);
|
||
|
|
ctx.request_repaint();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
#[cfg(not(target_arch = "wasm32"))]
|
||
|
|
pub(super) fn disconnect(&mut self) {
|
||
|
|
let mut guard = match self.serial.lock() {
|
||
|
|
Ok(g) => g,
|
||
|
|
Err(poisoned) => poisoned.into_inner(),
|
||
|
|
};
|
||
|
|
guard.disconnect();
|
||
|
|
drop(guard);
|
||
|
|
|
||
|
|
self.connected_cache = false;
|
||
|
|
self.firmware_version.clear();
|
||
|
|
self.keymap.clear();
|
||
|
|
self.layer_names = vec!["Layer 0".into()];
|
||
|
|
self.status_msg = "Disconnected".into();
|
||
|
|
}
|
||
|
|
|
||
|
|
#[cfg(target_arch = "wasm32")]
|
||
|
|
pub(super) fn disconnect(&mut self) {
|
||
|
|
self.serial.borrow_mut().disconnect();
|
||
|
|
|
||
|
|
self.firmware_version.clear();
|
||
|
|
self.keymap.clear();
|
||
|
|
self.layer_names = vec!["Layer 0".into()];
|
||
|
|
self.status_msg = "Disconnected".into();
|
||
|
|
}
|
||
|
|
}
|