From 35b2a06e64d70765923d1b6579db21c4449ce978 Mon Sep 17 00:00:00 2001 From: Sam Sartor Date: Sat, 24 Jan 2026 22:08:09 -0700 Subject: [PATCH] some ideas including stub --- gui/Cargo.toml | 1 - gui/src/imp/connect.rs | 5 ++ gui/src/imp/mobile.rs | 4 -- gui/src/imp/mod.rs | 50 ++++++++++----- gui/src/imp/native_audio.rs | 10 --- gui/src/imp/stub.rs | 117 ++++++++++++++++++++++++++++++++++++ gui/src/imp/web.rs | 16 +---- 7 files changed, 160 insertions(+), 43 deletions(-) create mode 100644 gui/src/imp/stub.rs diff --git a/gui/Cargo.toml b/gui/Cargo.toml index 0433118..7e29572 100644 --- a/gui/Cargo.toml +++ b/gui/Cargo.toml @@ -146,7 +146,6 @@ desktop = [ "rfd/xdg-portal", "etcetera", ] - mobile = [ "dioxus/mobile", "tokio", diff --git a/gui/src/imp/connect.rs b/gui/src/imp/connect.rs index 8136e2f..e7d3ce7 100644 --- a/gui/src/imp/connect.rs +++ b/gui/src/imp/connect.rs @@ -108,3 +108,8 @@ pub async fn network_connect( pub async fn get_status(client: &reqwest::Client) -> color_eyre::Result { bail!("status not supported on desktop yet") } + +#[allow(unused)] +pub use tokio::spawn; +#[allow(unused)] +pub type SpawnHandle = tokio::runtime::Handle; diff --git a/gui/src/imp/mobile.rs b/gui/src/imp/mobile.rs index 5f887c2..dec58d8 100644 --- a/gui/src/imp/mobile.rs +++ b/gui/src/imp/mobile.rs @@ -7,10 +7,6 @@ use std::time::Duration; pub use super::connect::*; -// ============================================================================ -// Platform Struct -// ============================================================================ - /// Mobile platform implementation using Tokio, native audio, and Android permissions. pub struct MobilePlatform; diff --git a/gui/src/imp/mod.rs b/gui/src/imp/mod.rs index 0b6cfe6..9952d85 100644 --- a/gui/src/imp/mod.rs +++ b/gui/src/imp/mod.rs @@ -31,8 +31,7 @@ pub trait AudioSystemInterface: Sized { each: impl FnMut(Vec, bool) + Send + 'static, ) -> Result<(), Error>; - /// Begin playback of an audio stream, returning an object that can be passed - /// with opus frames. + /// Begin playback of an audio stream, returning an object that can be passed opus frames. fn create_player(&mut self) -> Result; } @@ -89,18 +88,17 @@ pub trait PlatformInterface { // Platform Modules // ============================================================================ -#[cfg(feature = "web")] -pub mod web; - #[cfg(any(feature = "desktop", feature = "mobile"))] -pub mod connect; -#[cfg(any(feature = "desktop", feature = "mobile"))] -pub mod native_audio; - +mod connect; #[cfg(feature = "desktop")] -pub mod desktop; +mod desktop; #[cfg(feature = "mobile")] -pub mod mobile; +mod mobile; +#[cfg(any(feature = "desktop", feature = "mobile"))] +mod native_audio; +mod stub; +#[cfg(feature = "web")] +mod web; // ============================================================================ // Platform Type Alias @@ -115,20 +113,44 @@ pub type Platform = desktop::DesktopPlatform; #[cfg(all(feature = "mobile", not(feature = "web"), not(feature = "desktop")))] pub type Platform = mobile::MobilePlatform; +#[cfg(all( + not(feature = "mobile"), + not(feature = "web"), + not(feature = "desktop") +))] +pub type Platform = stub::StubPlatform; + pub type AudioSystem = ::AudioSystem; pub type AudioPlayer = ::AudioPlayer; // ======================== // Platform Async Runtime // ======================== + // Note: these can not be part of the Platform because they differ in Send requiremets #[cfg(all(any(feature = "desktop", feature = "mobile"), not(feature = "web")))] -pub use native_audio::{spawn, SpawnHandle}; +pub use connect::{spawn, SpawnHandle}; +#[cfg(all( + not(feature = "desktop"), + not(feature = "mobile"), + not(feature = "web") +))] +pub use stub::{spawn, SpawnHandle}; #[cfg(feature = "web")] pub use web::{spawn, SpawnHandle}; -/// Compile-time assertion that CurrentPlatform implements Platform. +// ======================= +// Compile-time Assertions +// ======================= const _: () = { fn assert_platform() {} - let _ = assert_platform::; + + // Check each implementation, and prevent warnings that the implementations are unused. + #[cfg(feature = "web")] + let _ = assert_platform::; + #[cfg(feature = "desktop")] + let _ = assert_platform::; + #[cfg(feature = "mobile")] + let _ = assert_platform::; + let _ = assert_platform::; }; diff --git a/gui/src/imp/native_audio.rs b/gui/src/imp/native_audio.rs index d8141d0..5b5b3c5 100644 --- a/gui/src/imp/native_audio.rs +++ b/gui/src/imp/native_audio.rs @@ -6,16 +6,6 @@ use std::sync::Arc; use std::sync::Mutex; use tracing::{error, info, warn}; -// ============= -// Async runtime -// ============= -pub use tokio::spawn; -pub type SpawnHandle = tokio::runtime::Handle; - -// ============ -// Audio System -// ============ - pub struct NativeAudioSystem { output: cpal::Device, input: cpal::Device, diff --git a/gui/src/imp/stub.rs b/gui/src/imp/stub.rs new file mode 100644 index 0000000..c4f2917 --- /dev/null +++ b/gui/src/imp/stub.rs @@ -0,0 +1,117 @@ +use crate::effects::AudioProcessor; +use color_eyre::eyre::Error; +use dioxus::hooks::UnboundedReceiver; +use mumble_web2_common::{ClientConfig, ServerStatus}; +use std::future::Future; + +pub struct StubPlatform; + +impl super::PlatformInterface for StubPlatform { + type AudioSystem = StubAudioSystem; + + fn init_logging() { + todo!() + } + + fn request_permissions() { + todo!() + } + + fn network_connect( + _address: String, + _username: String, + _event_rx: &mut UnboundedReceiver, + _gui_config: &ClientConfig, + ) -> impl Future> { + async { todo!() } + } + + fn get_status( + _client: &reqwest::Client, + ) -> impl Future> { + async { todo!() } + } + + fn load_config() -> impl Future> { + async { todo!() } + } + + fn load_username() -> Option { + todo!() + } + + fn load_server_url() -> Option { + todo!() + } + + fn set_default_username(_username: &str) -> Option<()> { + todo!() + } + + fn set_default_server(_server: &str) -> Option<()> { + todo!() + } + + fn sleep(_duration: std::time::Duration) -> impl Future { + async { todo!() } + } +} + +pub struct StubAudioSystem; + +impl super::AudioSystemInterface for StubAudioSystem { + type AudioPlayer = StubAudioPlayer; + + async fn new() -> Result { + todo!() + } + + fn set_processor(&self, _processor: AudioProcessor) { + todo!() + } + + fn start_recording( + &mut self, + _each: impl FnMut(Vec, bool) + Send + 'static, + ) -> Result<(), Error> { + todo!() + } + + fn create_player(&mut self) -> Result { + todo!() + } +} + +pub struct StubAudioPlayer; + +impl super::AudioPlayerInterface for StubAudioPlayer { + fn play_opus(&mut self, _payload: &[u8]) { + todo!() + } +} + +#[allow(unused)] +pub struct SpawnHandle; + +impl SpawnHandle { + #[allow(unused)] + pub fn spawn(&self, _future: F) + where + F: Future + 'static, + { + todo!() + } + + #[allow(unused)] + pub fn current() -> Self { + SpawnHandle + } +} + +#[allow(unused)] +pub fn spawn(_future: F) +where + F: Future + 'static, +{ + todo!() +} diff --git a/gui/src/imp/web.rs b/gui/src/imp/web.rs index 1bfef8f..92a1a18 100644 --- a/gui/src/imp/web.rs +++ b/gui/src/imp/web.rs @@ -38,18 +38,10 @@ use web_sys::WorkletOptions; use web_sys::{console, window}; use web_sys::{AudioContext, AudioDataCopyToOptions}; -pub trait ImpRead: AsyncRead + Unpin + 'static {} -impl ImpRead for T {} - -pub trait ImpWrite: AsyncWrite + Unpin + 'static {} -impl ImpWrite for T {} - -// ============= -// Async runtime -// ============= - +#[allow(unused)] pub use wasm_bindgen_futures::spawn_local as spawn; +#[allow(unused)] #[derive(Clone)] pub struct SpawnHandle; @@ -66,10 +58,6 @@ impl SpawnHandle { } } -// ============================================================================ -// Platform Struct -// ============================================================================ - /// Web platform implementation using WebTransport and Web Audio API. pub struct WebPlatform;