More fleshing out on how specifically game downloads will work (#1)

This commit is contained in:
quexeky
2024-10-19 17:35:26 +11:00
parent 27d0dcafc7
commit 23137dd049
2 changed files with 59 additions and 7 deletions

View File

@ -1,7 +1,8 @@
use std::sync::Arc; use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicUsize; use std::sync::atomic::AtomicUsize;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use versions::Version; use versions::Version;
use crate::AppState;
use crate::downloads::progress::ProgressChecker; use crate::downloads::progress::ProgressChecker;
#[derive(Serialize, Deserialize, Clone)] #[derive(Serialize, Deserialize, Clone)]
@ -9,7 +10,22 @@ use crate::downloads::progress::ProgressChecker;
pub struct GameDownload { pub struct GameDownload {
id: String, id: String,
version: Version, version: Version,
progress: Arc<AtomicUsize> progress: GameDownloadState
}
#[derive(Serialize, Deserialize, Clone)]
pub enum GameDownloadState {
Uninitialised,
Manifest,
Downloading(Arc<AtomicUsize>),
Finished,
Stalled,
Failed,
Cancelled
}
#[derive(Serialize, Deserialize, Clone)]
pub enum GameDownloadError {
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
#[serde(rename_all="camelCase")] #[serde(rename_all="camelCase")]
@ -17,20 +33,56 @@ pub struct GameChunkCtx {
chunk_id: usize, chunk_id: usize,
} }
#[derive(Serialize, Deserialize, Clone)]
pub struct GameDownloadManifest {
// TODO: Implement game manifest
}
impl GameDownload { impl GameDownload {
pub fn new(id: String, version: Version) -> Self { pub fn new(id: String, version: Version) -> Self {
Self { Self {
id, id,
version, version,
progress: Arc::new(AtomicUsize::new(0)) progress: GameDownloadState::Uninitialised
} }
} }
pub async fn download(&self, max_threads: usize, contexts: Vec<GameChunkCtx>) { pub async fn download(&mut self, max_threads: usize, contexts: Vec<GameChunkCtx>) -> Result<(), GameDownloadError> {
let progress = ProgressChecker::new(Box::new(download_game_chunk), self.progress.clone()); let progress = Arc::new(AtomicUsize::new(0));
self.progress = GameDownloadState::Downloading(progress.clone());
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(())
}
pub async fn download_manifest(&mut self) -> Result<GameDownloadManifest, GameDownloadError> {
todo!()
} }
} }
fn download_game_chunk(ctx: GameChunkCtx) { fn download_game_chunk(ctx: GameChunkCtx) {
todo!(); todo!();
// Need to implement actual download logic // Need to implement actual download logic
} }
#[tauri::command]
pub async fn start_game_download(
game_id: String,
game_version: Version,
max_threads: usize,
state: tauri::State<'_, Mutex<AppState>>,
) -> 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) }
};
download.download(max_threads, manifest.parse_to_chunks()).await
}
impl GameDownloadManifest {
fn parse_to_chunks(self) -> Vec<GameChunkCtx> {
todo!()
}
}

View File

@ -19,6 +19,7 @@ use serde::{Deserialize, Serialize};
use std::{ use std::{
collections::HashMap, sync::{LazyLock, Mutex} collections::HashMap, sync::{LazyLock, Mutex}
}; };
use std::sync::Arc;
use tauri_plugin_deep_link::DeepLinkExt; use tauri_plugin_deep_link::DeepLinkExt;
use crate::db::DatabaseImpls; use crate::db::DatabaseImpls;
use crate::downloads::game_download::GameDownload; use crate::downloads::game_download::GameDownload;
@ -46,7 +47,7 @@ pub struct AppState {
status: AppStatus, status: AppStatus,
user: Option<User>, user: Option<User>,
games: HashMap<String, Game>, games: HashMap<String, Game>,
game_downloads: Vec<GameDownload> game_downloads: Vec<Arc<GameDownload>>
} }
#[tauri::command] #[tauri::command]
@ -109,7 +110,6 @@ pub fn run() {
// Library // Library
fetch_library, fetch_library,
fetch_game, fetch_game,
// Downloads
]) ])
.plugin(tauri_plugin_shell::init()) .plugin(tauri_plugin_shell::init())
.setup(|app| { .setup(|app| {