Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 0 additions & 171 deletions src/openvic-simulation/country/CountryDefinition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,6 @@

#include <string_view>

#include <openvic-dataloader/v2script/AbstractSyntaxTree.hpp>

#include "openvic-simulation/dataloader/Dataloader.hpp"
#include "openvic-simulation/dataloader/NodeTools.hpp"
#include "openvic-simulation/DefinitionManager.hpp"
#include "openvic-simulation/politics/Government.hpp"
#include "openvic-simulation/politics/Ideology.hpp"
#include "openvic-simulation/politics/PartyPolicy.hpp"
#include "openvic-simulation/population/Culture.hpp"
#include "openvic-simulation/types/Colour.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
Expand Down Expand Up @@ -72,167 +64,4 @@ bool CountryDefinitionManager::add_country(
);
}

bool CountryDefinitionManager::load_countries(
DefinitionManager const& definition_manager, Dataloader const& dataloader, ast::NodeCPtr root
) {
static constexpr std::string_view common_dir = "common/";
bool is_dynamic = false;

const bool ret = expect_dictionary_reserve_length(
country_definitions,
[this, &definition_manager, &is_dynamic, &dataloader](std::string_view key, ast::NodeCPtr value) -> bool {
if (key == "dynamic_tags") {
return expect_bool([&is_dynamic](bool val) -> bool {
if (val == is_dynamic) {
spdlog::warn_s("Redundant \"is_dynamic\", already {}", val ? "true" : "false");
} else {
if (is_dynamic) {
spdlog::warn_s("Changing \"is_dynamic\" back to false");
}
is_dynamic = val;
}
return true;
})(value);
}
if (expect_string(
[this, &definition_manager, is_dynamic, &dataloader, &key](std::string_view filepath) -> bool {
if (load_country_data_file(
definition_manager, key, is_dynamic,
Dataloader::parse_defines(
dataloader.lookup_file(StringUtils::append_string_views(common_dir, filepath))
).get_file_node()
)) {
return true;
}
spdlog::critical_s("Failed to load country data file: {}", filepath);
return false;
}
)(value)) {
return true;
}
spdlog::critical_s("Failed to load country: {}", key);
return false;
}
)(root);
lock_country_definitions();
return ret;
}

bool CountryDefinitionManager::load_country_colours(ast::NodeCPtr root) {
return country_definitions.expect_item_dictionary_and_default(
[](std::string_view key, ast::NodeCPtr value) -> bool {
spdlog::warn_s("country_colors.txt references country tag {} which is not defined!", key);
return true;
},
[](CountryDefinition& country, ast::NodeCPtr colour_node) -> bool {
return expect_dictionary_keys(
"color1", ONE_EXACTLY, expect_colour(assign_variable_callback(country.primary_unit_colour)),
"color2", ONE_EXACTLY, expect_colour(assign_variable_callback(country.secondary_unit_colour)),
"color3", ONE_EXACTLY, expect_colour(assign_variable_callback(country.tertiary_unit_colour))
)(colour_node);
}
)(root);
}

node_callback_t CountryDefinitionManager::load_country_party(
PoliticsManager const& politics_manager, IdentifierRegistry<CountryParty>& country_parties
) const {
return [&politics_manager, &country_parties](ast::NodeCPtr value) -> bool {
std::string_view party_name;
Date start_date, end_date;
Ideology const* ideology = nullptr;
IndexedFlatMap<PartyPolicyGroup, PartyPolicy const*> policies { politics_manager.get_issue_manager().get_party_policy_groups() };

bool ret = expect_dictionary_keys_and_default(
[&politics_manager, &policies, &party_name](std::string_view key, ast::NodeCPtr value) -> bool {
return politics_manager.get_issue_manager().expect_party_policy_group_str(
[&politics_manager, &policies, value, &party_name](PartyPolicyGroup const& party_policy_group) -> bool {
PartyPolicy const*& policy = policies.at(party_policy_group);

if (policy != nullptr) {
spdlog::error_s(
"Country party \"{}\" has duplicate entry for party policy group \"{}\"",
party_name, party_policy_group
);
return false;
}

return politics_manager.get_issue_manager().expect_party_policy_identifier(
[&party_policy_group, &policy](PartyPolicy const& party_policy) -> bool {
if (&party_policy.get_issue_group() == &party_policy_group) {
policy = &party_policy;
return true;
}

// TODO - change this back to error/false once TGC no longer has this issue
spdlog::warn_s(
"Invalid party policy \"{}\", group is \"{}\" when \"{}\" was expected.",
party_policy,
party_policy.get_issue_group(),
party_policy_group
);
return true;
}
)(value);
}
)(key);
},
"name", ONE_EXACTLY, expect_string(assign_variable_callback(party_name)),
"start_date", ONE_EXACTLY, expect_date(assign_variable_callback(start_date)),
"end_date", ONE_EXACTLY, expect_date(assign_variable_callback(end_date)),
"ideology", ONE_EXACTLY,
politics_manager.get_ideology_manager().expect_ideology_identifier(assign_variable_callback_pointer(ideology))
)(value);

if (ideology == nullptr) {
spdlog::warn_s("Country party {} has no ideology, defaulting to nullptr / no ideology", party_name);
}

ret &= country_parties.emplace_item(
party_name,
duplicate_warning_callback,
party_name, start_date, end_date, ideology, std::move(policies)
);

return ret;
};
}

bool CountryDefinitionManager::load_country_data_file(
DefinitionManager const& definition_manager, std::string_view name, bool is_dynamic, ast::NodeCPtr root
) {
colour_t colour;
GraphicalCultureType const* graphical_culture;
IdentifierRegistry<CountryParty> parties { "country parties" };
CountryDefinition::unit_names_map_t unit_names;
CountryDefinition::government_colour_map_t alternative_colours;
bool ret = expect_dictionary_keys_and_default(
[&definition_manager, &alternative_colours](std::string_view key, ast::NodeCPtr value) -> bool {
return definition_manager.get_politics_manager().get_government_type_manager().expect_government_type_str(
[&alternative_colours, value](GovernmentType const& government_type) -> bool {
return expect_colour(map_callback(alternative_colours, &government_type))(value);
}
)(key);
},
"color", ONE_EXACTLY, expect_colour(assign_variable_callback(colour)),
"graphical_culture", ONE_EXACTLY,
definition_manager.get_pop_manager().get_culture_manager().expect_graphical_culture_type_identifier(
assign_variable_callback_pointer(graphical_culture)
),
"party", ZERO_OR_MORE, load_country_party(definition_manager.get_politics_manager(), parties),
"unit_names", ZERO_OR_ONE,
definition_manager.get_military_manager().get_unit_type_manager().expect_unit_type_dictionary_reserve_length(
unit_names,
[&unit_names](UnitType const& unit, ast::NodeCPtr value) -> bool {
return name_list_callback(map_callback(unit_names, &unit))(value);
}
)
)(root);

ret &= add_country(
name, colour, graphical_culture, std::move(parties), std::move(unit_names), is_dynamic, std::move(alternative_colours)
);
return ret;
}

template struct fmt::formatter<OpenVic::CountryDefinition>;
21 changes: 5 additions & 16 deletions src/openvic-simulation/country/CountryDefinition.hpp
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to move the CountryDefinitionManager out.
Either move it to a separate file or split it between the DefinitionManager and the CountryParser entirely (my preference).

Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,9 @@ namespace OpenVic {
unit_names_map_t PROPERTY(unit_names);
const bool PROPERTY_CUSTOM_PREFIX(dynamic_tag, is);
government_colour_map_t PROPERTY(alternative_colours);
colour_t PROPERTY(primary_unit_colour);
colour_t PROPERTY(secondary_unit_colour);
colour_t PROPERTY(tertiary_unit_colour);
// Unit colours not const due to being added after construction

colour_t PROPERTY_RW(primary_unit_colour);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why use property here?
Wouldn't exposing the fields work just fine?

Copy link
Member Author

@Spartan322 Spartan322 Nov 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No because PROPERTY only generate a const getter, (and even then colour returns by value anyway) the unit colours need to be assigned.

colour_t PROPERTY_RW(secondary_unit_colour);
colour_t PROPERTY_RW(tertiary_unit_colour);

public:
CountryDefinition(
Expand All @@ -56,23 +54,14 @@ namespace OpenVic {
private:
IdentifierRegistry<CountryDefinition> IDENTIFIER_REGISTRY(country_definition);

NodeTools::node_callback_t load_country_party(
PoliticsManager const& politics_manager, IdentifierRegistry<CountryParty>& country_parties
) const;

public:
IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(country_definition);

bool add_country(
std::string_view identifier, colour_t colour, GraphicalCultureType const* graphical_culture,
IdentifierRegistry<CountryParty>&& parties, CountryDefinition::unit_names_map_t&& unit_names, bool dynamic_tag,
CountryDefinition::government_colour_map_t&& alternative_colours
);

bool load_country_colours(ast::NodeCPtr root);

bool load_countries(DefinitionManager const& definition_manager, Dataloader const& dataloader, ast::NodeCPtr root);
bool load_country_data_file(
DefinitionManager const& definition_manager, std::string_view name, bool is_dynamic, ast::NodeCPtr root
);
};
}

Expand Down
60 changes: 48 additions & 12 deletions src/openvic-simulation/dataloader/Dataloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
#include <fmt/std.h>

#include "openvic-simulation/DefinitionManager.hpp"
#include "openvic-simulation/dataloader/parse/CountryParser.hpp"
#include "openvic-simulation/interface/UI.hpp"
#include "openvic-simulation/misc/GameRulesManager.hpp"
#include "openvic-simulation/misc/SoundEffect.hpp"
#include "openvic-simulation/utility/Error.hpp"
#include "openvic-simulation/utility/Logger.hpp"
#include "openvic-simulation/utility/StringUtils.hpp"
#include "openvic-simulation/utility/Containers.hpp"
Expand Down Expand Up @@ -926,6 +928,49 @@ bool Dataloader::_load_sound_effect_defines(DefinitionManager& definition_manage

}

static constexpr std::string_view common_folder = "common/";
static constexpr std::string_view countries_file = "common/countries.txt";
static constexpr std::string_view country_colours_file = "common/country_colors.txt";

Error Dataloader::_load_countries(DefinitionManager& definition_manager) {
CountryParser country_parser {
definition_manager.get_politics_manager().get_government_type_manager().get_government_type_registry(),
definition_manager.get_pop_manager().get_culture_manager().get_graphical_culture_type_registry(),
definition_manager.get_military_manager().get_unit_type_manager().get_unit_type_registry(),
definition_manager.get_politics_manager().get_issue_manager().get_party_policy_group_registry(),
definition_manager.get_politics_manager().get_issue_manager().get_party_policy_registry(),
definition_manager.get_politics_manager().get_ideology_manager().get_ideology_registry(),
parse_defines(lookup_file(countries_file))
};

if (Error err = country_parser.load_country_list(); err != Error::OK) {
spdlog::critical_s("Failed to load country list!");
return err;
}

if (Error err = country_parser.load_countries_from( //
common_folder, *this, definition_manager.get_country_definition_manager()
);
err != Error::OK //
) {
spdlog::critical_s("Failed to load countries!");
return err;
}

if (Error err = country_parser.load_country_colours(
parse_defines(lookup_file(country_colours_file)).get_file_node(),
definition_manager.get_country_definition_manager()
);
err != Error::OK //
) {
spdlog::critical_s("Failed to load country colours!");
return err;
}

return Error::OK;
}


bool Dataloader::load_defines(
GameRulesManager const& game_rules_manager,
DefinitionManager& definition_manager
Expand All @@ -938,8 +983,6 @@ bool Dataloader::load_defines(
static constexpr std::string_view defines_file = "common/defines.lua";
static constexpr std::string_view buildings_file = "common/buildings.txt";
static constexpr std::string_view bookmark_file = "common/bookmarks.txt";
static constexpr std::string_view countries_file = "common/countries.txt";
static constexpr std::string_view country_colours_file = "common/country_colors.txt";
static constexpr std::string_view culture_file = "common/cultures.txt";
static constexpr std::string_view governments_file = "common/governments.txt";
static constexpr std::string_view graphical_culture_type_file = "common/graphicalculturetype.txt";
Expand Down Expand Up @@ -1135,18 +1178,11 @@ bool Dataloader::load_defines(
spdlog::critical_s("Failed to load bookmarks!");
ret = false;
}
if (!definition_manager.get_country_definition_manager().load_countries(
definition_manager, *this, parse_defines(lookup_file(countries_file)).get_file_node()
)) {
spdlog::critical_s("Failed to load countries!");
ret = false;
}
if (!definition_manager.get_country_definition_manager().load_country_colours(
parse_defines(lookup_file(country_colours_file)).get_file_node()
)) {
spdlog::critical_s("Failed to load country colours!");

if(_load_countries(definition_manager) != Error::OK) {
ret = false;
}

if (!definition_manager.get_pop_manager().get_culture_manager().load_culture_file(
definition_manager.get_country_definition_manager(), parse_defines(lookup_file(culture_file)).get_file_node()
)) {
Expand Down
2 changes: 2 additions & 0 deletions src/openvic-simulation/dataloader/Dataloader.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "openvic-simulation/dataloader/ModManager.hpp"
#include "openvic-simulation/utility/Containers.hpp"
#include "openvic-simulation/utility/Concepts.hpp"
#include "openvic-simulation/utility/Error.hpp"

#include <function2/function2.hpp>

Expand Down Expand Up @@ -43,6 +44,7 @@ namespace OpenVic {
bool _load_sound_effect_defines(DefinitionManager& definition_manager) const;
bool _load_decisions(DefinitionManager& definition_manager);
bool _load_history(DefinitionManager& definition_manager, bool unused_history_file_warnings) const;
Error _load_countries(DefinitionManager& definition_manager);

bool should_ignore_path(fs::path const& path, path_span_t replace_paths) const;

Expand Down
Loading