Implement better error system and segregate errors and commands (#23)

* chore: Progress on amend_settings command

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Progress on better error handling with segragation of files

* chore: Progress on amend_settings command

Signed-off-by: quexeky <git@quexeky.dev>

* chore(commands): Separated commands under each subdirectory into respective commands.rs files

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Almost all errors and commands have been segregated

* chore(errors): Added drop server error

Signed-off-by: quexeky <git@quexeky.dev>

* feat(core): Update to using nightly compiler

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): More progress on error handling

Signed-off-by: quexeky <git@quexeky.dev>

* chore(errors): Implementing Try and FromResidual for UserValue

Signed-off-by: quexeky <git@quexeky.dev>

* refactor(errors): Segregated errors and commands from code, and made commands return UserValue struct

Signed-off-by: quexeky <git@quexeky.dev>

* fix(errors): Added missing files

* chore(errors): Convert match statement to map_err

* feat(settings): Implemented settings editing from UI

* feat(errors): Clarified return values from retry_connect command

* chore(errors): Moved autostart commands to autostart.rs

* chore(process manager): Converted launch_process function for games to use game_id

---------

Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
quexeky
2025-01-13 21:44:57 +11:00
committed by GitHub
parent 245a84d20b
commit 604d5b5884
45 changed files with 822 additions and 600 deletions

View File

@ -0,0 +1,31 @@
use std::sync::{mpsc::SendError, Arc, Mutex};
use crate::{
download_manager::{download_manager::DownloadManagerSignal, downloadable::Downloadable},
error::user_error::UserValue,
AppState,
};
use super::download_agent::GameDownloadAgent;
#[tauri::command]
pub fn download_game(
game_id: String,
game_version: String,
install_dir: usize,
state: tauri::State<'_, Mutex<AppState>>,
) -> UserValue<(), SendError<DownloadManagerSignal>> {
let sender = state.lock().unwrap().download_manager.get_sender();
let game_download_agent = Arc::new(Box::new(GameDownloadAgent::new(
game_id,
game_version,
install_dir,
sender,
)) as Box<dyn Downloadable + Send + Sync>);
state
.lock()
.unwrap()
.download_manager
.queue_download(game_download_agent)
.into()
}

View File

@ -1,6 +1,7 @@
use crate::auth::generate_authorization_header;
use crate::db::{set_game_status, ApplicationTransientStatus, DatabaseImpls};
use crate::download_manager::application_download_error::ApplicationDownloadError;
use crate::database::db::{
set_game_status, ApplicationTransientStatus, DatabaseImpls, GameDownloadStatus,
};
use crate::download_manager::download_manager::{DownloadManagerSignal, DownloadStatus};
use crate::download_manager::download_thread_control_flag::{
DownloadThreadControl, DownloadThreadControlFlag,
@ -8,9 +9,10 @@ use crate::download_manager::download_thread_control_flag::{
use crate::download_manager::downloadable::Downloadable;
use crate::download_manager::downloadable_metadata::{DownloadType, DownloadableMetadata};
use crate::download_manager::progress_object::{ProgressHandle, ProgressObject};
use crate::error::application_download_error::ApplicationDownloadError;
use crate::error::remote_access_error::RemoteAccessError;
use crate::games::downloads::manifest::{DropDownloadContext, DropManifest};
use crate::games::library::{on_game_complete, push_game_update};
use crate::remote::RemoteAccessError;
use crate::games::library::{on_game_complete, push_game_update, GameUpdateEvent};
use crate::DB;
use log::{debug, error, info};
use rayon::ThreadPoolBuilder;
@ -100,7 +102,7 @@ impl GameDownloadAgent {
let timer = Instant::now();
push_game_update(
app_handle,
&self.metadata(),
&self.metadata().id,
(
None,
Some(ApplicationTransientStatus::Downloading {
@ -208,7 +210,8 @@ impl GameDownloadAgent {
{
let mut completed_contexts_lock = self.completed_contexts.lock().unwrap();
completed_contexts_lock.clear();
completed_contexts_lock.extend(self.stored_manifest.get_completed_contexts());
completed_contexts_lock
.extend_from_slice(&self.stored_manifest.get_completed_contexts());
}
for (raw_path, chunk) in manifest {
@ -247,9 +250,12 @@ impl GameDownloadAgent {
// TODO: Change return value on Err
pub fn run(&self) -> Result<bool, ()> {
info!("downloading game: {}", self.id);
let max_download_threads = DB.borrow_data().unwrap().settings.max_download_threads;
info!(
"downloading game: {} with {} threads",
self.id, max_download_threads
);
let pool = ThreadPoolBuilder::new()
.num_threads(max_download_threads)
.build()
@ -401,8 +407,18 @@ impl Downloadable for GameDownloadAgent {
.unwrap();
}
fn on_incomplete(&self, _app_handle: &tauri::AppHandle) {
fn on_incomplete(&self, app_handle: &tauri::AppHandle) {
let meta = self.metadata();
*self.status.lock().unwrap() = DownloadStatus::Queued;
app_handle
.emit(
&format!("update_game/{}", meta.id),
GameUpdateEvent {
game_id: meta.id.clone(),
status: (Some(GameDownloadStatus::Remote {}), None),
},
)
.unwrap();
}
fn on_cancelled(&self, _app_handle: &tauri::AppHandle) {}

View File

@ -1,58 +0,0 @@
use std::sync::{Arc, Mutex};
use crate::{
download_manager::{downloadable::Downloadable, downloadable_metadata::DownloadableMetadata},
AppState,
};
use super::download_agent::GameDownloadAgent;
#[tauri::command]
pub fn download_game(
game_id: String,
game_version: String,
install_dir: usize,
state: tauri::State<'_, Mutex<AppState>>,
) -> Result<(), String> {
let sender = state.lock().unwrap().download_manager.get_sender();
let game_download_agent = Arc::new(Box::new(GameDownloadAgent::new(
game_id,
game_version,
install_dir,
sender,
)) as Box<dyn Downloadable + Send + Sync>);
state
.lock()
.unwrap()
.download_manager
.queue_download(game_download_agent)
.map_err(|_| "An error occurred while communicating with the download manager.".to_string())
}
#[tauri::command]
pub fn pause_game_downloads(state: tauri::State<'_, Mutex<AppState>>) {
state.lock().unwrap().download_manager.pause_downloads()
}
#[tauri::command]
pub fn resume_game_downloads(state: tauri::State<'_, Mutex<AppState>>) {
state.lock().unwrap().download_manager.resume_downloads()
}
#[tauri::command]
pub fn move_game_in_queue(
state: tauri::State<'_, Mutex<AppState>>,
old_index: usize,
new_index: usize,
) {
state
.lock()
.unwrap()
.download_manager
.rearrange(old_index, new_index)
}
#[tauri::command]
pub fn cancel_game(state: tauri::State<'_, Mutex<AppState>>, meta: DownloadableMetadata) {
state.lock().unwrap().download_manager.cancel(meta)
}

View File

@ -1,10 +1,10 @@
use crate::download_manager::application_download_error::ApplicationDownloadError;
use crate::download_manager::download_thread_control_flag::{
DownloadThreadControl, DownloadThreadControlFlag,
};
use crate::download_manager::progress_object::ProgressHandle;
use crate::error::application_download_error::ApplicationDownloadError;
use crate::error::remote_access_error::RemoteAccessError;
use crate::games::downloads::manifest::DropDownloadContext;
use crate::remote::RemoteAccessError;
use log::{error, warn};
use md5::{Context, Digest};
use reqwest::blocking::{RequestBuilder, Response};

View File

@ -1,5 +1,5 @@
pub mod commands;
pub mod download_agent;
pub mod download_commands;
mod download_logic;
mod manifest;
mod stored_manifest;