Optional dependencies for mod tool and add dependency name vector in recompiler context (#147)

This commit is contained in:
Wiseguy 2025-07-07 01:52:18 -04:00 committed by GitHub
parent 989a86b369
commit 3531bc0317
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 37 additions and 1 deletions

View file

@ -35,6 +35,8 @@ struct ModManifest {
std::vector<toml::table> config_options;
std::vector<std::string> dependencies;
std::vector<std::string> full_dependency_strings;
std::vector<std::string> optional_dependencies;
std::vector<std::string> 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<decltype(el)>) {
size_t dependency_id_length;
bool dependency_version_has_label;
if (!validate_dependency_string(el.template ref<std::string>(), 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<std::string>().substr(0, dependency_id_length);
ret.optional_dependencies.emplace_back(dependency_id);
ret.full_optional_dependency_strings.emplace_back(el.template ref<std::string>());
}
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 = {},

View file

@ -233,6 +233,8 @@ namespace N64Recomp {
//// Mod dependencies and their symbols
//// Imported values
// Dependency names.
std::vector<std::string> dependencies;
// Mapping of dependency name to dependency index.
std::unordered_map<std::string, size_t> 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);
}