Skip to content

Commit

Permalink
wip moving out logic from ProviderRef
Browse files Browse the repository at this point in the history
  • Loading branch information
lars-berger committed Nov 16, 2024
1 parent 265787e commit bdef4cf
Show file tree
Hide file tree
Showing 3 changed files with 100 additions and 16 deletions.
2 changes: 1 addition & 1 deletion packages/desktop/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ pub async fn unlisten_provider(
provider_manager: State<'_, Arc<ProviderManager>>,
) -> anyhow::Result<(), String> {
provider_manager
.destroy(&config_hash)
.stop(&config_hash)
.await
.map_err(|err| err.to_string())
}
Expand Down
110 changes: 98 additions & 12 deletions packages/desktop/src/providers/provider_manager.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,39 @@
use std::{collections::HashMap, sync::Arc};

use anyhow::Context;
use anyhow::{bail, Context};
use sysinfo::System;
use tauri::{AppHandle, Emitter};
use tokio::sync::{mpsc, oneshot, Mutex};
use tokio::{
sync::{mpsc, oneshot, Mutex},
task,
};
use tracing::info;

use super::{
battery::BatteryProvider, cpu::CpuProvider, disk::DiskProvider,
host::HostProvider, ip::IpProvider, memory::MemoryProvider,
network::NetworkProvider, weather::WeatherProvider, Provider,
ProviderConfig, ProviderEmission, ProviderFunction,
ProviderFunctionResult, ProviderRef,
ProviderFunctionResult, RuntimeType,
};
#[cfg(windows)]
use super::{
keyboard::KeyboardProvider, komorebi::KomorebiProvider,
media::MediaProvider,
};

/// Reference to an active provider.
pub struct ProviderRef {
/// Sender channel for stopping the provider.
destroy_tx: mpsc::Sender<()>,

/// Sender channel for sending function calls to the provider.
function_tx: mpsc::Sender<(
ProviderFunction,
oneshot::Sender<ProviderFunctionResult>,
)>,
}

/// State shared between providers.
#[derive(Clone)]
pub struct SharedProviderState {
Expand All @@ -18,10 +42,19 @@ pub struct SharedProviderState {

/// Manages the creation and cleanup of providers.
pub struct ProviderManager {
/// Handle to the Tauri application.
app_handle: AppHandle,

/// Map of active provider refs.
provider_refs: Arc<Mutex<HashMap<String, ProviderRef>>>,

/// Cache of provider emissions.
emit_cache: Arc<Mutex<HashMap<String, ProviderEmission>>>,

/// Shared state between providers.
shared_state: SharedProviderState,

/// Sender channel for provider emissions.
emit_tx: mpsc::UnboundedSender<ProviderEmission>,
}

Expand Down Expand Up @@ -66,20 +99,73 @@ impl ProviderManager {
};
}

let provider_ref = ProviderRef::new(
self.emit_tx.clone(),
config,
config_hash.clone(),
self.shared_state.clone(),
)
.await?;
let (stop_tx, stop_rx) = mpsc::channel::<()>(1);
let mut provider = self.create_provider(config, stop_rx)?;

let task_handle = match provider.runtime_type() {
RuntimeType::Async => task::spawn(async move {
provider.start_async().await;
info!("Provider stopped: {}", config_hash);
}),
RuntimeType::Sync => task::spawn_blocking(move || {
provider.start_sync();
info!("Provider stopped: {}", config_hash);
}),
};

let provider_ref = ProviderRef {
destroy_tx: self.emit_tx.clone(),
function_tx: self.emit_tx.clone(),
};

let mut providers = self.provider_refs.lock().await;
providers.insert(config_hash, provider_ref);
providers.insert(config_hash.to_string(), provider_ref);

Ok(())
}

fn create_provider(
&self,
config: ProviderConfig,
) -> anyhow::Result<Box<dyn Provider>> {
let provider: Box<dyn Provider> = match config {
ProviderConfig::Battery(config) => {
Box::new(BatteryProvider::new(config))
}
ProviderConfig::Cpu(config) => {
Box::new(CpuProvider::new(config, shared_state.sysinfo.clone()))
}
ProviderConfig::Host(config) => Box::new(HostProvider::new(config)),
ProviderConfig::Ip(config) => Box::new(IpProvider::new(config)),
#[cfg(windows)]
ProviderConfig::Komorebi(config) => {
Box::new(KomorebiProvider::new(config))
}
#[cfg(windows)]
ProviderConfig::Media(config) => {
Box::new(MediaProvider::new(config))
}
ProviderConfig::Memory(config) => {
Box::new(MemoryProvider::new(config, shared_state.sysinfo.clone()))
}
ProviderConfig::Disk(config) => Box::new(DiskProvider::new(config)),
ProviderConfig::Network(config) => {
Box::new(NetworkProvider::new(config))
}
ProviderConfig::Weather(config) => {
Box::new(WeatherProvider::new(config))
}
#[cfg(windows)]
ProviderConfig::Keyboard(config) => {
Box::new(KeyboardProvider::new(config))
}
#[allow(unreachable_patterns)]
_ => bail!("Provider not supported on this operating system."),
};

Ok(provider)
}

/// Sends a function call through a channel to be executed by the
/// provider.
///
Expand All @@ -100,7 +186,7 @@ impl ProviderManager {
}

/// Destroys and cleans up the provider with the given config.
pub async fn destroy(&self, config_hash: &str) -> anyhow::Result<()> {
pub async fn stop(&self, config_hash: &str) -> anyhow::Result<()> {
let mut provider_refs = self.provider_refs.lock().await;
let provider_ref = provider_refs
.remove(config_hash)
Expand Down
4 changes: 1 addition & 3 deletions packages/desktop/src/providers/provider_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@ use std::sync::Arc;

use anyhow::bail;
use serde::Serialize;
use serde_json::json;
use tauri::{AppHandle, Emitter};
use tokio::{
sync::{
mpsc::{self, UnboundedSender},
Mutex,
},
task,
};
use tracing::{info, warn};
use tracing::info;

use super::{
battery::BatteryProvider, cpu::CpuProvider, disk::DiskProvider,
Expand Down

0 comments on commit bdef4cf

Please sign in to comment.