diff --git a/src-tauri/src/db.rs b/src-tauri/src/db.rs index 9ebd141..74536dc 100644 --- a/src-tauri/src/db.rs +++ b/src-tauri/src/db.rs @@ -28,7 +28,6 @@ pub enum DatabaseGameStatus { Downloading, Installed, Updating, - Uninstalling, } diff --git a/src-tauri/src/downloads/download_manager.rs b/src-tauri/src/downloads/download_manager.rs index d71d801..f3406aa 100644 --- a/src-tauri/src/downloads/download_manager.rs +++ b/src-tauri/src/downloads/download_manager.rs @@ -1,69 +1,20 @@ use std::{ - collections::{HashMap, VecDeque}, + any::Any, + collections::VecDeque, sync::{ - mpsc::{channel, Receiver, Sender}, - Arc, Mutex, + mpsc::{SendError, Sender}, + Arc, Mutex, MutexGuard, }, - thread::spawn, + thread::JoinHandle, }; -use log::{info, warn}; +use log::info; use super::{ download_agent::{GameDownloadAgent, GameDownloadError}, - download_manager_interface::{AgentInterfaceData, DownloadManager}, - download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag}, progress_object::ProgressObject, queue::Queue, }; -/* - -Welcome to the download manager, the most overengineered, glorious piece of bullshit. - -The download manager takes a queue of game_ids and their associated -GameDownloadAgents, and then, one-by-one, executes them. It provides an interface -to interact with the currently downloading agent, and manage the queue. - -When the DownloadManager is initialised, it is designed to provide a reference -which can be used to provide some instructions (the DownloadManagerInterface), -but other than that, it runs without any sort of interruptions. - -It does this by opening up two data structures. Primarily is the command_receiver, -and mpsc (multi-channel-single-producer) which allows commands to be sent from -the Interface, and queued up for the Manager to process. - -These have been mapped in the DownloadManagerSignal docs. - -The other way to interact with the DownloadManager is via the donwload_queue, -which is just a collection of ids which may be rearranged to suit -whichever download queue order is required. - -+----------------------------------------------------------------------------+ -| DO NOT ATTEMPT TO ADD OR REMOVE FROM THE QUEUE WITHOUT USING SIGNALS!! | -| THIS WILL CAUSE A DESYNC BETWEEN THE DOWNLOAD AGENT REGISTRY AND THE QUEUE | -| WHICH HAS NOT BEEN ACCOUNTED FOR | -+----------------------------------------------------------------------------+ - -This download queue does not actually own any of the GameDownloadAgents. It is -simply a id-based reference system. The actual Agents are stored in the -download_agent_registry HashMap, as ordering is no issue here. This is why -appending or removing from the download_queue must be done via signals. - -Behold, my madness - quexeky - -*/ - -pub struct DownloadManagerBuilder { - download_agent_registry: HashMap>, - download_queue: Queue, - command_receiver: Receiver, - sender: Sender, - progress: Arc>>, - status: Arc>, - - current_game_interface: Option>, // Should be the only game download agent in the map with the "Go" flag - active_control_flag: Option, -} pub enum DownloadManagerSignal { /// Resumes (or starts) the DownloadManager Go, @@ -86,7 +37,7 @@ pub enum DownloadManagerStatus { Downloading, Paused, Empty, - Error, + Error(GameDownloadError), } pub enum GameDownloadStatus { Downloading, @@ -95,174 +46,120 @@ pub enum GameDownloadStatus { Error, } -impl DownloadManagerBuilder { - pub fn build() -> DownloadManager { - let queue = Queue::new(); - let (command_sender, command_receiver) = channel(); - let active_progress = Arc::new(Mutex::new(None)); - let status = Arc::new(Mutex::new(DownloadManagerStatus::Empty)); - - let manager = Self { - download_agent_registry: HashMap::new(), - download_queue: queue.clone(), - command_receiver, - current_game_interface: None, - active_control_flag: None, - status: status.clone(), - sender: command_sender.clone(), - progress: active_progress.clone(), - }; - - let terminator = spawn(|| manager.manage_queue()); - - DownloadManager::new(terminator, queue, active_progress, command_sender) - } - - fn manage_queue(mut self) -> Result<(), ()> { - loop { - let signal = match self.command_receiver.recv() { - Ok(signal) => signal, - Err(e) => return Err(()), - }; - - match signal { - DownloadManagerSignal::Go => { - self.manage_go_signal(); - } - DownloadManagerSignal::Stop => { - self.manage_stop_signal(); - } - DownloadManagerSignal::Completed(game_id) => { - self.manage_completed_signal(game_id); - } - DownloadManagerSignal::Queue(game_id, version, target_download_dir) => { - self.manage_queue_signal(game_id, version, target_download_dir); - } - DownloadManagerSignal::Finish => { - if let Some(active_control_flag) = self.active_control_flag { - active_control_flag.set(DownloadThreadControlFlag::Stop) - } - return Ok(()); - } - DownloadManagerSignal::Error(e) => { - self.manage_error_signal(e); - }, - DownloadManagerSignal::Cancel(id) => { - self.manage_cancel_signal(id); - }, - }; +/// Accessible front-end for the DownloadManager +/// +/// The system works entirely through signals, both internally and externally, +/// all of which are accessible through the DownloadManagerSignal type, but +/// should not be used directly. Rather, signals are abstracted through this +/// interface. +/// +/// The actual download queue may be accessed through the .edit() function, +/// which provides raw access to the underlying queue. +/// THIS EDITING IS BLOCKING!!! +pub struct DownloadManager { + terminator: JoinHandle>, + download_queue: Queue, + progress: Arc>>, + command_sender: Sender, +} +pub struct AgentInterfaceData { + pub id: String, + pub status: Mutex, +} +impl From> for AgentInterfaceData { + fn from(value: Arc) -> Self { + Self { + id: value.id.clone(), + status: Mutex::from(GameDownloadStatus::Uninitialised), } } - - fn manage_stop_signal(&mut self) { - info!("Got signal 'Stop'"); - if let Some(active_control_flag) = self.active_control_flag.clone() { - active_control_flag.set(DownloadThreadControlFlag::Stop); - } - } - - fn manage_completed_signal(&mut self, game_id: String) { - info!("Got signal 'Completed'"); - if let Some(interface) = &self.current_game_interface { - // When if let chains are stabilised, combine these two statements - if interface.id == game_id { - info!("Popping consumed data"); - self.download_queue.pop_front(); - self.download_agent_registry.remove(&game_id); - self.active_control_flag = None; - *self.progress.lock().unwrap() = None; - } - } - self.sender.send(DownloadManagerSignal::Go).unwrap(); - } - - fn manage_queue_signal(&mut self, id: String, version: String, target_download_dir: usize) { - info!("Got signal Queue"); - let download_agent = Arc::new(GameDownloadAgent::new( - id.clone(), - version, - target_download_dir, - self.sender.clone() - )); - let agent_status = GameDownloadStatus::Uninitialised; - let interface_data = AgentInterfaceData { - id, - status: Mutex::new(agent_status), - }; - self.download_agent_registry - .insert(interface_data.id.clone(), download_agent); - self.download_queue.append(interface_data); - } - - fn manage_go_signal(&mut self) { - info!("Got signal 'Go'"); - if self.active_control_flag.is_none() && !self.download_agent_registry.is_empty() { - info!("Starting download agent"); - let download_agent = { - let front = self.download_queue.read().front().unwrap().clone(); - self.download_agent_registry - .get(&front.id) - .unwrap() - .clone() - }; - let download_agent_interface = - Arc::new(AgentInterfaceData::from(download_agent.clone())); - self.current_game_interface = Some(download_agent_interface); - - let progress_object = download_agent.progress.clone(); - *self.progress.lock().unwrap() = Some(progress_object); - - let active_control_flag = download_agent.control_flag.clone(); - self.active_control_flag = Some(active_control_flag.clone()); - - let sender = self.sender.clone(); - - info!("Spawning download"); - spawn(move || { - match download_agent.download() { - Ok(_) => { - sender.send(DownloadManagerSignal::Completed(download_agent.id.clone())).unwrap(); - }, - Err(e) => { - warn!("Download failed"); - //todo!() // Account for if the setup_download function fails - }, - }; - }); - info!("Finished spawning Download"); - - active_control_flag.set(DownloadThreadControlFlag::Go); - self.set_status(DownloadManagerStatus::Downloading); - } else if let Some(active_control_flag) = self.active_control_flag.clone() { - info!("Restarting current download"); - active_control_flag.set(DownloadThreadControlFlag::Go); - } else { - info!("Nothing was set"); - } - } - fn manage_error_signal(&self, error: GameDownloadError) { - let current_status = self.current_game_interface.clone().unwrap(); - let mut lock = current_status.status.lock().unwrap(); - *lock = GameDownloadStatus::Error; - self.set_status(DownloadManagerStatus::Error); - } - fn manage_cancel_signal(&mut self, game_id: String) { - if let Some(current_flag) = &self.active_control_flag { - current_flag.set(DownloadThreadControlFlag::Stop); - self.active_control_flag = None; - *self.progress.lock().unwrap() = None; - } - self.download_agent_registry.remove(&game_id); - let mut lock = self.download_queue.edit(); - let index = match lock.iter().position(|interface| interface.id == game_id) { - Some(index) => index, - None => return, - }; - lock.remove(index); - self.sender.send(DownloadManagerSignal::Go).unwrap(); - info!("{:?}", self.download_agent_registry.iter().map(|x| x.0.clone()).collect::()); - } - fn set_status(&self, status: DownloadManagerStatus) { - *self.status.lock().unwrap() = status; - } +} + +impl DownloadManager { + pub fn new( + terminator: JoinHandle>, + download_queue: Queue, + progress: Arc>>, + command_sender: Sender, + ) -> Self { + Self { + terminator, + download_queue, + progress, + command_sender, + } + } + + pub fn queue_game( + &self, + id: String, + version: String, + target_download_dir: usize, + ) -> Result<(), SendError> { + info!("Adding game id {}", id); + self.command_sender.send(DownloadManagerSignal::Queue( + id, + version, + target_download_dir, + ))?; + self.command_sender.send(DownloadManagerSignal::Go) + } + pub fn cancel_download( + &self, + game_id: String + ) { + self.command_sender.send(DownloadManagerSignal::Cancel(game_id)).unwrap(); + } + pub fn edit(&self) -> MutexGuard<'_, VecDeque>> { + self.download_queue.edit() + } + pub fn read_queue(&self) -> VecDeque> { + self.download_queue.read() + } + pub fn get_current_game_download_progress(&self) -> Option { + let progress_object = (*self.progress.lock().unwrap()).clone()?; + Some(progress_object.get_progress()) + } + pub fn rearrange_string(&self, id: String, new_index: usize) { + let mut queue = self.edit(); + let current_index = get_index_from_id(&mut queue, id).unwrap(); + let to_move = queue.remove(current_index).unwrap(); + queue.insert(new_index, to_move); + } + pub fn rearrange(&self, current_index: usize, new_index: usize) { + let mut queue = self.edit(); + let to_move = queue.remove(current_index).unwrap(); + queue.insert(new_index, to_move); + } + pub fn remove_from_queue(&self, index: usize) { + self.edit().remove(index); + } + pub fn remove_from_queue_string(&self, id: String) { + let mut queue = self.edit(); + let current_index = get_index_from_id(&mut queue, id).unwrap(); + queue.remove(current_index); + } + pub fn pause_downloads(&self) -> Result<(), SendError> { + self.command_sender.send(DownloadManagerSignal::Stop) + } + pub fn resume_downloads(&self) -> Result<(), SendError> { + self.command_sender.send(DownloadManagerSignal::Go) + } + pub fn ensure_terminated(self) -> Result, Box> { + self.command_sender + .send(DownloadManagerSignal::Finish) + .unwrap(); + self.terminator.join() + } +} + +/// Takes in the locked value from .edit() and attempts to +/// get the index of whatever game_id is passed in +fn get_index_from_id( + queue: &mut MutexGuard<'_, VecDeque>>, + id: String, +) -> Option { + queue + .iter() + .position(|download_agent| download_agent.id == id) } diff --git a/src-tauri/src/downloads/download_manager_builder.rs b/src-tauri/src/downloads/download_manager_builder.rs new file mode 100644 index 0000000..e696abf --- /dev/null +++ b/src-tauri/src/downloads/download_manager_builder.rs @@ -0,0 +1,252 @@ +use std::{ + collections::HashMap, + sync::{ + mpsc::{channel, Receiver, Sender}, + Arc, Mutex, + }, + thread::spawn, +}; + +use log::{error, info, warn}; + +use super::{ + download_agent::{GameDownloadAgent, GameDownloadError}, + download_manager::{ + AgentInterfaceData, DownloadManager, DownloadManagerSignal, DownloadManagerStatus, + GameDownloadStatus, + }, + download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag}, + progress_object::ProgressObject, + queue::Queue, +}; + +/* + +Welcome to the download manager, the most overengineered, glorious piece of bullshit. + +The download manager takes a queue of game_ids and their associated +GameDownloadAgents, and then, one-by-one, executes them. It provides an interface +to interact with the currently downloading agent, and manage the queue. + +When the DownloadManager is initialised, it is designed to provide a reference +which can be used to provide some instructions (the DownloadManagerInterface), +but other than that, it runs without any sort of interruptions. + +It does this by opening up two data structures. Primarily is the command_receiver, +and mpsc (multi-channel-single-producer) which allows commands to be sent from +the Interface, and queued up for the Manager to process. + +These have been mapped in the DownloadManagerSignal docs. + +The other way to interact with the DownloadManager is via the donwload_queue, +which is just a collection of ids which may be rearranged to suit +whichever download queue order is required. + ++----------------------------------------------------------------------------+ +| DO NOT ATTEMPT TO ADD OR REMOVE FROM THE QUEUE WITHOUT USING SIGNALS!! | +| THIS WILL CAUSE A DESYNC BETWEEN THE DOWNLOAD AGENT REGISTRY AND THE QUEUE | +| WHICH HAS NOT BEEN ACCOUNTED FOR | ++----------------------------------------------------------------------------+ + +This download queue does not actually own any of the GameDownloadAgents. It is +simply a id-based reference system. The actual Agents are stored in the +download_agent_registry HashMap, as ordering is no issue here. This is why +appending or removing from the download_queue must be done via signals. + +Behold, my madness - quexeky + +*/ + +pub struct DownloadManagerBuilder { + download_agent_registry: HashMap>, + download_queue: Queue, + command_receiver: Receiver, + sender: Sender, + progress: Arc>>, + status: Arc>, + + current_game_interface: Option>, // Should be the only game download agent in the map with the "Go" flag + active_control_flag: Option, +} + +impl DownloadManagerBuilder { + pub fn build() -> DownloadManager { + let queue = Queue::new(); + let (command_sender, command_receiver) = channel(); + let active_progress = Arc::new(Mutex::new(None)); + let status = Arc::new(Mutex::new(DownloadManagerStatus::Empty)); + + let manager = Self { + download_agent_registry: HashMap::new(), + download_queue: queue.clone(), + command_receiver, + current_game_interface: None, + active_control_flag: None, + status: status.clone(), + sender: command_sender.clone(), + progress: active_progress.clone(), + }; + + let terminator = spawn(|| manager.manage_queue()); + + DownloadManager::new(terminator, queue, active_progress, command_sender) + } + + fn manage_queue(mut self) -> Result<(), ()> { + loop { + let signal = match self.command_receiver.recv() { + Ok(signal) => signal, + Err(_) => return Err(()), + }; + + match signal { + DownloadManagerSignal::Go => { + self.manage_go_signal(); + } + DownloadManagerSignal::Stop => { + self.manage_stop_signal(); + } + DownloadManagerSignal::Completed(game_id) => { + self.manage_completed_signal(game_id); + } + DownloadManagerSignal::Queue(game_id, version, target_download_dir) => { + self.manage_queue_signal(game_id, version, target_download_dir); + } + DownloadManagerSignal::Finish => { + if let Some(active_control_flag) = self.active_control_flag { + active_control_flag.set(DownloadThreadControlFlag::Stop) + } + return Ok(()); + } + DownloadManagerSignal::Error(e) => { + self.manage_error_signal(e); + } + DownloadManagerSignal::Cancel(id) => { + self.manage_cancel_signal(id); + } + }; + } + } + + fn manage_stop_signal(&mut self) { + info!("Got signal 'Stop'"); + if let Some(active_control_flag) = self.active_control_flag.clone() { + active_control_flag.set(DownloadThreadControlFlag::Stop); + } + } + + fn manage_completed_signal(&mut self, game_id: String) { + info!("Got signal 'Completed'"); + if let Some(interface) = &self.current_game_interface { + // When if let chains are stabilised, combine these two statements + if interface.id == game_id { + info!("Popping consumed data"); + self.download_queue.pop_front(); + self.download_agent_registry.remove(&game_id); + self.active_control_flag = None; + *self.progress.lock().unwrap() = None; + } + } + self.sender.send(DownloadManagerSignal::Go).unwrap(); + } + + fn manage_queue_signal(&mut self, id: String, version: String, target_download_dir: usize) { + info!("Got signal Queue"); + let download_agent = Arc::new(GameDownloadAgent::new( + id.clone(), + version, + target_download_dir, + self.sender.clone(), + )); + let agent_status = GameDownloadStatus::Uninitialised; + let interface_data = AgentInterfaceData { + id, + status: Mutex::new(agent_status), + }; + self.download_agent_registry + .insert(interface_data.id.clone(), download_agent); + self.download_queue.append(interface_data); + } + + fn manage_go_signal(&mut self) { + info!("Got signal 'Go'"); + if self.active_control_flag.is_none() && !self.download_agent_registry.is_empty() { + info!("Starting download agent"); + let download_agent = { + let front = self.download_queue.read().front().unwrap().clone(); + self.download_agent_registry.get(&front.id).unwrap().clone() + }; + let download_agent_interface = + Arc::new(AgentInterfaceData::from(download_agent.clone())); + self.current_game_interface = Some(download_agent_interface); + + let progress_object = download_agent.progress.clone(); + *self.progress.lock().unwrap() = Some(progress_object); + + let active_control_flag = download_agent.control_flag.clone(); + self.active_control_flag = Some(active_control_flag.clone()); + + let sender = self.sender.clone(); + + info!("Spawning download"); + spawn(move || { + match download_agent.download() { + Ok(_) => { + // TODO wrap this pattern in a macro + let result = sender + .send(DownloadManagerSignal::Completed(download_agent.id.clone())); + if let Err(err) = result { + error!("{}", err); + } + } + Err(err) => { + let result = sender.send(DownloadManagerSignal::Error(err)); + if let Err(err) = result { + error!("{}", err); + } + } + }; + }); + info!("Finished spawning Download"); + + active_control_flag.set(DownloadThreadControlFlag::Go); + self.set_status(DownloadManagerStatus::Downloading); + } else if let Some(active_control_flag) = self.active_control_flag.clone() { + info!("Restarting current download"); + active_control_flag.set(DownloadThreadControlFlag::Go); + } else { + info!("Nothing was set"); + } + } + fn manage_error_signal(&self, error: GameDownloadError) { + let current_status = self.current_game_interface.clone().unwrap(); + let mut lock = current_status.status.lock().unwrap(); + *lock = GameDownloadStatus::Error; + self.set_status(DownloadManagerStatus::Error(error)); + } + fn manage_cancel_signal(&mut self, game_id: String) { + if let Some(current_flag) = &self.active_control_flag { + current_flag.set(DownloadThreadControlFlag::Stop); + self.active_control_flag = None; + *self.progress.lock().unwrap() = None; + } + self.download_agent_registry.remove(&game_id); + let mut lock = self.download_queue.edit(); + let index = match lock.iter().position(|interface| interface.id == game_id) { + Some(index) => index, + None => return, + }; + lock.remove(index); + self.sender.send(DownloadManagerSignal::Go).unwrap(); + info!( + "{:?}", + self.download_agent_registry + .iter() + .map(|x| x.0.clone()) + .collect::() + ); + } + fn set_status(&self, status: DownloadManagerStatus) { + *self.status.lock().unwrap() = status; + } +} diff --git a/src-tauri/src/downloads/download_manager_interface.rs b/src-tauri/src/downloads/download_manager_interface.rs deleted file mode 100644 index 0ecf2bd..0000000 --- a/src-tauri/src/downloads/download_manager_interface.rs +++ /dev/null @@ -1,135 +0,0 @@ -use std::{ - any::Any, - collections::VecDeque, - sync::{ - mpsc::{SendError, Sender}, - Arc, Mutex, MutexGuard, - }, - thread::JoinHandle, -}; - -use log::info; - -use super::{ - download_agent::GameDownloadAgent, - download_manager::{DownloadManagerSignal, GameDownloadStatus}, - progress_object::ProgressObject, queue::Queue, -}; - -/// Accessible front-end for the DownloadManager -/// -/// The system works entirely through signals, both internally and externally, -/// all of which are accessible through the DownloadManagerSignal type, but -/// should not be used directly. Rather, signals are abstracted through this -/// interface. -/// -/// The actual download queue may be accessed through the .edit() function, -/// which provides raw access to the underlying queue. -/// THIS EDITING IS BLOCKING!!! -pub struct DownloadManager { - terminator: JoinHandle>, - download_queue: Queue, - progress: Arc>>, - command_sender: Sender, -} -pub struct AgentInterfaceData { - pub id: String, - pub status: Mutex, -} -impl From> for AgentInterfaceData { - fn from(value: Arc) -> Self { - Self { - id: value.id.clone(), - status: Mutex::from(GameDownloadStatus::Uninitialised), - } - } -} - -impl DownloadManager { - pub fn new( - terminator: JoinHandle>, - download_queue: Queue, - progress: Arc>>, - command_sender: Sender, - ) -> Self { - Self { - terminator, - download_queue, - progress, - command_sender, - } - } - - pub fn queue_game( - &self, - id: String, - version: String, - target_download_dir: usize, - ) -> Result<(), SendError> { - info!("Adding game id {}", id); - self.command_sender.send(DownloadManagerSignal::Queue( - id, - version, - target_download_dir, - ))?; - self.command_sender.send(DownloadManagerSignal::Go) - } - pub fn cancel_download( - &self, - game_id: String - ) { - self.command_sender.send(DownloadManagerSignal::Cancel(game_id)).unwrap(); - } - pub fn edit(&self) -> MutexGuard<'_, VecDeque>> { - self.download_queue.edit() - } - pub fn read_queue(&self) -> VecDeque> { - self.download_queue.read() - } - pub fn get_current_game_download_progress(&self) -> Option { - let progress_object = (*self.progress.lock().unwrap()).clone()?; - Some(progress_object.get_progress()) - } - pub fn rearrange_string(&self, id: String, new_index: usize) { - let mut queue = self.edit(); - let current_index = get_index_from_id(&mut queue, id).unwrap(); - let to_move = queue.remove(current_index).unwrap(); - queue.insert(new_index, to_move); - } - pub fn rearrange(&self, current_index: usize, new_index: usize) { - let mut queue = self.edit(); - let to_move = queue.remove(current_index).unwrap(); - queue.insert(new_index, to_move); - } - pub fn remove_from_queue(&self, index: usize) { - self.edit().remove(index); - } - pub fn remove_from_queue_string(&self, id: String) { - let mut queue = self.edit(); - let current_index = get_index_from_id(&mut queue, id).unwrap(); - queue.remove(current_index); - } - pub fn pause_downloads(&self) -> Result<(), SendError> { - self.command_sender.send(DownloadManagerSignal::Stop) - } - pub fn resume_downloads(&self) -> Result<(), SendError> { - self.command_sender.send(DownloadManagerSignal::Go) - } - pub fn ensure_terminated(self) -> Result, Box> { - self.command_sender - .send(DownloadManagerSignal::Finish) - .unwrap(); - self.terminator.join() - } -} - -/// Takes in the locked value from .edit() and attempts to -/// get the index of whatever game_id is passed in -fn get_index_from_id( - queue: &mut MutexGuard<'_, VecDeque>>, - id: String, -) -> Option { - queue - .iter() - .position(|download_agent| download_agent.id == id) -} diff --git a/src-tauri/src/downloads/mod.rs b/src-tauri/src/downloads/mod.rs index 3556f81..c7c11ee 100644 --- a/src-tauri/src/downloads/mod.rs +++ b/src-tauri/src/downloads/mod.rs @@ -1,8 +1,8 @@ pub mod download_agent; pub mod download_commands; mod download_logic; +pub mod download_manager_builder; pub mod download_manager; -pub mod download_manager_interface; mod download_thread_control_flag; mod manifest; mod progress_object; diff --git a/src-tauri/src/downloads/queue.rs b/src-tauri/src/downloads/queue.rs index de1be17..1ce695f 100644 --- a/src-tauri/src/downloads/queue.rs +++ b/src-tauri/src/downloads/queue.rs @@ -1,6 +1,6 @@ use std::{collections::VecDeque, sync::{Arc, Mutex, MutexGuard}}; -use super::download_manager_interface::AgentInterfaceData; +use super::download_manager::AgentInterfaceData; #[derive(Clone)] pub struct Queue { diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index ce9462e..840b803 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -10,13 +10,16 @@ mod tests; use crate::db::DatabaseImpls; use auth::{auth_initiate, generate_authorization_header, recieve_handshake, retry_connect}; -use db::{add_download_dir, delete_download_dir, fetch_download_dir_stats, DatabaseInterface, DATA_ROOT_DIR}; +use db::{ + add_download_dir, delete_download_dir, fetch_download_dir_stats, DatabaseInterface, + DATA_ROOT_DIR, +}; use downloads::download_commands::*; -use downloads::download_manager::DownloadManagerBuilder; -use downloads::download_manager_interface::DownloadManager; +use downloads::download_manager_builder::DownloadManagerBuilder; +use downloads::download_manager::DownloadManager; use env_logger::Env; use http::{header::*, response::Builder as ResponseBuilder}; -use library::{fetch_game, fetch_library, Game}; +use library::{fetch_game, fetch_game_status, fetch_library, Game}; use log::{debug, info}; use remote::{gen_drop_url, use_remote, RemoteAccessError}; use serde::{Deserialize, Serialize}; @@ -130,6 +133,7 @@ pub fn run() { add_download_dir, delete_download_dir, fetch_download_dir_stats, + fetch_game_status, // Downloads download_game, get_current_game_download_progress, diff --git a/src-tauri/src/library.rs b/src-tauri/src/library.rs index 50da6af..3fbea71 100644 --- a/src-tauri/src/library.rs +++ b/src-tauri/src/library.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; use serde_json::json; use tauri::{AppHandle, Manager}; +use crate::db; use crate::db::DatabaseGameStatus; use crate::db::DatabaseImpls; use crate::remote::RemoteAccessError; @@ -109,3 +110,17 @@ pub fn fetch_game(id: String, app: tauri::AppHandle) -> Result { Ok(result.unwrap()) } + +#[tauri::command] +pub fn fetch_game_status(id: String) -> Result { + let db_handle = DB.borrow_data().unwrap(); + let status = db_handle + .games + .games_statuses + .get(&id) + .unwrap_or(&DatabaseGameStatus::Remote) + .clone(); + drop(db_handle); + + return Ok(status); +}