removed callback function from fomod installer

This commit is contained in:
2026-03-29 22:48:21 +02:00
parent ea50f4d59b
commit 7e20cd370c
2 changed files with 59 additions and 39 deletions

View File

@@ -8,7 +8,7 @@ use log::{debug, trace};
use crate::{
fomod, install_prompt,
mod_config_installer::run_fomod_installer,
mod_config_installer::FomodInstaller,
types::{ModConfig, ModFile, ModdedInstance, RootConfig},
utils::{resolve_case_insensitive, walk_all_files},
};
@@ -66,7 +66,13 @@ fn install_fomod(
.collect();
trace!("Current loded plugins: {:?}", active_plugins);
let files = run_fomod_installer(module_config, &active_plugins, install_prompt::prompt)?;
let mut installer = FomodInstaller::new(&module_config, &active_plugins);
let mut selection: Option<Vec<usize>> = None;
while let Some(prompt) = installer.run_step(selection.as_deref()) {
selection = Some(install_prompt::prompt(prompt));
}
let files = installer.finalize();
let mod_files: Vec<_> = files
.iter()

View File

@@ -191,66 +191,80 @@ fn resolve_plugin_type(
}
}
pub fn run_fomod_installer(
fomod_config: Config,
installed_plugins: &[String],
group_prompt: fn(GroupPrompt) -> Vec<usize>,
) -> anyhow::Result<Vec<FileTypeEnum>> {
let mut state = InstallerState::new();
pub struct FomodInstaller<'a> {
state: InstallerState,
current_step: (usize, usize),
config: &'a Config,
installed_plugins: &'a [String],
}
// Always-installed files first
if let Some(required) = &fomod_config.required_install_files {
state.add_files(required);
impl<'a> FomodInstaller<'a> {
pub fn new(fomod_config: &'a Config, installed_plugins: &'a [String]) -> Self {
let mut state = InstallerState::new();
if let Some(required) = &fomod_config.required_install_files {
state.add_files(required);
}
Self {
state,
current_step: (0, 0),
config: fomod_config,
installed_plugins,
}
}
if let Some(install_steps) = fomod_config.install_steps {
let steps = &install_steps.install_step;
pub fn run_step(&mut self, selection: Option<&[usize]>) -> Option<GroupPrompt> {
let Some(install_steps) = &self.config.install_steps else {
return None;
};
for step in steps {
// Check if the step should be visible
if step
.visible
.as_ref()
.is_some_and(|v| !evaluate_module_depbendecy(v, &state, installed_plugins))
{
// Dependency to show the step not meet. Skipping.
continue;
}
let step = install_steps.install_step.get(self.current_step.0)?;
for group in &step.optional_file_groups.group {
// TODO: Skip groups where all plugins are NotUsable
// Check if the step should be visible
if step
.visible
.as_ref()
.is_some_and(|v| !evaluate_module_depbendecy(v, &self.state, self.installed_plugins))
{
// Dependency to show the step not meet. Skipping.
self.current_step = (self.current_step.0 + 1, 0);
return self.run_step(selection);
}
let prompt = GroupPrompt::new(group, &state, installed_plugins);
let Some(group) = step.optional_file_groups.group.get(self.current_step.1) else {
self.current_step = (self.current_step.0 + 1, 0);
return self.run_step(selection);
};
let selected_plugins = (group_prompt)(prompt);
// TODO: Skip groups where all plugins are NotUsable
match selection {
Some(selected_plugins) => {
for i in selected_plugins {
let plugin = &group.plugins.plugin[i];
let plugin = &group.plugins.plugin[*i];
// Add files from selected plugin
if let Some(files) = &plugin.files {
state.add_files(files);
self.state.add_files(files);
}
// Set condition flags
if let Some(condition_flags) = &plugin.condition_flags {
for flag in &condition_flags.flag {
state.set_flag(&flag.name, &flag.flag_value);
self.state.set_flag(&flag.name, &flag.flag_value);
}
}
}
// Next step
self.current_step = (self.current_step.0, self.current_step.1 + 1);
self.run_step(None)
}
None => Some(GroupPrompt::new(group, &self.state, self.installed_plugins)),
}
}
// Evaluate conditional file installs based on final flag state
if let Some(conditional) = &fomod_config.conditional_file_installs {
for pattern in &conditional.patterns.pattern {
if evaluate_module_depbendecy(&pattern.dependencies, &state, installed_plugins) {
state.add_files(&pattern.files);
}
}
pub fn finalize(self) -> Vec<FileTypeEnum> {
self.state.into_file_list()
}
Ok(state.into_file_list())
}