diff --git a/src-tauri/src/downloads/game_download.rs b/src-tauri/src/downloads/game_download.rs index 8f4cd35..371af57 100644 --- a/src-tauri/src/downloads/game_download.rs +++ b/src-tauri/src/downloads/game_download.rs @@ -1,3 +1,4 @@ +use std::future::Future; use std::sync::{Arc, Mutex}; use std::sync::atomic::AtomicUsize; use serde::{Deserialize, Serialize}; @@ -5,35 +6,40 @@ use versions::Version; use crate::AppState; use crate::downloads::progress::ProgressChecker; -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize)] #[serde(rename_all="camelCase")] pub struct GameDownload { id: String, version: Version, - progress: GameDownloadState + progress: Arc, + state: Mutex, + manifest: Option> } -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)] pub enum GameDownloadState { Uninitialised, + Queued, Manifest, - Downloading(Arc), + Downloading, Finished, Stalled, Failed, Cancelled } -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)] pub enum GameDownloadError { - + ManifestAlreadyExists, + ManifestDoesNotExist, + ManifestDownloadError, } -#[derive(Serialize, Deserialize)] +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Ord, PartialOrd)] #[serde(rename_all="camelCase")] pub struct GameChunkCtx { chunk_id: usize, } -#[derive(Serialize, Deserialize, Clone)] +#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)] pub struct GameDownloadManifest { // TODO: Implement game manifest } @@ -43,17 +49,38 @@ impl GameDownload { Self { id, version, - progress: GameDownloadState::Uninitialised + progress: Arc::new(AtomicUsize::new(0)), + state: Mutex::from(GameDownloadState::Uninitialised), + manifest: None } } - pub async fn download(&mut self, max_threads: usize, contexts: Vec) -> Result<(), GameDownloadError> { + pub async fn queue(&self) -> Result<(), GameDownloadError> { + self.change_state(GameDownloadState::Queued); + if self.manifest.is_none() { + return Ok(()) + } + self.download_manifest().await + } + pub async fn download(&self, max_threads: usize, contexts: Vec) -> Result<(), GameDownloadError> { let progress = Arc::new(AtomicUsize::new(0)); - self.progress = GameDownloadState::Downloading(progress.clone()); + self.change_state(GameDownloadState::Downloading); let progress = ProgressChecker::new(Box::new(download_game_chunk), progress); progress.run_contexts_parallel_async(contexts, max_threads).await; Ok(()) } - pub async fn download_manifest(&mut self) -> Result { + pub async fn download_manifest(&self) -> Result<(), GameDownloadError> { + if self.manifest.is_some() { + return Err(GameDownloadError::ManifestAlreadyExists); + } + todo!() // Need to actually download the manifest + } + pub fn change_state(&self, state: GameDownloadState) { + let mut lock = self.state.lock().unwrap(); + *lock = state; + } +} +impl GameDownloadManifest { + fn parse_to_chunks(&self) -> Vec { todo!() } } @@ -71,18 +98,26 @@ pub async fn start_game_download( ) -> Result<(), GameDownloadError> { let mut download = Arc::new(GameDownload::new(game_id, game_version)); let mut app_state = state.lock().unwrap(); - app_state.game_downloads.push(download.clone()); - let manifest = match download.download_manifest().await { - Ok(manifest) => { manifest } - Err(e) => { return Err(e) } + let tmp = download.clone(); + let manifest = &tmp.manifest; + + let Some(unlocked) = manifest else { return Err(GameDownloadError::ManifestDoesNotExist) }; + let lock = unlocked.lock().unwrap(); + + let chunks = lock.parse_to_chunks(); + + /* + let manifest = match d.manifest { + Some(lock) => { + let lock = lock.lock().unwrap(); + lock.parse_to_chunks() + }, + None => { return Err(GameDownloadError::ManifestDoesNotExist) } }; + */ - download.download(max_threads, manifest.parse_to_chunks()).await + app_state.game_downloads.push(download.clone()); + download.download(max_threads, chunks).await } -impl GameDownloadManifest { - fn parse_to_chunks(self) -> Vec { - todo!() - } -} \ No newline at end of file