From f8b96d06e703cd033c16166b765b72ae353bcbc4 Mon Sep 17 00:00:00 2001 From: quexeky Date: Fri, 18 Oct 2024 20:42:26 +1100 Subject: [PATCH] Progress checker works --- desktop/src-tauri/src/downloads/mod.rs | 3 +- desktop/src-tauri/src/downloads/progress.rs | 66 +++++++++++++++++++ desktop/src-tauri/src/lib.rs | 3 +- desktop/src-tauri/src/tests/mod.rs | 1 + desktop/src-tauri/src/tests/progress_tests.rs | 17 +++++ desktop/src-tauri/src/utils.rs | 19 +++--- 6 files changed, 98 insertions(+), 11 deletions(-) create mode 100644 desktop/src-tauri/src/downloads/progress.rs create mode 100644 desktop/src-tauri/src/tests/mod.rs create mode 100644 desktop/src-tauri/src/tests/progress_tests.rs diff --git a/desktop/src-tauri/src/downloads/mod.rs b/desktop/src-tauri/src/downloads/mod.rs index c7dc3df4..9124aaad 100644 --- a/desktop/src-tauri/src/downloads/mod.rs +++ b/desktop/src-tauri/src/downloads/mod.rs @@ -1,2 +1,3 @@ mod downloads; -mod manifest; \ No newline at end of file +mod manifest; +pub mod progress; \ No newline at end of file diff --git a/desktop/src-tauri/src/downloads/progress.rs b/desktop/src-tauri/src/downloads/progress.rs new file mode 100644 index 00000000..dfcf2d9a --- /dev/null +++ b/desktop/src-tauri/src/downloads/progress.rs @@ -0,0 +1,66 @@ +use std::sync::Arc; +use std::sync::atomic::{AtomicUsize, Ordering}; +use rayon::ThreadPoolBuilder; + +pub struct ProgressChecker +where T: 'static + Send + Sync +{ + counter: AtomicUsize, + f: Arc>, +} + +impl ProgressChecker +where T: Send + Sync +{ + pub fn new(f: Box) -> Self { + Self { + f: f.into(), + counter: AtomicUsize::new(0) + } + } + pub async fn run_contexts_sequentially_async(&self, contexts: Vec) { + for context in contexts { + (self.f)(context); + self.counter.fetch_add(1, Ordering::Relaxed); + } + } + pub fn run_contexts_sequentially(&self, contexts: Vec) { + for context in contexts { + (self.f)(context); + self.counter.fetch_add(1, Ordering::Relaxed); + } + } + pub async fn run_contexts_parallel_async(&self, contexts: Vec, max_threads: usize) { + let threads = ThreadPoolBuilder::new() + // If max_threads == 0, then the limit will be determined + // by Rayon's internal RAYON_NUM_THREADS + .num_threads(max_threads) + .build() + .unwrap(); + + for context in contexts { + let f = self.f.clone(); + threads.spawn(move || f(context)); + } + } + pub fn run_contexts_parallel(&self, contexts: Vec, max_threads: usize) { + let threads = ThreadPoolBuilder::new() + // If max_threads == 0, then the limit will be determined + // by Rayon's internal RAYON_NUM_THREADS + .num_threads(max_threads) + .build() + .unwrap(); + + for context in contexts { + let f = self.f.clone(); + threads.spawn(move || f(context)); + } + } + pub fn get_progress(&self) -> usize { + self.counter.load(Ordering::Relaxed) + } + // I strongly dislike type casting in my own code, so I've shovelled it into here + pub fn get_progress_percentage>(&self, capacity: C) -> f64 { + (self.get_progress() as f64) / (capacity.into()) + } +} \ No newline at end of file diff --git a/desktop/src-tauri/src/lib.rs b/desktop/src-tauri/src/lib.rs index e91a19e3..4291c3fe 100644 --- a/desktop/src-tauri/src/lib.rs +++ b/desktop/src-tauri/src/lib.rs @@ -5,6 +5,8 @@ mod remote; mod unpacker; mod downloads; mod utils; +#[cfg(test)] +mod tests; use auth::{auth_initiate, generate_authorization_header, recieve_handshake}; use db::{DatabaseInterface, DATA_ROOT_DIR}; @@ -104,7 +106,6 @@ pub fn run() { fetch_library, fetch_game, // Downloads - download_game ]) .plugin(tauri_plugin_shell::init()) .setup(|app| { diff --git a/desktop/src-tauri/src/tests/mod.rs b/desktop/src-tauri/src/tests/mod.rs new file mode 100644 index 00000000..9dff719b --- /dev/null +++ b/desktop/src-tauri/src/tests/mod.rs @@ -0,0 +1 @@ +mod progress_tests; \ No newline at end of file diff --git a/desktop/src-tauri/src/tests/progress_tests.rs b/desktop/src-tauri/src/tests/progress_tests.rs new file mode 100644 index 00000000..4ebeedf4 --- /dev/null +++ b/desktop/src-tauri/src/tests/progress_tests.rs @@ -0,0 +1,17 @@ +use crate::downloads::progress::ProgressChecker; + +#[test] +fn test_progress_sequentially() { + let p = ProgressChecker::new(Box::new(test_fn)); + p.run_contexts_sequentially((1..100).collect()); + println!("Progress: {}", p.get_progress_percentage(100)); +} +#[test] +fn test_progress_parallel() { + let p = ProgressChecker::new(Box::new(test_fn)); + p.run_contexts_parallel((1..100).collect(), 10); +} + +fn test_fn(int: usize) { + println!("{}", int); +} \ No newline at end of file diff --git a/desktop/src-tauri/src/utils.rs b/desktop/src-tauri/src/utils.rs index aeb4f376..aa06dfde 100644 --- a/desktop/src-tauri/src/utils.rs +++ b/desktop/src-tauri/src/utils.rs @@ -1,13 +1,9 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::atomic::Ordering::Relaxed; -use crate::utils::ProgressChecker::Complete; +use rayon::{ThreadPool, ThreadPoolBuilder}; -#[derive(Eq, PartialEq)] -pub enum ProgressChecker { - Complete, - Incomplete -} +/* // This function is designed to take in any function which does not regularly return a value, // and instead loops over it until it returns "Complete". The current number of iterations // is counted by "progress" @@ -18,16 +14,20 @@ pub async fn progress_updater(function: Box ProgressChecker>, progre } } +pub async fn new_progress_updater(function: Box D>, contexts: T, progress: AtomicUsize) { + +} + pub async fn threaded_progress_updater(f: F, progress: AtomicUsize, max_threads: usize, instances: usize) -> ProgressChecker where F: Fn() -> ProgressChecker + Send + Clone + Copy + 'static { let mut threads = Vec::new(); + let pool = ThreadPoolBuilder::new().num_threads(max_threads).build().unwrap(); for instance in 0..instances { - let func = tokio::spawn(async move { + pool.spawn(move || -> ProgressChecker { let res = f(); return res }); - threads.push(func); } let mut completed = ProgressChecker::Incomplete; for thread in threads { @@ -41,4 +41,5 @@ where F: Fn() -> ProgressChecker + Send + Clone + Copy + 'static fn test() -> ProgressChecker { ProgressChecker::Incomplete -} \ No newline at end of file +} + */ \ No newline at end of file