diff --git a/desktop/src-tauri/src/db.rs b/desktop/src-tauri/src/db.rs index a88bc326..a427b37a 100644 --- a/desktop/src-tauri/src/db.rs +++ b/desktop/src-tauri/src/db.rs @@ -23,7 +23,7 @@ pub struct DatabaseAuth { // Strings are version names for a particular game #[derive(Serialize, Clone, Deserialize)] #[serde(tag = "type")] -pub enum GameStatus { +pub enum ApplicationStatus { Remote {}, SetupRequired { version_name: String, @@ -37,7 +37,7 @@ pub enum GameStatus { // Stuff that shouldn't be synced to disk #[derive(Clone, Serialize)] -pub enum GameTransientStatus { +pub enum ApplicationTransientStatus { Downloading { version_name: String }, Uninstalling {}, Updating { version_name: String }, @@ -46,7 +46,7 @@ pub enum GameTransientStatus { #[derive(Serialize, Deserialize, Clone)] #[serde(rename_all = "camelCase")] -pub struct GameVersion { +pub struct ApplicationVersion { pub version_index: usize, pub version_name: String, pub launch_command: String, @@ -55,14 +55,15 @@ pub struct GameVersion { } #[derive(Serialize, Clone, Deserialize)] -pub struct DatabaseGames { +#[serde(rename_all = "camelCase")] +pub struct DatabaseApplications { pub install_dirs: Vec, // Guaranteed to exist if the game also exists in the app state map - pub statuses: HashMap, - pub versions: HashMap>, + pub statuses: HashMap, + pub versions: HashMap>, #[serde(skip)] - pub transient_statuses: HashMap, + pub transient_statuses: HashMap, } #[derive(Serialize, Deserialize, Clone)] @@ -86,7 +87,7 @@ pub struct Database { pub settings: Settings, pub auth: Option, pub base_url: String, - pub games: DatabaseGames, + pub applications: DatabaseApplications, } pub static DATA_ROOT_DIR: LazyLock> = LazyLock::new(|| Mutex::new(BaseDirs::new().unwrap().data_dir().join("drop"))); @@ -136,7 +137,7 @@ impl DatabaseImpls for DatabaseInterface { settings: Settings::default(), auth: None, base_url: "".to_string(), - games: DatabaseGames { + applications: DatabaseApplications { install_dirs: vec![games_base_dir.to_str().unwrap().to_string()], statuses: HashMap::new(), transient_statuses: HashMap::new(), @@ -187,10 +188,10 @@ pub fn add_download_dir(new_dir: String) -> Result<(), String> { // Add it to the dictionary let mut lock = DB.borrow_data_mut().unwrap(); - if lock.games.install_dirs.contains(&new_dir) { + if lock.applications.install_dirs.contains(&new_dir) { return Err("Download directory already used".to_string()); } - lock.games.install_dirs.push(new_dir); + lock.applications.install_dirs.push(new_dir); drop(lock); DB.save().unwrap(); @@ -200,7 +201,7 @@ pub fn add_download_dir(new_dir: String) -> Result<(), String> { #[tauri::command] pub fn delete_download_dir(index: usize) -> Result<(), String> { let mut lock = DB.borrow_data_mut().unwrap(); - lock.games.install_dirs.remove(index); + lock.applications.install_dirs.remove(index); drop(lock); DB.save().unwrap(); @@ -212,7 +213,7 @@ pub fn delete_download_dir(index: usize) -> Result<(), String> { #[tauri::command] pub fn fetch_download_dir_stats() -> Result, String> { let lock = DB.borrow_data().unwrap(); - let directories = lock.games.install_dirs.clone(); + let directories = lock.applications.install_dirs.clone(); drop(lock); Ok(directories) diff --git a/desktop/src-tauri/src/download_manager/download_manager.rs b/desktop/src-tauri/src/download_manager/download_manager.rs index 7945d6da..ede48e10 100644 --- a/desktop/src-tauri/src/download_manager/download_manager.rs +++ b/desktop/src-tauri/src/download_manager/download_manager.rs @@ -12,18 +12,23 @@ use std::{ use log::info; use serde::Serialize; -use crate::downloads::download_agent::{GameDownloadAgent, GameDownloadError}; +use crate::downloads::download_agent::GameDownloadError; -use super::{download_manager_builder::CurrentProgressObject, progress_object::ProgressObject, queue::Queue}; +use super::{download_manager_builder::{CurrentProgressObject, DownloadableQueueStandin}, downloadable::Downloadable, queue::Queue}; + +pub enum DownloadType { + Game, + Tool, +} pub enum DownloadManagerSignal { /// Resumes (or starts) the DownloadManager Go, /// Pauses the DownloadManager Stop, - /// Called when a GameDownloadAgent has fully completed a download. + /// Called when a DownloadAgent has fully completed a download. Completed(String), - /// Generates and appends a GameDownloadAgent + /// Generates and appends a DownloadAgent /// to the registry and queue Queue(String, String, usize), /// Tells the Manager to stop the current @@ -32,15 +37,15 @@ pub enum DownloadManagerSignal { Finish, /// Stops (but doesn't remove) current download Cancel, - /// Removes a given game + /// Removes a given application Remove(String), /// Any error which occurs in the agent Error(GameDownloadError), /// Pushes UI update UpdateUIQueue, UpdateUIStats(usize, usize), //kb/s and seconds - /// Uninstall game - /// Takes game ID + /// Uninstall download + /// Takes download ID Uninstall(String), } @@ -63,7 +68,7 @@ impl Serialize for DownloadManagerStatus { } #[derive(Serialize, Clone)] -pub enum GameDownloadStatus { +pub enum DownloadStatus { Queued, Downloading, Error, @@ -85,23 +90,18 @@ pub struct DownloadManager { progress: CurrentProgressObject, command_sender: Sender, } -pub struct GameDownloadAgentQueueStandin { - pub id: String, - pub status: Mutex, - pub progress: Arc, -} -impl From> for GameDownloadAgentQueueStandin { - fn from(value: Arc) -> Self { +impl From> for DownloadableQueueStandin { + fn from(value: Arc) -> Self { Self { - id: value.id.clone(), - status: Mutex::from(GameDownloadStatus::Queued), - progress: value.progress.clone(), + id: value.id(), + status: Mutex::from(DownloadStatus::Queued), + progress: value.progress().clone(), } } } -impl Debug for GameDownloadAgentQueueStandin { +impl Debug for DownloadableQueueStandin { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("GameDownloadAgentQueueStandin") + f.debug_struct("DownloadableQueueStandin") .field("id", &self.id) .finish() } @@ -123,13 +123,13 @@ impl DownloadManager { } } - pub fn queue_game( + pub fn queue_download( &self, id: String, version: String, target_download_dir: usize, ) -> Result<(), SendError> { - info!("Adding game id {}", id); + info!("Adding download id {}", id); self.command_sender.send(DownloadManagerSignal::Queue( id, version, @@ -137,13 +137,13 @@ impl DownloadManager { ))?; self.command_sender.send(DownloadManagerSignal::Go) } - pub fn edit(&self) -> MutexGuard<'_, VecDeque>> { + pub fn edit(&self) -> MutexGuard<'_, VecDeque>> { self.download_queue.edit() } - pub fn read_queue(&self) -> VecDeque> { + pub fn read_queue(&self) -> VecDeque> { self.download_queue.read() } - pub fn get_current_game_download_progress(&self) -> Option { + pub fn get_current_download_progress(&self) -> Option { let progress_object = (*self.progress.lock().unwrap()).clone()?; Some(progress_object.get_progress()) } @@ -156,9 +156,9 @@ impl DownloadManager { .send(DownloadManagerSignal::UpdateUIQueue) .unwrap(); } - pub fn cancel(&self, game_id: String) { + pub fn cancel(&self, id: String) { self.command_sender - .send(DownloadManagerSignal::Remove(game_id)) + .send(DownloadManagerSignal::Remove(id)) .unwrap(); } pub fn rearrange(&self, current_index: usize, new_index: usize) { @@ -202,17 +202,17 @@ impl DownloadManager { .unwrap(); self.terminator.join() } - pub fn uninstall_game(&self, game_id: String) { + pub fn uninstall_application(&self, id: String) { self.command_sender - .send(DownloadManagerSignal::Uninstall(game_id)) + .send(DownloadManagerSignal::Uninstall(id)) .unwrap(); } } /// Takes in the locked value from .edit() and attempts to -/// get the index of whatever game_id is passed in +/// get the index of whatever id is passed in fn get_index_from_id( - queue: &mut MutexGuard<'_, VecDeque>>, + queue: &mut MutexGuard<'_, VecDeque>>, id: String, ) -> Option { queue diff --git a/desktop/src-tauri/src/download_manager/download_manager_builder.rs b/desktop/src-tauri/src/download_manager/download_manager_builder.rs index fd534458..c36867b2 100644 --- a/desktop/src-tauri/src/download_manager/download_manager_builder.rs +++ b/desktop/src-tauri/src/download_manager/download_manager_builder.rs @@ -12,20 +12,20 @@ use log::{error, info}; use tauri::{AppHandle, Emitter}; use crate::{ - db::{Database, GameStatus, GameTransientStatus}, download_manager::download_manager::GameDownloadStatus, downloads::download_agent::{GameDownloadAgent, GameDownloadError}, library::{ - on_game_complete, push_game_update, QueueUpdateEvent, + db::{Database, ApplicationStatus, ApplicationTransientStatus}, download_manager::download_manager::DownloadStatus, downloads::download_agent::{GameDownloadAgent, GameDownloadError}, library::{ + on_game_complete, push_application_update, QueueUpdateEvent, QueueUpdateEventQueueData, StatsUpdateEvent, }, state::GameStatusManager, DB }; -use super::{download_manager::{DownloadManager, DownloadManagerSignal, DownloadManagerStatus, GameDownloadAgentQueueStandin}, download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag}, downloadable::Downloadable, progress_object::ProgressObject, queue::Queue}; +use super::{download_manager::{DownloadManager, DownloadManagerSignal, DownloadManagerStatus}, download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag}, downloadable::Downloadable, 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 +The download manager takes a queue of ids and their associated +DownloadAgents, 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 @@ -48,7 +48,7 @@ whichever download queue order is required. | WHICH HAS NOT BEEN ACCOUNTED FOR | +----------------------------------------------------------------------------+ -This download queue does not actually own any of the GameDownloadAgents. It is +This download queue does not actually own any of the DownloadAgents. 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. @@ -70,10 +70,15 @@ pub struct DownloadManagerBuilder { status: Arc>, app_handle: AppHandle, - current_download_agent: Option>, // Should be the only game download agent in the map with the "Go" flag + current_download_agent: Option>, // Should be the only download agent in the map with the "Go" flag current_download_thread: Mutex>>, active_control_flag: Option, } +pub struct DownloadableQueueStandin { + pub id: String, + pub status: Mutex, + pub progress: Arc, +} impl DownloadManagerBuilder { pub fn build(app_handle: AppHandle) -> DownloadManager { @@ -101,7 +106,7 @@ impl DownloadManagerBuilder { DownloadManager::new(terminator, queue, active_progress, command_sender) } - fn set_game_status, &String)>( + fn set_download_status, &String)>( &self, id: String, setter: F, @@ -113,7 +118,7 @@ impl DownloadManagerBuilder { let status = GameStatusManager::fetch_state(&id); - push_game_update(&self.app_handle, id, status); + push_application_update(&self.app_handle, id, status); } fn push_ui_stats_update(&self, kbs: usize, time: usize) { @@ -157,9 +162,9 @@ impl DownloadManagerBuilder { drop(download_thread_lock); } - fn remove_and_cleanup_front_game(&mut self, game_id: &String) -> DownloadAgent { + fn remove_and_cleanup_front_download(&mut self, id: &String) -> DownloadAgent { self.download_queue.pop_front(); - let download_agent = self.download_agent_registry.remove(game_id).unwrap(); + let download_agent = self.download_agent_registry.remove(id).unwrap(); self.cleanup_current_download(); download_agent } @@ -190,11 +195,11 @@ impl DownloadManagerBuilder { DownloadManagerSignal::Stop => { self.manage_stop_signal(); } - DownloadManagerSignal::Completed(game_id) => { - self.manage_completed_signal(game_id); + DownloadManagerSignal::Completed(id) => { + self.manage_completed_signal(id); } - DownloadManagerSignal::Queue(game_id, version, target_download_dir) => { - self.manage_queue_signal(game_id, version, target_download_dir); + DownloadManagerSignal::Queue(id, version, target_download_dir) => { + self.manage_queue_signal(id, version, target_download_dir); } DownloadManagerSignal::Error(e) => { self.manage_error_signal(e); @@ -212,54 +217,54 @@ impl DownloadManagerBuilder { self.stop_and_wait_current_download(); return Ok(()); } - DownloadManagerSignal::Remove(game_id) => { - self.manage_remove_game_queue(game_id); + DownloadManagerSignal::Remove(id) => { + self.manage_remove_download_from_queue(id); } - DownloadManagerSignal::Uninstall(game_id) => { - self.uninstall_game(game_id); + DownloadManagerSignal::Uninstall(id) => { + self.uninstall_application(id); } }; } } - fn uninstall_game(&mut self, game_id: String) { - // Removes the game if it's in the queue - self.manage_remove_game_queue(game_id.clone()); + fn uninstall_application(&mut self, id: String) { + // Removes the download if it's in the queue + self.manage_remove_download_from_queue(id.clone()); let mut db_handle = DB.borrow_data_mut().unwrap(); db_handle - .games + .applications .transient_statuses - .entry(game_id.clone()) - .and_modify(|v| *v = GameTransientStatus::Uninstalling {}); - push_game_update( + .entry(id.clone()) + .and_modify(|v| *v = ApplicationTransientStatus::Uninstalling {}); + push_application_update( &self.app_handle, - game_id.clone(), - (None, Some(GameTransientStatus::Uninstalling {})), + id.clone(), + (None, Some(ApplicationTransientStatus::Uninstalling {})), ); - let previous_state = db_handle.games.statuses.get(&game_id).cloned(); + let previous_state = db_handle.applications.statuses.get(&id).cloned(); if previous_state.is_none() { info!("uninstall job doesn't have previous state, failing silently"); return; } let previous_state = previous_state.unwrap(); if let Some((version_name, install_dir)) = match previous_state { - GameStatus::Installed { + ApplicationStatus::Installed { version_name, install_dir, } => Some((version_name, install_dir)), - GameStatus::SetupRequired { + ApplicationStatus::SetupRequired { version_name, install_dir, } => Some((version_name, install_dir)), _ => None, } { db_handle - .games + .applications .transient_statuses - .entry(game_id.clone()) - .and_modify(|v| *v = GameTransientStatus::Uninstalling {}); + .entry(id.clone()) + .and_modify(|v| *v = ApplicationTransientStatus::Uninstalling {}); drop(db_handle); let sender = self.sender.clone(); @@ -274,36 +279,36 @@ impl DownloadManagerBuilder { } Ok(_) => { let mut db_handle = DB.borrow_data_mut().unwrap(); - db_handle.games.transient_statuses.remove(&game_id); + db_handle.applications.transient_statuses.remove(&id); db_handle - .games + .applications .statuses - .entry(game_id.clone()) - .and_modify(|e| *e = GameStatus::Remote {}); + .entry(id.clone()) + .and_modify(|e| *e = ApplicationStatus::Remote {}); drop(db_handle); DB.save().unwrap(); - info!("uninstalled {}", game_id); + info!("uninstalled {}", id); - push_game_update(&app_handle, game_id, (Some(GameStatus::Remote {}), None)); + push_application_update(&app_handle, id, (Some(ApplicationStatus::Remote {}), None)); } }); } } - fn manage_remove_game_queue(&mut self, game_id: String) { + fn manage_remove_download_from_queue(&mut self, id: String) { if let Some(current_download) = &self.current_download_agent { - if current_download.id == game_id { + if current_download.id == id { self.manage_cancel_signal(); } } - let index = self.download_queue.get_by_id(game_id.clone()); + let index = self.download_queue.get_by_id(id.clone()); if let Some(index) = index { let mut queue_handle = self.download_queue.edit(); queue_handle.remove(index); - self.set_game_status(game_id, |db_handle, id| { - db_handle.games.transient_statuses.remove(id); + self.set_download_status(id, |db_handle, id| { + db_handle.applications.transient_statuses.remove(id); }); drop(queue_handle); } @@ -323,13 +328,13 @@ impl DownloadManagerBuilder { } } - fn manage_completed_signal(&mut self, game_id: String) { + fn manage_completed_signal(&mut self, id: String) { info!("Got signal 'Completed'"); if let Some(interface) = &self.current_download_agent { // When if let chains are stabilised, combine these two statements - if interface.id == game_id { + if interface.id == id { info!("Popping consumed data"); - let download_agent = self.remove_and_cleanup_front_game(&game_id); + let download_agent = self.remove_and_cleanup_front_download(&id); let download_agent_lock = download_agent.lock().unwrap(); let version = download_agent_lock.version(); @@ -338,7 +343,7 @@ impl DownloadManagerBuilder { drop(download_agent_lock); if let Err(error) = - on_game_complete(game_id, version, install_dir, &self.app_handle) + on_game_complete(id, version, install_dir, &self.app_handle) { error!("failed to mark game as completed: {}", error); // TODO mark game as remote so user can retry @@ -359,13 +364,13 @@ impl DownloadManagerBuilder { if let Some(download_agent) = self.download_agent_registry.get(&id) { let download_agent_handle = download_agent.lock().unwrap(); if download_agent_handle.version() == version { - info!("game with same version already queued, skipping"); + info!("Application with same version already queued, skipping"); return; } // If it's not the same, we want to cancel the current one, and then add the new one drop(download_agent_handle); - self.manage_remove_game_queue(id.clone()); + self.manage_remove_download_from_queue(id.clone()); } } @@ -377,8 +382,8 @@ impl DownloadManagerBuilder { ))); let download_agent_lock = download_agent.lock().unwrap(); - let agent_status = GameDownloadStatus::Queued; - let interface_data = GameDownloadAgentQueueStandin { + let agent_status = DownloadStatus::Queued; + let interface_data = DownloadableQueueStandin { id: id.clone(), status: Mutex::new(agent_status), progress: download_agent_lock.progress.clone(), @@ -391,10 +396,10 @@ impl DownloadManagerBuilder { .insert(interface_data.id.clone(), download_agent); self.download_queue.append(interface_data); - self.set_game_status(id, |db, id| { - db.games.transient_statuses.insert( + self.set_download_status(id, |db, id| { + db.applications.transient_statuses.insert( id.to_string(), - GameTransientStatus::Downloading { version_name }, + ApplicationTransientStatus::Downloading { version_name }, ); }); self.sender @@ -455,13 +460,13 @@ impl DownloadManagerBuilder { drop(download_agent_lock); })); - // Set status for games - for queue_game in self.download_queue.read() { - let mut status_handle = queue_game.status.lock().unwrap(); - if queue_game.id == agent_data.id { - *status_handle = GameDownloadStatus::Downloading; + // Set status for applications + for queue_application in self.download_queue.read() { + let mut status_handle = queue_application.status.lock().unwrap(); + if queue_application.id == agent_data.id { + *status_handle = DownloadStatus::Downloading; } else { - *status_handle = GameDownloadStatus::Queued; + *status_handle = DownloadStatus::Queued; } drop(status_handle); } @@ -469,10 +474,10 @@ impl DownloadManagerBuilder { // Set flags for download manager active_control_flag.set(DownloadThreadControlFlag::Go); self.set_status(DownloadManagerStatus::Downloading); - self.set_game_status(agent_data.id.clone(), |db, id| { - db.games.transient_statuses.insert( + self.set_download_status(agent_data.id.clone(), |db, id| { + db.applications.transient_statuses.insert( id.to_string(), - GameTransientStatus::Downloading { version_name }, + ApplicationTransientStatus::Downloading { version_name }, ); }); @@ -485,19 +490,19 @@ impl DownloadManagerBuilder { let current_status = self.current_download_agent.clone().unwrap(); self.stop_and_wait_current_download(); - self.remove_and_cleanup_front_game(¤t_status.id); // Remove all the locks and shit, and remove from queue + self.remove_and_cleanup_front_download(¤t_status.id); // Remove all the locks and shit, and remove from queue self.app_handle .emit("download_error", error.to_string()) .unwrap(); let mut lock = current_status.status.lock().unwrap(); - *lock = GameDownloadStatus::Error; + *lock = DownloadStatus::Error; self.set_status(DownloadManagerStatus::Error(error)); - let game_id = current_status.id.clone(); - self.set_game_status(game_id, |db_handle, id| { - db_handle.games.transient_statuses.remove(id); + let id = current_status.id.clone(); + self.set_download_status(id, |db_handle, id| { + db_handle.applications.transient_statuses.remove(id); }); self.sender diff --git a/desktop/src-tauri/src/download_manager/queue.rs b/desktop/src-tauri/src/download_manager/queue.rs index 0ea65cae..1b11b115 100644 --- a/desktop/src-tauri/src/download_manager/queue.rs +++ b/desktop/src-tauri/src/download_manager/queue.rs @@ -3,11 +3,11 @@ use std::{ sync::{Arc, Mutex, MutexGuard}, }; -use super::download_manager::GameDownloadAgentQueueStandin; +use super::download_manager_builder::DownloadableQueueStandin; #[derive(Clone)] pub struct Queue { - inner: Arc>>>, + inner: Arc>>>, } #[allow(dead_code)] @@ -17,13 +17,13 @@ impl Queue { inner: Arc::new(Mutex::new(VecDeque::new())), } } - pub fn read(&self) -> VecDeque> { + pub fn read(&self) -> VecDeque> { self.inner.lock().unwrap().clone() } - pub fn edit(&self) -> MutexGuard<'_, VecDeque>> { + pub fn edit(&self) -> MutexGuard<'_, VecDeque>> { self.inner.lock().unwrap() } - pub fn pop_front(&self) -> Option> { + pub fn pop_front(&self) -> Option> { self.edit().pop_front() } pub fn empty(&self) -> bool { @@ -31,35 +31,35 @@ impl Queue { } /// Either inserts `interface` at the specified index, or appends to /// the back of the deque if index is greater than the length of the deque - pub fn insert(&self, interface: GameDownloadAgentQueueStandin, index: usize) { + pub fn insert(&self, interface: DownloadableQueueStandin, index: usize) { if self.read().len() > index { self.append(interface); } else { self.edit().insert(index, Arc::new(interface)); } } - pub fn append(&self, interface: GameDownloadAgentQueueStandin) { + pub fn append(&self, interface: DownloadableQueueStandin) { self.edit().push_back(Arc::new(interface)); } pub fn pop_front_if_equal( &self, - game_id: String, - ) -> Option> { + id: String, + ) -> Option> { let mut queue = self.edit(); let front = match queue.front() { Some(front) => front, None => return None, }; - if front.id == game_id { + if front.id == id { return queue.pop_front(); } None } - pub fn get_by_id(&self, game_id: String) -> Option { - self.read().iter().position(|data| data.id == game_id) + pub fn get_by_id(&self, id: String) -> Option { + self.read().iter().position(|data| data.id == id) } - pub fn move_to_index_by_id(&self, game_id: String, new_index: usize) -> Result<(), ()> { - let index = match self.get_by_id(game_id) { + pub fn move_to_index_by_id(&self, id: String, new_index: usize) -> Result<(), ()> { + let index = match self.get_by_id(id) { Some(index) => index, None => return Err(()), }; diff --git a/desktop/src-tauri/src/downloads/download_agent.rs b/desktop/src-tauri/src/downloads/download_agent.rs index d7110d78..8bb7cfe6 100644 --- a/desktop/src-tauri/src/downloads/download_agent.rs +++ b/desktop/src-tauri/src/downloads/download_agent.rs @@ -1,6 +1,6 @@ use crate::auth::generate_authorization_header; use crate::db::DatabaseImpls; -use crate::download_manager::download_manager::{DownloadManagerSignal, GameDownloadStatus}; +use crate::download_manager::download_manager::{DownloadManagerSignal, DownloadStatus}; use crate::download_manager::download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag}; use crate::download_manager::downloadable::Downloadable; use crate::download_manager::progress_object::{ProgressHandle, ProgressObject}; @@ -35,9 +35,9 @@ pub struct GameDownloadAgent { pub progress: Arc, sender: Sender, pub stored_manifest: StoredManifest, - status: Mutex } +// TODO: Rename / separate from downloads #[derive(Debug, Clone)] pub enum GameDownloadError { Communication(RemoteAccessError), @@ -85,7 +85,7 @@ impl GameDownloadAgent { let control_flag = DownloadThreadControl::new(DownloadThreadControlFlag::Stop); let db_lock = DB.borrow_data().unwrap(); - let base_dir = db_lock.games.install_dirs[target_download_dir].clone(); + let base_dir = db_lock.applications.install_dirs[target_download_dir].clone(); drop(db_lock); let base_dir_path = Path::new(&base_dir); @@ -104,7 +104,6 @@ impl GameDownloadAgent { progress: Arc::new(ProgressObject::new(0, 0, sender.clone())), sender, stored_manifest, - status: Mutex::new(GameDownloadStatus::Queued), } } diff --git a/desktop/src-tauri/src/downloads/download_commands.rs b/desktop/src-tauri/src/downloads/download_commands.rs index d3ca2e77..4ac35540 100644 --- a/desktop/src-tauri/src/downloads/download_commands.rs +++ b/desktop/src-tauri/src/downloads/download_commands.rs @@ -13,7 +13,7 @@ pub fn download_game( .lock() .unwrap() .download_manager - .queue_game(game_id, game_version, install_dir) + .queue_download(game_id, game_version, install_dir) .map_err(|_| "An error occurred while communicating with the download manager.".to_string()) } diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index 21121401..612e8ed7 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -22,7 +22,7 @@ use auth::{ }; use cleanup::{cleanup_and_exit, quit}; use db::{ - add_download_dir, delete_download_dir, fetch_download_dir_stats, DatabaseInterface, GameStatus, + add_download_dir, delete_download_dir, fetch_download_dir_stats, DatabaseInterface, ApplicationStatus, DATA_ROOT_DIR, }; use download_manager::download_manager::DownloadManager; @@ -148,12 +148,12 @@ fn setup(handle: AppHandle) -> AppState<'static> { let db_handle = DB.borrow_data().unwrap(); let mut missing_games = Vec::new(); - let statuses = db_handle.games.statuses.clone(); + let statuses = db_handle.applications.statuses.clone(); drop(db_handle); for (game_id, status) in statuses.into_iter() { match status { - db::GameStatus::Remote {} => {} - db::GameStatus::SetupRequired { + db::ApplicationStatus::Remote {} => {} + db::ApplicationStatus::SetupRequired { version_name: _, install_dir, } => { @@ -162,7 +162,7 @@ fn setup(handle: AppHandle) -> AppState<'static> { missing_games.push(game_id); } } - db::GameStatus::Installed { + db::ApplicationStatus::Installed { version_name: _, install_dir, } => { @@ -179,10 +179,10 @@ fn setup(handle: AppHandle) -> AppState<'static> { let mut db_handle = DB.borrow_data_mut().unwrap(); for game_id in missing_games { db_handle - .games + .applications .statuses .entry(game_id.to_string()) - .and_modify(|v| *v = GameStatus::Remote {}); + .and_modify(|v| *v = ApplicationStatus::Remote {}); } drop(db_handle); info!("finished setup!"); diff --git a/desktop/src-tauri/src/library.rs b/desktop/src-tauri/src/library.rs index e8a31663..62bd62b6 100644 --- a/desktop/src-tauri/src/library.rs +++ b/desktop/src-tauri/src/library.rs @@ -7,9 +7,9 @@ use tauri::{AppHandle, Manager}; use urlencoding::encode; use crate::db::DatabaseImpls; -use crate::db::GameStatus; -use crate::db::GameVersion; -use crate::downloads::download_manager::{DownloadManagerStatus, GameDownloadStatus}; +use crate::db::ApplicationVersion; +use crate::db::ApplicationStatus; +use crate::download_manager::download_manager::{DownloadManagerStatus, DownloadStatus}; use crate::process::process_manager::Platform; use crate::remote::{DropServerError, RemoteAccessError}; use crate::state::{GameStatusManager, GameStatusWithTransient}; @@ -44,7 +44,7 @@ pub struct GameUpdateEvent { #[derive(Serialize, Clone)] pub struct QueueUpdateEventQueueData { pub id: String, - pub status: GameDownloadStatus, + pub status: DownloadStatus, pub progress: f64, } @@ -99,11 +99,11 @@ fn fetch_library_logic(app: AppHandle) -> Result, RemoteAccessError> { for game in games.iter() { handle.games.insert(game.id.clone(), game.clone()); - if !db_handle.games.statuses.contains_key(&game.id) { + if !db_handle.applications.statuses.contains_key(&game.id) { db_handle - .games + .applications .statuses - .insert(game.id.clone(), GameStatus::Remote {}); + .insert(game.id.clone(), ApplicationStatus::Remote {}); } } @@ -162,10 +162,10 @@ fn fetch_game_logic( let mut db_handle = DB.borrow_data_mut().unwrap(); db_handle - .games + .applications .statuses .entry(id.clone()) - .or_insert(GameStatus::Remote {}); + .or_insert(ApplicationStatus::Remote {}); drop(db_handle); let status = GameStatusManager::fetch_state(&id); @@ -246,13 +246,13 @@ pub fn uninstall_game( state: tauri::State<'_, Mutex>, ) -> Result<(), String> { let state_lock = state.lock().unwrap(); - state_lock.download_manager.uninstall_game(game_id); + state_lock.download_manager.uninstall_application(game_id); drop(state_lock); Ok(()) } -pub fn push_game_update(app_handle: &AppHandle, id: String, status: GameStatusWithTransient) { +pub fn push_application_update(app_handle: &AppHandle, id: String, status: GameStatusWithTransient) { app_handle .emit( &format!("update_game/{}", id), @@ -297,11 +297,11 @@ pub fn on_game_complete( )); } - let data = response.json::()?; + let data = response.json::()?; let mut handle = DB.borrow_data_mut().unwrap(); handle - .games + .applications .versions .entry(game_id.clone()) .or_default() @@ -310,12 +310,12 @@ pub fn on_game_complete( DB.save().unwrap(); let status = if data.setup_command.is_empty() { - GameStatus::Installed { + ApplicationStatus::Installed { version_name, install_dir, } } else { - GameStatus::SetupRequired { + ApplicationStatus::SetupRequired { version_name, install_dir, } @@ -323,7 +323,7 @@ pub fn on_game_complete( let mut db_handle = DB.borrow_data_mut().unwrap(); db_handle - .games + .applications .statuses .insert(game_id.clone(), status.clone()); drop(db_handle); diff --git a/desktop/src-tauri/src/process/process_manager.rs b/desktop/src-tauri/src/process/process_manager.rs index ccab03d8..f9654496 100644 --- a/desktop/src-tauri/src/process/process_manager.rs +++ b/desktop/src-tauri/src/process/process_manager.rs @@ -15,8 +15,8 @@ use tauri::{AppHandle, Manager}; use umu_wrapper_lib::command_builder::UmuCommandBuilder; use crate::{ - db::{GameStatus, GameTransientStatus, DATA_ROOT_DIR}, - library::push_game_update, + db::{ApplicationStatus, ApplicationTransientStatus, DATA_ROOT_DIR}, + library::push_application_update, state::GameStatusManager, AppState, DB, }; @@ -107,20 +107,20 @@ impl ProcessManager<'_> { self.processes.remove(&game_id); let mut db_handle = DB.borrow_data_mut().unwrap(); - db_handle.games.transient_statuses.remove(&game_id); + db_handle.applications.transient_statuses.remove(&game_id); - let current_state = db_handle.games.statuses.get(&game_id).cloned(); + let current_state = db_handle.applications.statuses.get(&game_id).cloned(); if let Some(saved_state) = current_state { - if let GameStatus::SetupRequired { + if let ApplicationStatus::SetupRequired { version_name, install_dir, } = saved_state { if let Ok(exit_code) = result { if exit_code.success() { - db_handle.games.statuses.insert( + db_handle.applications.statuses.insert( game_id.clone(), - GameStatus::Installed { + ApplicationStatus::Installed { version_name: version_name.to_string(), install_dir: install_dir.to_string(), }, @@ -133,7 +133,7 @@ impl ProcessManager<'_> { let status = GameStatusManager::fetch_state(&game_id); - push_game_update(&self.app_handle, game_id.clone(), status); + push_application_update(&self.app_handle, game_id.clone(), status); // TODO better management } @@ -152,17 +152,17 @@ impl ProcessManager<'_> { let mut db_lock = DB.borrow_data_mut().unwrap(); let game_status = db_lock - .games + .applications .statuses .get(&game_id) .ok_or("Game not installed")?; let status_metadata: Option<(&String, &String)> = match game_status { - GameStatus::Installed { + ApplicationStatus::Installed { version_name, install_dir, } => Some((version_name, install_dir)), - GameStatus::SetupRequired { + ApplicationStatus::SetupRequired { version_name, install_dir, } => Some((version_name, install_dir)), @@ -176,7 +176,7 @@ impl ProcessManager<'_> { let (version_name, install_dir) = status_metadata.unwrap(); let game_version = db_lock - .games + .applications .versions .get(&game_id) .ok_or("Invalid game ID".to_owned())? @@ -184,11 +184,11 @@ impl ProcessManager<'_> { .ok_or("Invalid version name".to_owned())?; let raw_command: String = match game_status { - GameStatus::Installed { + ApplicationStatus::Installed { version_name: _, install_dir: _, } => game_version.launch_command.clone(), - GameStatus::SetupRequired { + ApplicationStatus::SetupRequired { version_name: _, install_dir: _, } => game_version.setup_command.clone(), @@ -252,14 +252,14 @@ impl ProcessManager<'_> { Arc::new(SharedChild::new(launch_process).map_err(|e| e.to_string())?); db_lock - .games + .applications .transient_statuses - .insert(game_id.clone(), GameTransientStatus::Running {}); + .insert(game_id.clone(), ApplicationTransientStatus::Running {}); - push_game_update( + push_application_update( &self.app_handle, game_id.clone(), - (None, Some(GameTransientStatus::Running {})), + (None, Some(ApplicationTransientStatus::Running {})), ); let wait_thread_handle = launch_process_handle.clone(); diff --git a/desktop/src-tauri/src/state.rs b/desktop/src-tauri/src/state.rs index 63f6c505..df0585f0 100644 --- a/desktop/src-tauri/src/state.rs +++ b/desktop/src-tauri/src/state.rs @@ -1,9 +1,9 @@ use crate::{ - db::{Database, GameStatus, GameTransientStatus}, + db::{ApplicationStatus, ApplicationTransientStatus, Database}, DB, }; -pub type GameStatusWithTransient = (Option, Option); +pub type GameStatusWithTransient = (Option, Option); pub struct GameStatusManager {} impl GameStatusManager { @@ -15,8 +15,8 @@ impl GameStatusManager { game_id: &String, db_lock: &Database, ) -> GameStatusWithTransient { - let offline_state = db_lock.games.statuses.get(game_id).cloned(); - let online_state = db_lock.games.transient_statuses.get(game_id).cloned(); + let offline_state = db_lock.applications.statuses.get(game_id).cloned(); + let online_state = db_lock.applications.transient_statuses.get(game_id).cloned(); if online_state.is_some() { return (None, online_state);