Skip to content

Commit

Permalink
Uses total files for progress when installing a PKG (#758)
Browse files Browse the repository at this point in the history
  • Loading branch information
ultimaweapon authored Mar 23, 2024
1 parent ea3380c commit 9b3c26c
Show file tree
Hide file tree
Showing 9 changed files with 171 additions and 173 deletions.
44 changes: 44 additions & 0 deletions src/core.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
#include <QString>
#include <QUtf8StringView>

#include <cstddef>

struct error;
struct param;
struct pkg;

typedef void (*pkg_extract_status_t) (const char *status, std::size_t current, std::size_t total, void *ud);

extern "C" {
void error_free(error *err);
Expand All @@ -21,6 +26,12 @@ extern "C" {
void param_title_id_get(const param *param, QString &buf);
void param_version_get(const param *param, QString &buf);

pkg *pkg_open(const char *file, error **error);
void pkg_close(pkg *pkg);

param *pkg_get_param(const pkg *pkg, error **error);
error *pkg_extract(const pkg *pkg, const char *dir, pkg_extract_status_t status, void *ud);

error *system_download(
const char *from,
const char *to,
Expand Down Expand Up @@ -155,3 +166,36 @@ class Param final {
private:
param *m_obj;
};

class Pkg final {
public:
Pkg() : m_obj(nullptr) {}
Pkg(const Pkg &) = delete;
~Pkg() { close(); }

public:
Pkg &operator=(const Pkg &) = delete;
Pkg &operator=(pkg *obj)
{
if (m_obj) {
pkg_close(m_obj);
}

m_obj = obj;
return *this;
}

operator pkg *() const { return m_obj; }

public:
void close()
{
if (m_obj) {
pkg_close(m_obj);
m_obj = nullptr;
}
}

private:
pkg *m_obj;
};
7 changes: 1 addition & 6 deletions src/core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
#![allow(clippy::enum_variant_names)]

// The purpose of this crate is to generate a static library to link with the GUI. So it is required
// to add other crates that expose API to the GUI as a dependency of this crate then re-export all
// of those APIs here.
pub use error::*;
pub use pkg::*;

mod ffi;
mod fwdl;
mod param;
mod pkg;
52 changes: 52 additions & 0 deletions src/core/src/pkg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
use error::Error;
use param::Param;
use pkg::Pkg;
use std::ffi::{c_char, c_void, CStr};
use std::ptr::null_mut;

#[no_mangle]
pub unsafe extern "C" fn pkg_open(file: *const c_char, error: *mut *mut Error) -> *mut Pkg {
let path = CStr::from_ptr(file);
let pkg = match Pkg::open(path.to_str().unwrap()) {
Ok(v) => Box::new(v),
Err(e) => {
*error = Error::new(e);
return null_mut();
}
};

Box::into_raw(pkg)
}

#[no_mangle]
pub unsafe extern "C" fn pkg_close(pkg: *mut Pkg) {
drop(Box::from_raw(pkg));
}

#[no_mangle]
pub unsafe extern "C" fn pkg_get_param(pkg: &Pkg, error: *mut *mut Error) -> *mut Param {
let param = match pkg.get_param() {
Ok(v) => Box::new(v),
Err(e) => {
*error = Error::new(e);
return null_mut();
}
};

Box::into_raw(param)
}

#[no_mangle]
pub unsafe extern "C" fn pkg_extract(
pkg: &Pkg,
dir: *const c_char,
status: extern "C" fn(*const c_char, usize, usize, *mut c_void),
ud: *mut c_void,
) -> *mut Error {
let dir = CStr::from_ptr(dir);

match pkg.extract(dir.to_str().unwrap(), status, ud) {
Ok(_) => null_mut(),
Err(e) => Error::new(e),
}
}
1 change: 0 additions & 1 deletion src/game_models.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#include "game_models.hpp"
#include "path.hpp"
#include "pkg.hpp"

Game::Game(const QString &id, const QString &name, const QString &directory) :
m_id(id),
Expand Down
34 changes: 8 additions & 26 deletions src/main_window.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include "main_window.hpp"
#include "app_data.hpp"
#include "core.hpp"
#include "game_models.hpp"
#include "game_settings.hpp"
#include "game_settings_dialog.hpp"
#include "log_formatter.hpp"
#include "path.hpp"
#include "pkg.hpp"
#include "progress_dialog.hpp"
#include "settings.hpp"
#include "string.hpp"
Expand Down Expand Up @@ -317,34 +317,16 @@ void MainWindow::installPkg()
// Extract items.
progress.setWindowTitle(title);

error = pkg_extract(pkg, directory.c_str(), [](const char *name, std::uint64_t total, std::uint64_t written, void *ud) {
auto toProgress = [total](std::uint64_t v) -> int {
if (total >= 1024UL*1024UL*1024UL*1024UL) { // >= 1TB
return v / (1024UL*1024UL*1024UL*10UL); // 10GB step.
} else if (total >= 1024UL*1024UL*1024UL*100UL) { // >= 100GB
return v / (1024UL*1024UL*1024UL); // 1GB step.
} else if (total >= 1024UL*1024UL*1024UL*10UL) { // >= 10GB
return v / (1024UL*1024UL*100UL); // 100MB step.
} else if (total >= 1024UL*1024UL*1024UL) { // >= 1GB
return v / (1024UL*1024UL*10UL); // 10MB step.
} else if (total >= 1024UL*1024UL*100UL) { // >= 100MB
return v / (1024UL*1024UL);// 1MB step.
} else {
return v;
}
};

error = pkg_extract(pkg, directory.c_str(), [](const char *status, std::size_t current, std::size_t total, void *ud) {
auto progress = reinterpret_cast<ProgressDialog *>(ud);
auto max = toProgress(total);
auto value = toProgress(written);
auto label = QString("Installing %1...").arg(name);

if (progress->statusText() != label) {
progress->setStatusText(label);
progress->setValue(0);
progress->setMaximum(max);
progress->setStatusText(status);

if (current) {
progress->setValue(static_cast<int>(current));
} else {
progress->setValue(value == max && written != total ? value - 1 : value);
progress->setValue(0);
progress->setMaximum(static_cast<int>(total));
}
}, &progress);

Expand Down
4 changes: 4 additions & 0 deletions src/pfs/src/directory/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ pub struct Items<'a> {
}

impl<'a> Items<'a> {
pub fn len(&self) -> usize {
self.items.len()
}

pub fn get(&self, name: &[u8]) -> Option<&Item<'a>> {
self.items.get(name)
}
Expand Down
23 changes: 16 additions & 7 deletions src/pfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ pub mod image;
pub mod inode;
pub mod pfsc;

pub fn open<'a, I>(mut image: I, ekpfs: Option<&[u8]>) -> Result<Directory<'a>, OpenError>
pub fn open<'a, I>(mut image: I, ekpfs: Option<&[u8]>) -> Result<Rc<Pfs<'a>>, OpenError>
where
I: Read + Seek + 'a,
{
Expand Down Expand Up @@ -126,19 +126,28 @@ where
return Err(OpenError::InvalidSuperRoot);
}

// Construct super-root.
let pfs = Pfs {
Ok(Rc::new(Pfs {
image: Mutex::new(image),
inodes,
};

Ok(Directory::new(Rc::new(pfs), super_root))
root: super_root,
}))
}

/// Represents a loaded PFS.
pub(crate) struct Pfs<'a> {
pub struct Pfs<'a> {
image: Mutex<Box<dyn Image + 'a>>,
inodes: Vec<Inode>,
root: usize,
}

impl<'a> Pfs<'a> {
pub fn inodes(&self) -> usize {
self.inodes.len()
}

pub fn root(self: &Rc<Self>) -> Directory<'a> {
Directory::new(self.clone(), self.root)
}
}

/// Encapsulate a PFS image.
Expand Down
51 changes: 0 additions & 51 deletions src/pkg.hpp

This file was deleted.

Loading

0 comments on commit 9b3c26c

Please sign in to comment.