mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-14 08:41:21 +10:00
chore(downloads): partial download manager
This commit is contained in:
@ -4,11 +4,13 @@ use crate::downloads::manifest::{DropDownloadContext, DropManifest};
|
|||||||
use crate::remote::RemoteAccessError;
|
use crate::remote::RemoteAccessError;
|
||||||
use crate::DB;
|
use crate::DB;
|
||||||
use log::info;
|
use log::info;
|
||||||
use rayon::ThreadPoolBuilder;
|
use rayon::{spawn, ThreadPool, ThreadPoolBuilder};
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
use std::fs::{create_dir_all, File};
|
use std::fs::{create_dir_all, File};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::Mutex;
|
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
use std::thread::Thread;
|
||||||
use urlencoding::encode;
|
use urlencoding::encode;
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
@ -207,6 +209,7 @@ impl GameDownloadAgent {
|
|||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|
||||||
pool.scope(move |scope| {
|
pool.scope(move |scope| {
|
||||||
let contexts = self.contexts.lock().unwrap();
|
let contexts = self.contexts.lock().unwrap();
|
||||||
|
|
||||||
@ -223,6 +226,6 @@ impl GameDownloadAgent {
|
|||||||
download_game_chunk(context, control_flag, progress).unwrap();
|
download_game_chunk(context, control_flag, progress).unwrap();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,6 +11,7 @@ pub fn download_game(
|
|||||||
game_version: String,
|
game_version: String,
|
||||||
state: tauri::State<'_, Mutex<AppState>>,
|
state: tauri::State<'_, Mutex<AppState>>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
|
/*
|
||||||
info!("beginning game download...");
|
info!("beginning game download...");
|
||||||
|
|
||||||
let mut download_agent = GameDownloadAgent::new(game_id.clone(), game_version.clone(), 0);
|
let mut download_agent = GameDownloadAgent::new(game_id.clone(), game_version.clone(), 0);
|
||||||
@ -19,7 +20,7 @@ pub fn download_game(
|
|||||||
|
|
||||||
let mut lock: std::sync::MutexGuard<'_, AppState> = state.lock().unwrap();
|
let mut lock: std::sync::MutexGuard<'_, AppState> = state.lock().unwrap();
|
||||||
let download_agent_ref = Arc::new(download_agent);
|
let download_agent_ref = Arc::new(download_agent);
|
||||||
lock.game_downloads
|
lock.download_manager
|
||||||
.insert(game_id, download_agent_ref.clone());
|
.insert(game_id, download_agent_ref.clone());
|
||||||
|
|
||||||
// Run it in another thread
|
// Run it in another thread
|
||||||
@ -27,6 +28,7 @@ pub fn download_game(
|
|||||||
// Run doesn't require mutable
|
// Run doesn't require mutable
|
||||||
download_agent_ref.clone().run();
|
download_agent_ref.clone().run();
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -36,18 +38,23 @@ pub fn get_game_download_progress(
|
|||||||
state: tauri::State<'_, Mutex<AppState>>,
|
state: tauri::State<'_, Mutex<AppState>>,
|
||||||
game_id: String,
|
game_id: String,
|
||||||
) -> Result<f64, String> {
|
) -> Result<f64, String> {
|
||||||
|
/*
|
||||||
let download_agent = use_download_agent(state, game_id)?;
|
let download_agent = use_download_agent(state, game_id)?;
|
||||||
|
|
||||||
let progress = &download_agent.progress;
|
let progress = &download_agent.progress;
|
||||||
|
|
||||||
Ok(progress.get_progress())
|
Ok(progress.get_progress())
|
||||||
}
|
*/
|
||||||
|
|
||||||
|
Ok(0.0)
|
||||||
|
}
|
||||||
|
/*
|
||||||
fn use_download_agent(
|
fn use_download_agent(
|
||||||
state: tauri::State<'_, Mutex<AppState>>,
|
state: tauri::State<'_, Mutex<AppState>>,
|
||||||
game_id: String,
|
game_id: String,
|
||||||
) -> Result<Arc<GameDownloadAgent>, String> {
|
) -> Result<Arc<GameDownloadAgent>, String> {
|
||||||
let lock = state.lock().unwrap();
|
let lock = state.lock().unwrap();
|
||||||
let download_agent = lock.game_downloads.get(&game_id).ok_or("Invalid game ID")?;
|
let download_agent = lock.download_manager.get(&game_id).ok_or("Invalid game ID")?;
|
||||||
Ok(download_agent.clone()) // Clones the Arc, not the underlying data structure
|
Ok(download_agent.clone()) // Clones the Arc, not the underlying data structure
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
40
src-tauri/src/downloads/download_manager.rs
Normal file
40
src-tauri/src/downloads/download_manager.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use std::{
|
||||||
|
collections::HashMap,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
thread::JoinHandle,
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{download_agent::GameDownloadAgent, download_thread_control_flag::DownloadThreadControlFlag};
|
||||||
|
|
||||||
|
pub struct DownloadManager {
|
||||||
|
download_agent_registry: HashMap<String, Arc<Mutex<GameDownloadAgent>>>,
|
||||||
|
download_queue: Vec<String>,
|
||||||
|
|
||||||
|
current_thread: Option<JoinHandle<()>>,
|
||||||
|
current_game_id: Option<String>, // Should be the only game download agent in the map with the "Go" flag
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DownloadManager {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
return Self {
|
||||||
|
download_agent_registry: HashMap::new(),
|
||||||
|
download_queue: Vec::new(),
|
||||||
|
current_thread: None,
|
||||||
|
current_game_id: None,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn queue_game(&mut self, game_id: String, version_name: String) {
|
||||||
|
let existing_da = self.download_agent_registry.get(&game_id);
|
||||||
|
|
||||||
|
if let Some(da_mutex) = existing_da {
|
||||||
|
let da = da_mutex.lock().unwrap();
|
||||||
|
if da.version == version_name {
|
||||||
|
return; // We're already queued
|
||||||
|
}
|
||||||
|
|
||||||
|
da.control_flag.set(DownloadThreadControlFlag::Stop);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
pub mod download_agent;
|
pub mod download_agent;
|
||||||
pub mod download_commands;
|
pub mod download_commands;
|
||||||
|
pub mod download_manager;
|
||||||
mod download_logic;
|
mod download_logic;
|
||||||
mod download_thread_control_flag;
|
mod download_thread_control_flag;
|
||||||
mod manifest;
|
mod manifest;
|
||||||
|
|||||||
@ -13,6 +13,7 @@ use crate::downloads::download_agent::GameDownloadAgent;
|
|||||||
use auth::{auth_initiate, generate_authorization_header, recieve_handshake};
|
use auth::{auth_initiate, generate_authorization_header, recieve_handshake};
|
||||||
use db::{add_new_download_dir, DatabaseInterface, DATA_ROOT_DIR};
|
use db::{add_new_download_dir, DatabaseInterface, DATA_ROOT_DIR};
|
||||||
use downloads::download_commands::*;
|
use downloads::download_commands::*;
|
||||||
|
use downloads::download_manager::DownloadManager;
|
||||||
use env_logger::Env;
|
use env_logger::Env;
|
||||||
use http::{header::*, response::Builder as ResponseBuilder};
|
use http::{header::*, response::Builder as ResponseBuilder};
|
||||||
use library::{fetch_game, fetch_library, Game};
|
use library::{fetch_game, fetch_library, Game};
|
||||||
@ -53,7 +54,7 @@ pub struct AppState {
|
|||||||
games: HashMap<String, Game>,
|
games: HashMap<String, Game>,
|
||||||
|
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
game_downloads: HashMap<String, Arc<GameDownloadAgent>>,
|
download_manager: Arc<DownloadManager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@ -67,13 +68,16 @@ fn fetch_state(state: tauri::State<'_, Mutex<AppState>>) -> Result<AppState, Str
|
|||||||
fn setup() -> AppState {
|
fn setup() -> AppState {
|
||||||
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||||
|
|
||||||
|
let games = HashMap::new();
|
||||||
|
let download_manager = Arc::new(DownloadManager::new());
|
||||||
|
|
||||||
let is_set_up = DB.database_is_set_up();
|
let is_set_up = DB.database_is_set_up();
|
||||||
if !is_set_up {
|
if !is_set_up {
|
||||||
return AppState {
|
return AppState {
|
||||||
status: AppStatus::NotConfigured,
|
status: AppStatus::NotConfigured,
|
||||||
user: None,
|
user: None,
|
||||||
games: HashMap::new(),
|
games,
|
||||||
game_downloads: HashMap::new(),
|
download_manager,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +85,8 @@ fn setup() -> AppState {
|
|||||||
AppState {
|
AppState {
|
||||||
status: app_status,
|
status: app_status,
|
||||||
user,
|
user,
|
||||||
games: HashMap::new(),
|
games,
|
||||||
game_downloads: HashMap::new(),
|
download_manager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user