mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-14 08:41:21 +10:00
Theoretically adding queue support and optimistic manifest downloading (#1). Needs tests when actual functions are implemented
This commit is contained in:
@ -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<AtomicUsize>,
|
||||
state: Mutex<GameDownloadState>,
|
||||
manifest: Option<Mutex<GameDownloadManifest>>
|
||||
}
|
||||
#[derive(Serialize, Deserialize, Clone)]
|
||||
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)]
|
||||
pub enum GameDownloadState {
|
||||
Uninitialised,
|
||||
Queued,
|
||||
Manifest,
|
||||
Downloading(Arc<AtomicUsize>),
|
||||
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<GameChunkCtx>) -> 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<GameChunkCtx>) -> 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<GameDownloadManifest, GameDownloadError> {
|
||||
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<GameChunkCtx> {
|
||||
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<GameChunkCtx> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user