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::{ use crate::{
fomod, install_prompt, fomod, install_prompt,
mod_config_installer::run_fomod_installer, mod_config_installer::FomodInstaller,
types::{ModConfig, ModFile, ModdedInstance, RootConfig}, types::{ModConfig, ModFile, ModdedInstance, RootConfig},
utils::{resolve_case_insensitive, walk_all_files}, utils::{resolve_case_insensitive, walk_all_files},
}; };
@@ -66,7 +66,13 @@ fn install_fomod(
.collect(); .collect();
trace!("Current loded plugins: {:?}", active_plugins); 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 let mod_files: Vec<_> = files
.iter() .iter()

View File

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