From 3531bc03178ce4d2d46fff9eb99a172c3dab3c65 Mon Sep 17 00:00:00 2001 From: Wiseguy <68165316+Mr-Wiseguy@users.noreply.github.com> Date: Mon, 7 Jul 2025 01:52:18 -0400 Subject: [PATCH] Optional dependencies for mod tool and add dependency name vector in recompiler context (#147) --- RecompModTool/main.cpp | 34 +++++++++++++++++++++++++++++++++- include/recompiler/context.h | 4 ++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/RecompModTool/main.cpp b/RecompModTool/main.cpp index 85d6d48..760b897 100644 --- a/RecompModTool/main.cpp +++ b/RecompModTool/main.cpp @@ -35,6 +35,8 @@ struct ModManifest { std::vector config_options; std::vector dependencies; std::vector full_dependency_strings; + std::vector optional_dependencies; + std::vector full_optional_dependency_strings; }; struct ModInputs { @@ -323,6 +325,31 @@ ModManifest parse_mod_config_manifest(const std::filesystem::path& basedir, cons }); } + // Optional dependency list (optional) + const toml::array& optional_dependency_array = read_toml_array(manifest_table, "optional_dependencies", false); + if (!optional_dependency_array.empty()) { + // Reserve room for all the dependencies. + ret.dependencies.reserve(optional_dependency_array.size()); + optional_dependency_array.for_each([&ret](const auto& el) { + if constexpr (toml::is_string) { + size_t dependency_id_length; + bool dependency_version_has_label; + if (!validate_dependency_string(el.template ref(), dependency_id_length, dependency_version_has_label)) { + throw toml::parse_error("Invalid optional dependency entry", el.source()); + } + if (dependency_version_has_label) { + throw toml::parse_error("Dependency versions may not have labels", el.source()); + } + std::string dependency_id = el.template ref().substr(0, dependency_id_length); + ret.optional_dependencies.emplace_back(dependency_id); + ret.full_optional_dependency_strings.emplace_back(el.template ref()); + } + else { + throw toml::parse_error("Invalid type for optional dependency entry", el.source()); + } + }); + } + // Config schema (optional) const toml::array& config_options_array = read_toml_array(manifest_table, "config_options", false); if (!config_options_array.empty()) { @@ -507,6 +534,10 @@ void write_manifest(const std::filesystem::path& path, const ModManifest& manife output_data.emplace("dependencies", string_vector_to_toml(manifest.full_dependency_strings)); } + if (!manifest.full_optional_dependency_strings.empty()) { + output_data.emplace("optional_dependencies", string_vector_to_toml(manifest.full_optional_dependency_strings)); + } + if (!manifest.config_options.empty()) { toml::array options_array{}; for (const auto& option : manifest.config_options) { @@ -1138,8 +1169,9 @@ int main(int argc, const char** argv) { } } - // Copy the dependencies from the config into the context. + // Copy the dependencies and optional dependencies from the config into the context. context.add_dependencies(config.manifest.dependencies); + context.add_dependencies(config.manifest.optional_dependencies); N64Recomp::ElfParsingConfig elf_config { .bss_section_suffix = {}, diff --git a/include/recompiler/context.h b/include/recompiler/context.h index 8e2ce5b..a3f0ac6 100644 --- a/include/recompiler/context.h +++ b/include/recompiler/context.h @@ -233,6 +233,8 @@ namespace N64Recomp { //// Mod dependencies and their symbols //// Imported values + // Dependency names. + std::vector dependencies; // Mapping of dependency name to dependency index. std::unordered_map dependencies_by_name; // List of symbols imported from dependencies. @@ -276,6 +278,7 @@ namespace N64Recomp { size_t dependency_index = dependencies_by_name.size(); + dependencies.emplace_back(id); dependencies_by_name.emplace(id, dependency_index); dependency_events_by_name.resize(dependencies_by_name.size()); dependency_imports_by_name.resize(dependencies_by_name.size()); @@ -295,6 +298,7 @@ namespace N64Recomp { for (const std::string& dep : new_dependencies) { size_t dependency_index = dependencies_by_name.size(); + dependencies.emplace_back(dep); dependencies_by_name.emplace(dep, dependency_index); }