mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2026-07-27 18:24:51 +10:00
Progress checker works
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
mod downloads;
|
mod downloads;
|
||||||
mod manifest;
|
mod manifest;
|
||||||
|
pub mod progress;
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
use rayon::ThreadPoolBuilder;
|
||||||
|
|
||||||
|
pub struct ProgressChecker<T>
|
||||||
|
where T: 'static + Send + Sync
|
||||||
|
{
|
||||||
|
counter: AtomicUsize,
|
||||||
|
f: Arc<Box<dyn Fn(T) + Send + Sync + 'static>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> ProgressChecker<T>
|
||||||
|
where T: Send + Sync
|
||||||
|
{
|
||||||
|
pub fn new(f: Box<dyn Fn(T) + Send + Sync + 'static>) -> Self {
|
||||||
|
Self {
|
||||||
|
f: f.into(),
|
||||||
|
counter: AtomicUsize::new(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn run_contexts_sequentially_async(&self, contexts: Vec<T>) {
|
||||||
|
for context in contexts {
|
||||||
|
(self.f)(context);
|
||||||
|
self.counter.fetch_add(1, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn run_contexts_sequentially(&self, contexts: Vec<T>) {
|
||||||
|
for context in contexts {
|
||||||
|
(self.f)(context);
|
||||||
|
self.counter.fetch_add(1, Ordering::Relaxed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub async fn run_contexts_parallel_async(&self, contexts: Vec<T>, 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<T>, 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<C: Into<f64>>(&self, capacity: C) -> f64 {
|
||||||
|
(self.get_progress() as f64) / (capacity.into())
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,8 @@ mod remote;
|
|||||||
mod unpacker;
|
mod unpacker;
|
||||||
mod downloads;
|
mod downloads;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
use auth::{auth_initiate, generate_authorization_header, recieve_handshake};
|
use auth::{auth_initiate, generate_authorization_header, recieve_handshake};
|
||||||
use db::{DatabaseInterface, DATA_ROOT_DIR};
|
use db::{DatabaseInterface, DATA_ROOT_DIR};
|
||||||
@@ -104,7 +106,6 @@ pub fn run() {
|
|||||||
fetch_library,
|
fetch_library,
|
||||||
fetch_game,
|
fetch_game,
|
||||||
// Downloads
|
// Downloads
|
||||||
download_game
|
|
||||||
])
|
])
|
||||||
.plugin(tauri_plugin_shell::init())
|
.plugin(tauri_plugin_shell::init())
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
mod progress_tests;
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -1,13 +1,9 @@
|
|||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::atomic::Ordering::Relaxed;
|
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,
|
// 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
|
// and instead loops over it until it returns "Complete". The current number of iterations
|
||||||
// is counted by "progress"
|
// is counted by "progress"
|
||||||
@@ -18,16 +14,20 @@ pub async fn progress_updater(function: Box<dyn Fn() -> ProgressChecker>, progre
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn new_progress_updater<T, D>(function: Box<dyn Fn(T) -> D>, contexts: T, progress: AtomicUsize) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn threaded_progress_updater<F>(f: F, progress: AtomicUsize, max_threads: usize, instances: usize) -> ProgressChecker
|
pub async fn threaded_progress_updater<F>(f: F, progress: AtomicUsize, max_threads: usize, instances: usize) -> ProgressChecker
|
||||||
where F: Fn() -> ProgressChecker + Send + Clone + Copy + 'static
|
where F: Fn() -> ProgressChecker + Send + Clone + Copy + 'static
|
||||||
{
|
{
|
||||||
let mut threads = Vec::new();
|
let mut threads = Vec::new();
|
||||||
|
let pool = ThreadPoolBuilder::new().num_threads(max_threads).build().unwrap();
|
||||||
for instance in 0..instances {
|
for instance in 0..instances {
|
||||||
let func = tokio::spawn(async move {
|
pool.spawn(move || -> ProgressChecker {
|
||||||
let res = f();
|
let res = f();
|
||||||
return res
|
return res
|
||||||
});
|
});
|
||||||
threads.push(func);
|
|
||||||
}
|
}
|
||||||
let mut completed = ProgressChecker::Incomplete;
|
let mut completed = ProgressChecker::Incomplete;
|
||||||
for thread in threads {
|
for thread in threads {
|
||||||
@@ -42,3 +42,4 @@ where F: Fn() -> ProgressChecker + Send + Clone + Copy + 'static
|
|||||||
fn test() -> ProgressChecker {
|
fn test() -> ProgressChecker {
|
||||||
ProgressChecker::Incomplete
|
ProgressChecker::Incomplete
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
Reference in New Issue
Block a user