mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-14 16:51:18 +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::{Arc, Mutex};
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -5,35 +6,40 @@ use versions::Version;
|
|||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
use crate::downloads::progress::ProgressChecker;
|
use crate::downloads::progress::ProgressChecker;
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize)]
|
||||||
#[serde(rename_all="camelCase")]
|
#[serde(rename_all="camelCase")]
|
||||||
pub struct GameDownload {
|
pub struct GameDownload {
|
||||||
id: String,
|
id: String,
|
||||||
version: Version,
|
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 {
|
pub enum GameDownloadState {
|
||||||
Uninitialised,
|
Uninitialised,
|
||||||
|
Queued,
|
||||||
Manifest,
|
Manifest,
|
||||||
Downloading(Arc<AtomicUsize>),
|
Downloading,
|
||||||
Finished,
|
Finished,
|
||||||
Stalled,
|
Stalled,
|
||||||
Failed,
|
Failed,
|
||||||
Cancelled
|
Cancelled
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)]
|
||||||
pub enum GameDownloadError {
|
pub enum GameDownloadError {
|
||||||
|
ManifestAlreadyExists,
|
||||||
|
ManifestDoesNotExist,
|
||||||
|
ManifestDownloadError,
|
||||||
}
|
}
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||||
#[serde(rename_all="camelCase")]
|
#[serde(rename_all="camelCase")]
|
||||||
pub struct GameChunkCtx {
|
pub struct GameChunkCtx {
|
||||||
chunk_id: usize,
|
chunk_id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone)]
|
#[derive(Serialize, Deserialize, Clone, Eq, PartialEq)]
|
||||||
pub struct GameDownloadManifest {
|
pub struct GameDownloadManifest {
|
||||||
// TODO: Implement game manifest
|
// TODO: Implement game manifest
|
||||||
}
|
}
|
||||||
@ -43,17 +49,38 @@ impl GameDownload {
|
|||||||
Self {
|
Self {
|
||||||
id,
|
id,
|
||||||
version,
|
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));
|
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);
|
let progress = ProgressChecker::new(Box::new(download_game_chunk), progress);
|
||||||
progress.run_contexts_parallel_async(contexts, max_threads).await;
|
progress.run_contexts_parallel_async(contexts, max_threads).await;
|
||||||
Ok(())
|
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!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,18 +98,26 @@ pub async fn start_game_download(
|
|||||||
) -> Result<(), GameDownloadError> {
|
) -> Result<(), GameDownloadError> {
|
||||||
let mut download = Arc::new(GameDownload::new(game_id, game_version));
|
let mut download = Arc::new(GameDownload::new(game_id, game_version));
|
||||||
let mut app_state = state.lock().unwrap();
|
let mut app_state = state.lock().unwrap();
|
||||||
app_state.game_downloads.push(download.clone());
|
|
||||||
|
|
||||||
let manifest = match download.download_manifest().await {
|
let tmp = download.clone();
|
||||||
Ok(manifest) => { manifest }
|
let manifest = &tmp.manifest;
|
||||||
Err(e) => { return Err(e) }
|
|
||||||
|
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