Skip to content

Commit

Permalink
Merge pull request #13 from SARDONYX-sard/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
SARDONYX-sard authored Oct 12, 2023
2 parents 330041f + 8209df5 commit f8f0c02
Show file tree
Hide file tree
Showing 29 changed files with 640 additions and 219 deletions.
4 changes: 1 addition & 3 deletions .github/workflows/release-gui.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
releaseName: "DAR to OAR Converter v__VERSION__"
tagName: ${{ github.ref_name }} # This only works if your workflow triggers on new tags.
releaseName: "DAR to OAR Converter v__VERSION__" # tauri-action replaces \_\_VERSION\_\_ with the app version.
releaseBody: "See the assets to download and install this version."
releaseDraft: true
prerelease: false
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[workspace.package]
version = "0.1.4"
version = "0.1.5"
description = "DAR to OAR Converter"

[workspace]
Expand Down
1 change: 1 addition & 0 deletions cspell.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"Greatsword",
"icns",
"jwalk",
"mohidden",
"multispace",
"noconflict",
"rfind",
Expand Down
51 changes: 31 additions & 20 deletions dar2oar_cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use clap::{arg, Parser};
use dar2oar_core::{convert_dar_to_oar, fs::parallel, read_mapping_table};
use dar2oar_core::{
convert_dar_to_oar,
fs::{parallel, ConvertOptions},
read_mapping_table,
};
use std::path::PathBuf;

/// dar2oar --src "DAR path" --dist "OAR path"
Expand All @@ -12,7 +16,7 @@ pub struct Args {
/// OAR destination dir path(If not, it is inferred from src)
#[clap(long, value_parser)]
dist: Option<String>,
/// mod name in config.json & folder name(If not, it is inferred from src)
/// mod name in config.json & directory name(If not, it is inferred from src)
#[arg(long)]
name: Option<String>,
/// mod author in config.json
Expand All @@ -33,6 +37,9 @@ pub struct Args {
/// use multi thread(Probably effective for those with long DAR syntax. Basically single-threaded is faster.)
#[arg(long)]
run_parallel: bool,
#[arg(long)]
/// After converting to OAR, add mohidden to the DAR directory before conversion to treat it as a hidden directory. (for MO2 users)
hide_dar: bool,
}

pub fn run_cli(args: Args) -> anyhow::Result<()> {
Expand Down Expand Up @@ -64,22 +71,26 @@ pub fn run_cli(args: Args) -> anyhow::Result<()> {
None => None,
};

match args.run_parallel {
true => parallel::convert_dar_to_oar(
args.src,
dist,
args.name.as_deref(),
args.author.as_deref(),
table,
table_1person,
),
false => convert_dar_to_oar(
args.src,
dist,
args.name.as_deref(),
args.author.as_deref(),
table,
table_1person,
),
}
let msg = match args.run_parallel {
true => parallel::convert_dar_to_oar(ConvertOptions {
dar_dir: args.src,
oar_dir: dist,
mod_name: args.name.as_deref(),
author: args.author.as_deref(),
section_table: table,
section_1person_table: table_1person,
hide_dar: args.hide_dar,
}),
false => convert_dar_to_oar(ConvertOptions {
dar_dir: args.src,
oar_dir: dist,
mod_name: args.name.as_deref(),
author: args.author.as_deref(),
section_table: table,
section_1person_table: table_1person,
hide_dar: args.hide_dar,
}),
}?;
log::debug!("{}", msg);
Ok(())
}
18 changes: 15 additions & 3 deletions dar2oar_core/benches/convert_n_thread.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use criterion::{black_box, criterion_group, criterion_main, Criterion};
use dar2oar_core::{convert_dar_to_oar, fs::parallel, read_mapping_table};
use dar2oar_core::{
convert_dar_to_oar,
fs::{parallel, ConvertOptions},
read_mapping_table,
};
use std::time::Duration;

const REMOVE_TARGET: &str =
Expand Down Expand Up @@ -28,7 +32,11 @@ fn criterion_benchmark(c: &mut Criterion) {
let table_content = "../test/settings/mapping_table.txt";
let mapping = read_mapping_table(table_content).unwrap();

parallel::convert_dar_to_oar(black_box(TARGET), None, None, None, Some(mapping), None)
parallel::convert_dar_to_oar(black_box(ConvertOptions {
dar_dir: TARGET,
section_table: Some(mapping),
..Default::default()
}))
})
});

Expand All @@ -40,7 +48,11 @@ fn criterion_benchmark(c: &mut Criterion) {
let table_content = "../test/settings/mapping_table.txt";
let mapping = read_mapping_table(table_content).unwrap();

convert_dar_to_oar(black_box(TARGET), None, None, None, Some(mapping), None)
convert_dar_to_oar(black_box(ConvertOptions {
dar_dir: TARGET,
section_table: Some(mapping),
..Default::default()
}))
})
});

Expand Down
143 changes: 117 additions & 26 deletions dar2oar_core/src/fs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,28 @@ pub use sequential::convert_dar_to_oar;

use crate::conditions::{ConditionsConfig, MainConfig};
use anyhow::Context as _;
use std::collections::HashMap;
use std::fs;
use std::io::{self, Read, Write};
use std::path::Path;
use std::path::{Path, PathBuf};

#[derive(Debug, Default, PartialEq)]
pub struct ConvertOptions<'a, P: AsRef<Path>> {
/// DAR source dir path
pub dar_dir: P,
/// OAR destination dir path(If not, it is inferred from src)
pub oar_dir: Option<PathBuf>,
/// mod name in config.json & directory name(If not, it is inferred from src)
pub mod_name: Option<&'a str>,
/// mod author in config.json
pub author: Option<&'a str>,
/// path to section name table
pub section_table: Option<HashMap<String, String>>,
/// path to section name table(For _1st_person)
pub section_1person_table: Option<HashMap<String, String>>,
/// After converting to OAR, add mohidden to the DAR directory before conversion to treat it as a hidden directory. (for MO2 users)
pub hide_dar: bool,
}

fn read_file<P>(file_path: P) -> io::Result<String>
where
Expand Down Expand Up @@ -65,32 +84,104 @@ where
Ok(())
}

#[cfg(test)]
mod test {
use super::*;
/// # Returns
/// Report which dirs have been restored
///
/// # NOTE
/// It is currently used only in GUI, but is implemented in Core as an API.
pub fn restore_dar(dar_dir: impl AsRef<Path>) -> anyhow::Result<String> {
let mut restored_dar = None;
let mut restored_1st_dar = None;
for entry in walkdir::WalkDir::new(dar_dir) {
let entry = entry?;
let path = entry.path();
let (dar_root, _, is_1st_person, _, _, _) =
match path_changer::parse_dar_path(path, Some("DynamicAnimationReplacer.mohidden")) {
Ok(data) => data,
Err(_) => continue, // NOTE: The first search is skipped because it does not yet lead to the DAR file.
};

if restored_dar.is_none() && path.is_dir() {
restored_dar = Some(dar_root);
continue;
}
if restored_1st_dar.is_none() && path.is_dir() && is_1st_person {
restored_1st_dar = Some(dar_root);
}
}

let mut msg = String::new();
if let Some(dar_root) = restored_dar.as_ref() {
let dist = dar_root
.as_os_str()
.to_string_lossy()
.replace(".mohidden", "");
fs::rename(dar_root.clone(), dist)?;
msg = format!("{}- Restored 3rd_person", msg);
}
if let Some(dar_root) = restored_1st_dar.as_ref() {
let dist = dar_root
.as_os_str()
.to_string_lossy()
.replace(".mohidden", "");
fs::rename(dar_root.clone(), dist)?;
msg = format!("{}\n- Restored 1rd_person", msg);
}

if restored_dar.is_none() && restored_1st_dar.is_none() {
anyhow::bail!("Neither 1st or 3rd person DynamicAnimationReplacer.mohidden found.")
} else {
Ok(msg)
}
}

/// # NOTE
/// It is currently used only in GUI, but is implemented in Core as an API.
pub fn remove_oar(dar_dir: impl AsRef<Path>) -> anyhow::Result<()> {
let mut restored_dar = None;
let mut restored_1st_dar = None;
for entry in walkdir::WalkDir::new(dar_dir) {
let entry = entry?;
let path = entry.path();
// NOTE: The OAR root obtained by parse fn is calculated and not guaranteed to exist.
let (dar_root, oar_name_space_path, is_1st_person, _, _, _) =
match path_changer::parse_dar_path(path, Some("DynamicAnimationReplacer.mohidden")) {
Ok(data) => data,
Err(_) => {
match path_changer::parse_dar_path(path, Some("DynamicAnimationReplacer")) {
Ok(data) => data,
Err(_) => continue, // NOTE: The first search is skipped because it does not yet lead to the DAR file.
}
} // NOTE: The first search is skipped because it does not yet lead to the DAR file.
};

#[ignore]
#[test]
fn should_parallel_traverse() -> anyhow::Result<()> {
let config = simple_log::LogConfigBuilder::builder()
.path("../convert.log")
.size(100)
.roll_count(10)
.level("error")
.output_file()
.output_console()
.build();
simple_log::new(config).unwrap();
if restored_dar.is_none() && path.is_dir() {
restored_dar = Some((dar_root, oar_name_space_path));
continue;
}
if restored_1st_dar.is_none() && path.is_dir() && is_1st_person {
restored_1st_dar = Some((dar_root, oar_name_space_path));
}
}

let table_content = "../test/settings/mapping_table.txt";
let mapping = read_mapping_table(table_content)?;
convert_dar_to_oar(
"../test/data/Modern Female Sitting Animations Overhaul",
None,
None,
None,
Some(mapping),
None,
)
if let Some((_, oar_root)) = restored_dar {
dbg!(&oar_root);
if oar_root.exists() {
fs::remove_dir_all(oar_root)?;
}
}
if let Some((_, oar_root)) = restored_1st_dar {
dbg!(&oar_root);
if oar_root.exists() {
fs::remove_dir_all(oar_root)?;
}
}
Ok(())
}

#[ignore]
#[test]
fn should_restore_dar() {
let dar_dir = "../test/data/UNDERDOG Animations";
remove_oar(dar_dir).unwrap();
}
Loading

0 comments on commit f8f0c02

Please sign in to comment.