refactor state refresh mechanism.
This commit is contained in:
parent
4f5420b658
commit
d9a4f92c04
|
@ -27,7 +27,7 @@ pub async fn handle_bluetooth_events(
|
|||
while let Some(event) = event_stream.next().await {
|
||||
match event {
|
||||
btleplug::api::CentralEvent::DeviceDiscovered(_id) => {
|
||||
app.emit("app_state_updated", ()).unwrap();
|
||||
app.emit("peripheral_found", ()).unwrap();
|
||||
}
|
||||
btleplug::api::CentralEvent::DeviceConnected(_id) => {
|
||||
let state = app_state.write().await;
|
||||
|
@ -36,7 +36,7 @@ pub async fn handle_bluetooth_events(
|
|||
for peripheral in peripherals {
|
||||
if peripheral.id() == _id {
|
||||
state.set_connected_peripheral(peripheral).await;
|
||||
app.emit("app_state_updated", ()).unwrap();
|
||||
app.emit("peripheral_connected", ()).unwrap();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -45,14 +45,14 @@ pub async fn handle_bluetooth_events(
|
|||
btleplug::api::CentralEvent::DeviceDisconnected(_id) => {
|
||||
let state = app_state.write().await;
|
||||
state.clear_connected_peripheral().await;
|
||||
app.emit("app_state_updated", ()).unwrap();
|
||||
app.emit("peripheral_disconnected", ()).unwrap();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}))
|
||||
} else {
|
||||
app.emit("app_state_updated", ()).unwrap();
|
||||
app.emit("central_state_updated", ()).unwrap();
|
||||
Err(errors::AppError::BluetoothNotReady)
|
||||
}
|
||||
}
|
||||
|
@ -91,8 +91,8 @@ pub async fn start_scan(
|
|||
.start_scan(ScanFilter::default())
|
||||
.await
|
||||
.map_err(|_| errors::AppError::UnableToStartScan)?;
|
||||
app_handle.emit("app_state_updated", ()).unwrap();
|
||||
state.set_scanning(true).await;
|
||||
app_handle.emit("scanning_started", ()).unwrap();
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors::AppError::NoAvailableBluetoothAdapter)
|
||||
|
@ -110,8 +110,8 @@ pub async fn stop_scan(
|
|||
.stop_scan()
|
||||
.await
|
||||
.map_err(|_| errors::AppError::UnableToStopScan)?;
|
||||
app_handle.emit("app_state_updated", ()).unwrap();
|
||||
state.set_scanning(false).await;
|
||||
app_handle.emit("scanning_stopped", ()).unwrap();
|
||||
Ok(())
|
||||
} else {
|
||||
Err(errors::AppError::NoAvailableBluetoothAdapter)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use btleplug::api::{Central as _, Peripheral as _};
|
||||
use state::{ApplicationState, CentralState, ChannelState, PeripheralItem};
|
||||
use state::{CentralState, ChannelState, PeripheralItem};
|
||||
use tauri::{async_runtime::RwLock, AppHandle, Emitter, State};
|
||||
|
||||
use crate::{bluetooth, errors, state::AppState};
|
||||
|
@ -23,28 +23,81 @@ pub async fn activate_central_adapter(
|
|||
let handle =
|
||||
bluetooth::handle_bluetooth_events(Arc::clone(&app), Arc::clone(&app_state)).await?;
|
||||
{
|
||||
let state = app_state.write().await; // Changed from lock() to write()
|
||||
let state = app_state.write().await;
|
||||
state.set_central_event_handler(handle).await;
|
||||
}
|
||||
app.emit("app_state_updated", ()).unwrap();
|
||||
app.emit("central_state_updated", ()).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn refresh_application_state(
|
||||
pub async fn central_device_state(
|
||||
app_state: State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<ApplicationState, errors::AppError> {
|
||||
) -> Result<CentralState, errors::AppError> {
|
||||
let state = app_state.read().await;
|
||||
let mut peripherals: Vec<PeripheralItem> = vec![];
|
||||
let mut connected_peripheral = None;
|
||||
|
||||
let central = state.get_central_adapter().await;
|
||||
let central_state = if let Some(central) = central {
|
||||
if let Some(central) = central {
|
||||
let central_device_state = central
|
||||
.adapter_state()
|
||||
.await
|
||||
.map_err(|_| errors::AppError::BluetoothNotReady)?;
|
||||
Ok(CentralState {
|
||||
is_ready: central_device_state == btleplug::api::CentralState::PoweredOn,
|
||||
is_scanning: *state.scanning.lock().await,
|
||||
connected: state
|
||||
.connected_peripheral
|
||||
.lock()
|
||||
.await
|
||||
.clone()
|
||||
.map(|p| p.id()),
|
||||
})
|
||||
} else {
|
||||
Ok(CentralState::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn connected_peripheral_state(
|
||||
app_state: State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<Option<PeripheralItem>, errors::AppError> {
|
||||
let state = app_state.read().await;
|
||||
let connected_peripheral = state.connected_peripheral.lock().await.clone();
|
||||
if let Some(peripheral) = connected_peripheral {
|
||||
let properties = peripheral
|
||||
.properties()
|
||||
.await
|
||||
.map_err(|_| errors::AppError::UnableToRetrievePeripheralProperties)?;
|
||||
if let Some(properties) = properties {
|
||||
let represent = properties
|
||||
.local_name
|
||||
.unwrap_or_else(|| properties.address.to_string());
|
||||
Ok(Some(PeripheralItem {
|
||||
id: peripheral.id(),
|
||||
address: properties.address.to_string(),
|
||||
represent,
|
||||
is_connected: peripheral
|
||||
.is_connected()
|
||||
.await
|
||||
.map_err(|_| errors::AppError::UnableToRetrievePeripheralProperties)?,
|
||||
rssi: properties.rssi,
|
||||
battery: properties.tx_power_level,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn found_peripherals(
|
||||
app_state: State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<Vec<PeripheralItem>, errors::AppError> {
|
||||
let state = app_state.read().await;
|
||||
let central = state.get_central_adapter().await;
|
||||
let mut peripherals: Vec<PeripheralItem> = vec![];
|
||||
if let Some(central) = central {
|
||||
let found_peripherals = central
|
||||
.peripherals()
|
||||
.await
|
||||
|
@ -69,38 +122,25 @@ pub async fn refresh_application_state(
|
|||
rssi: properties.rssi,
|
||||
battery: properties.tx_power_level,
|
||||
};
|
||||
if peripheral
|
||||
.is_connected()
|
||||
.await
|
||||
.map_err(|_| errors::AppError::UnableToRetrievePeripheralState)?
|
||||
{
|
||||
connected_peripheral = Some(item.clone());
|
||||
}
|
||||
peripherals.push(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(peripherals)
|
||||
}
|
||||
|
||||
CentralState {
|
||||
is_ready: central_device_state == btleplug::api::CentralState::PoweredOn,
|
||||
is_scanning: *state.scanning.lock().await,
|
||||
connected: state
|
||||
.connected_peripheral
|
||||
.lock()
|
||||
.await
|
||||
.clone()
|
||||
.map(|p| p.id()),
|
||||
}
|
||||
} else {
|
||||
CentralState::default()
|
||||
};
|
||||
#[tauri::command]
|
||||
pub async fn channel_a_state(
|
||||
_app_state: State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<ChannelState, errors::AppError> {
|
||||
Ok(ChannelState::default())
|
||||
}
|
||||
|
||||
Ok(ApplicationState {
|
||||
central: central_state,
|
||||
peripherals,
|
||||
connected_peripheral,
|
||||
channel_a: ChannelState::default(),
|
||||
channel_b: ChannelState::default(),
|
||||
})
|
||||
#[tauri::command]
|
||||
pub async fn channel_b_state(
|
||||
_app_state: State<'_, Arc<RwLock<AppState>>>,
|
||||
) -> Result<ChannelState, errors::AppError> {
|
||||
Ok(ChannelState::default())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
|
|
@ -4,6 +4,7 @@ use serde::Serialize;
|
|||
use crate::playlist::PlayMode;
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CentralState {
|
||||
pub is_ready: bool,
|
||||
pub is_scanning: bool,
|
||||
|
@ -11,6 +12,7 @@ pub struct CentralState {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct PeripheralItem {
|
||||
pub id: PeripheralId,
|
||||
pub address: String,
|
||||
|
@ -21,6 +23,7 @@ pub struct PeripheralItem {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ChannelState {
|
||||
pub is_playing: bool,
|
||||
pub strength: u32,
|
||||
|
@ -30,12 +33,3 @@ pub struct ChannelState {
|
|||
pub boost_limit: u32,
|
||||
pub play_mode: PlayMode,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct ApplicationState {
|
||||
pub central: CentralState,
|
||||
pub peripherals: Vec<PeripheralItem>,
|
||||
pub connected_peripheral: Option<PeripheralItem>,
|
||||
pub channel_a: ChannelState,
|
||||
pub channel_b: ChannelState,
|
||||
}
|
||||
|
|
|
@ -53,7 +53,11 @@ pub fn run() {
|
|||
Ok(())
|
||||
})
|
||||
.invoke_handler(generate_handler![
|
||||
cmd::refresh_application_state,
|
||||
cmd::central_device_state,
|
||||
cmd::connected_peripheral_state,
|
||||
cmd::found_peripherals,
|
||||
cmd::channel_a_state,
|
||||
cmd::channel_b_state,
|
||||
cmd::activate_central_adapter,
|
||||
cmd::start_scan_devices,
|
||||
cmd::stop_scan_devices
|
||||
|
|
Loading…
Reference in New Issue
Block a user