From 22bab51a45b53df69bf998a4de24b58020ffedb8 Mon Sep 17 00:00:00 2001 From: wvpm <24685035+wvpm@users.noreply.github.com> Date: Tue, 24 Feb 2026 19:58:31 +0100 Subject: [PATCH] Refactor units, leader & provinces to use reference_wrapper --- .../country/CountryInstance.cpp | 64 +++---- .../country/CountryInstance.hpp | 9 +- .../country/CountryInstanceManager.cpp | 4 +- .../history/CountryHistory.hpp | 2 +- .../map/ProvinceDefinition.hpp | 4 +- .../map/ProvinceInstance.cpp | 33 ++-- .../map/ProvinceInstance.hpp | 6 +- .../military/Deployment.cpp | 34 ++-- .../military/Deployment.hpp | 5 +- src/openvic-simulation/military/Leader.hpp | 8 +- .../military/UnitInstance.hpp | 4 + .../military/UnitInstanceGroup.cpp | 162 +++++++++--------- .../military/UnitInstanceGroup.hpp | 70 ++++---- .../pathfinding/AStarPathing.cpp | 4 +- 14 files changed, 219 insertions(+), 190 deletions(-) diff --git a/src/openvic-simulation/country/CountryInstance.cpp b/src/openvic-simulation/country/CountryInstance.cpp index cdbdf3729..d961e1483 100644 --- a/src/openvic-simulation/country/CountryInstance.cpp +++ b/src/openvic-simulation/country/CountryInstance.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -705,10 +706,10 @@ bool CountryInstance::add_unit_instance_group(UnitInstanceGroup& group) { switch (group.branch) { case LAND: - armies.push_back(static_cast(&group)); + armies.emplace_back(static_cast(group)); return true; case NAVAL: - navies.push_back(static_cast(&group)); + navies.emplace_back(static_cast(group)); return true; default: spdlog::error_s( @@ -721,10 +722,13 @@ bool CountryInstance::add_unit_instance_group(UnitInstanceGroup& group) { bool CountryInstance::remove_unit_instance_group(UnitInstanceGroup const& group) { const auto remove_from_vector = [this, &group]( - memory::vector*>& unit_instance_groups + memory::vector>>& unit_instance_groups ) -> bool { - const typename memory::vector*>::const_iterator it = - std::find(unit_instance_groups.begin(), unit_instance_groups.end(), &group); + const auto it = std::find( + unit_instance_groups.begin(), + unit_instance_groups.end(), + group + ); if (it != unit_instance_groups.end()) { unit_instance_groups.erase(it); @@ -759,10 +763,10 @@ bool CountryInstance::add_leader(LeaderInstance& leader) { switch (leader.branch) { case LAND: - generals.push_back(&leader); + generals.push_back(leader); return true; case NAVAL: - admirals.push_back(&leader); + admirals.push_back(leader); return true; default: spdlog::error_s( @@ -776,7 +780,7 @@ bool CountryInstance::add_leader(LeaderInstance& leader) { bool CountryInstance::remove_leader(LeaderInstance const& leader) { using enum unit_branch_t; - memory::vector* leaders; + memory::vector>* leaders; switch (leader.branch) { case LAND: @@ -793,7 +797,7 @@ bool CountryInstance::remove_leader(LeaderInstance const& leader) { return false; } - const typename memory::vector::const_iterator it = std::find(leaders->begin(), leaders->end(), &leader); + const auto it = std::find(leaders->begin(), leaders->end(), leader); if (it != leaders->end()) { leaders->erase(it); @@ -808,9 +812,11 @@ bool CountryInstance::remove_leader(LeaderInstance const& leader) { } bool CountryInstance::has_leader_with_name(std::string_view name) const { - const auto check_leaders = [&name](memory::vector const& leaders) -> bool { - for (LeaderInstance const* leader : leaders) { - if (leader->get_name() == name) { + const auto check_leaders = [name]( + memory::vector> const& leaders + ) -> bool { + for (LeaderInstance const& leader : leaders) { + if (leader.get_name() == name) { return true; } } @@ -1595,24 +1601,24 @@ void CountryInstance::_update_diplomacy() { void CountryInstance::_update_military() { regiment_count = 0; - for (ArmyInstance const* army : armies) { - regiment_count += army->get_unit_count(); + for (ArmyInstance const& army : armies) { + regiment_count += army.get_unit_count(); } ship_count = 0; total_consumed_ship_supply = 0; - for (NavyInstance const* navy : navies) { - ship_count += navy->get_unit_count(); - total_consumed_ship_supply += navy->get_total_consumed_supply(); + for (NavyInstance const& navy : navies) { + ship_count += navy.get_unit_count(); + total_consumed_ship_supply += navy.get_total_consumed_supply(); } // Calculate military power from land, sea, and leaders size_t deployed_non_mobilised_regiments = 0; - for (ArmyInstance const* army : armies) { - for (RegimentInstance const* regiment : army->get_regiment_instances()) { - if (!regiment->is_mobilised()) { + for (ArmyInstance const& army : armies) { + for (RegimentInstance const& regiment : army.get_regiment_instances()) { + if (!regiment.is_mobilised()) { deployed_non_mobilised_regiments++; } } @@ -1643,9 +1649,9 @@ void CountryInstance::_update_military() { } fixed_point_t military_power_from_sea_running_total = 0; - for (NavyInstance const* navy : navies) { - for (ShipInstance const* ship : navy->get_ship_instances()) { - ShipType const& ship_type = ship->get_ship_type(); + for (NavyInstance const& navy : navies) { + for (ShipInstance const& ship : navy.get_ship_instances()) { + ShipType const& ship_type = ship.get_ship_type(); if (ship_type.is_capital) { @@ -1908,7 +1914,7 @@ void CountryInstance::update_gamestate(const Date today, MapInstance& map_instan for (ProvinceDefinition::adjacency_t const& adjacency : province_definition.get_adjacencies()) { // TODO - should we limit based on adjacency type? Straits and impassable still work in game, // and water provinces don't have an owner so they'll get caught by the later checks anyway. - CountryInstance* neighbour = map_instance.get_province_instance_by_definition(*adjacency.get_to()).get_owner(); + CountryInstance* neighbour = map_instance.get_province_instance_by_definition(adjacency.get_to()).get_owner(); if (neighbour != nullptr && neighbour != this) { neighbouring_countries.insert(neighbour); } @@ -1922,18 +1928,18 @@ void CountryInstance::update_gamestate(const Date today, MapInstance& map_instan if (capital != nullptr) { capital->set_connected_to_capital(true); - memory::vector province_checklist { capital }; + memory::vector> province_checklist { *capital }; - for (size_t index = 0; index < province_checklist.size(); index++) { - ProvinceInstance const& province = *province_checklist[index]; + for (size_t index = 0; index < province_checklist.size(); ++index) { + ProvinceInstance const& province = province_checklist[index]; for (ProvinceDefinition::adjacency_t const& adjacency : province.province_definition.get_adjacencies()) { - ProvinceInstance& adjacent_province = map_instance.get_province_instance_by_definition(*adjacency.get_to()); + ProvinceInstance& adjacent_province = map_instance.get_province_instance_by_definition(adjacency.get_to()); if (adjacent_province.get_owner() == this && !adjacent_province.get_connected_to_capital()) { adjacent_province.set_connected_to_capital(true); adjacent_province.set_is_overseas(false); - province_checklist.push_back(&adjacent_province); + province_checklist.emplace_back(adjacent_province); } } } diff --git a/src/openvic-simulation/country/CountryInstance.hpp b/src/openvic-simulation/country/CountryInstance.hpp index 692865851..3d3b2744a 100644 --- a/src/openvic-simulation/country/CountryInstance.hpp +++ b/src/openvic-simulation/country/CountryInstance.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -353,10 +354,10 @@ namespace OpenVic { OV_STATE_PROPERTY(fixed_point_t, military_power_from_sea); OV_STATE_PROPERTY(fixed_point_t, military_power_from_leaders); size_t PROPERTY(military_rank, 0); - memory::vector SPAN_PROPERTY(generals); - memory::vector SPAN_PROPERTY(admirals); - memory::vector SPAN_PROPERTY(armies); - memory::vector SPAN_PROPERTY(navies); + memory::vector> SPAN_PROPERTY(generals); + memory::vector> SPAN_PROPERTY(admirals); + memory::vector> SPAN_PROPERTY(armies); + memory::vector> SPAN_PROPERTY(navies); size_t PROPERTY(regiment_count, 0); size_t PROPERTY(mobilisation_potential_regiment_count, 0); size_t PROPERTY(mobilisation_max_regiment_count, 0); diff --git a/src/openvic-simulation/country/CountryInstanceManager.cpp b/src/openvic-simulation/country/CountryInstanceManager.cpp index e10b3f1f2..c22ad2309 100644 --- a/src/openvic-simulation/country/CountryInstanceManager.cpp +++ b/src/openvic-simulation/country/CountryInstanceManager.cpp @@ -239,7 +239,7 @@ bool CountryInstanceManager::apply_history_to_countries(InstanceManager& instanc map_instance ); - if (entry->get_initial_oob().has_value()) { + if (entry->get_initial_oob() != nullptr) { oob_history_entry = entry.get(); } if (entry->get_consciousness().has_value()) { @@ -261,7 +261,7 @@ bool CountryInstanceManager::apply_history_to_countries(InstanceManager& instanc } if (oob_history_entry != nullptr) { - ret &= unit_instance_manager.generate_deployment( + ret &= oob_history_entry->get_initial_oob() != nullptr && unit_instance_manager.generate_deployment( map_instance, country_instance, *oob_history_entry->get_initial_oob() ); } diff --git a/src/openvic-simulation/history/CountryHistory.hpp b/src/openvic-simulation/history/CountryHistory.hpp index 62bb11444..72ac07278 100644 --- a/src/openvic-simulation/history/CountryHistory.hpp +++ b/src/openvic-simulation/history/CountryHistory.hpp @@ -43,7 +43,7 @@ namespace OpenVic { std::optional PROPERTY_CUSTOM_PREFIX(civilised, is); std::optional PROPERTY(prestige); ordered_set PROPERTY(reforms); - std::optional PROPERTY(initial_oob); + Deployment const* PROPERTY(initial_oob, nullptr); std::optional PROPERTY(tech_school); ordered_map PROPERTY(technologies); ordered_map PROPERTY(inventions); diff --git a/src/openvic-simulation/map/ProvinceDefinition.hpp b/src/openvic-simulation/map/ProvinceDefinition.hpp index 3bc9fd135..147e36ffd 100644 --- a/src/openvic-simulation/map/ProvinceDefinition.hpp +++ b/src/openvic-simulation/map/ProvinceDefinition.hpp @@ -1,8 +1,8 @@ #pragma once +#include #include -#include #include #include "openvic-simulation/dataloader/NodeTools.hpp" @@ -53,7 +53,7 @@ namespace OpenVic { private: // fields are const after loading. They have to be mutable to support std::vector.erase(iterator) - type_safe::object_ref PROPERTY(to); + std::reference_wrapper PROPERTY(to); ProvinceDefinition const* PROPERTY(through); distance_t PROPERTY(distance); type_t PROPERTY(type); diff --git a/src/openvic-simulation/map/ProvinceInstance.cpp b/src/openvic-simulation/map/ProvinceInstance.cpp index 158405a3f..0e84b6dd3 100644 --- a/src/openvic-simulation/map/ProvinceInstance.cpp +++ b/src/openvic-simulation/map/ProvinceInstance.cpp @@ -340,23 +340,23 @@ void ProvinceInstance::update_gamestate(InstanceManager const& instance_manager) MapInstance const& map_instance = instance_manager.get_map_instance(); for (ProvinceDefinition::adjacency_t const& adjacency : province_definition.get_adjacencies()) { - ProvinceDefinition const& province_definition = *adjacency.get_to(); - ProvinceInstance const& province_instance = map_instance.get_province_instance_by_definition(province_definition); + ProvinceDefinition const& adjacent_to_definition = adjacency.get_to(); + ProvinceInstance const& adjacent_to_instance = map_instance.get_province_instance_by_definition(adjacent_to_definition); - if (province_instance.is_empty()) { + if (adjacent_to_instance.is_empty()) { has_empty_adjacent_province = true; - } else if (!province_definition.is_water()) { - adjacent_nonempty_land_provinces.push_back(&province_instance); + } else if (!adjacent_to_definition.is_water()) { + adjacent_nonempty_land_provinces.emplace_back(adjacent_to_instance); } } land_regiment_count = 0; - for (ArmyInstance const* army : armies) { - land_regiment_count += army->get_unit_count(); + for (ArmyInstance const& army : armies) { + land_regiment_count += army.get_unit_count(); } - for (NavyInstance const* navy : navies) { - for (ArmyInstance const* army : navy->get_carried_armies()) { - land_regiment_count += army->get_unit_count(); + for (NavyInstance const& navy : navies) { + for (ArmyInstance const& army : navy.get_carried_armies()) { + land_regiment_count += army.get_unit_count(); } } @@ -409,10 +409,10 @@ bool ProvinceInstance::add_unit_instance_group(UnitInstanceGroup& group) { switch (group.branch) { case LAND: - armies.push_back(static_cast(&group)); + armies.emplace_back(static_cast(group)); return true; case NAVAL: - navies.push_back(static_cast(&group)); + navies.emplace_back(static_cast(group)); return true; default: spdlog::error_s( @@ -425,10 +425,13 @@ bool ProvinceInstance::add_unit_instance_group(UnitInstanceGroup& group) { bool ProvinceInstance::remove_unit_instance_group(UnitInstanceGroup const& group) { const auto remove_from_vector = [this, &group]( - memory::vector*>& unit_instance_groups + memory::vector>>& unit_instance_groups ) -> bool { - const typename memory::vector*>::const_iterator it = - std::find(unit_instance_groups.begin(), unit_instance_groups.end(), &group); + auto it = std::find( + unit_instance_groups.begin(), + unit_instance_groups.end(), + group + ); if (it != unit_instance_groups.end()) { unit_instance_groups.erase(it); diff --git a/src/openvic-simulation/map/ProvinceInstance.hpp b/src/openvic-simulation/map/ProvinceInstance.hpp index 55b1e2736..eb48f2636 100644 --- a/src/openvic-simulation/map/ProvinceInstance.hpp +++ b/src/openvic-simulation/map/ProvinceInstance.hpp @@ -97,7 +97,7 @@ namespace OpenVic { bool PROPERTY_RW(connected_to_capital, false); bool PROPERTY_RW(is_overseas, false); bool PROPERTY(has_empty_adjacent_province, false); - memory::vector SPAN_PROPERTY(adjacent_nonempty_land_provinces); + memory::vector> SPAN_PROPERTY(adjacent_nonempty_land_provinces); Crime const* PROPERTY_RW(crime, nullptr); ResourceGatheringOperation PROPERTY(rgo); memory::FixedVector _buildings; @@ -107,8 +107,8 @@ namespace OpenVic { return buildings; } private: - memory::vector SPAN_PROPERTY(armies); - memory::vector SPAN_PROPERTY(navies); + memory::vector> SPAN_PROPERTY(armies); + memory::vector> SPAN_PROPERTY(navies); // The number of land regiments currently in the province, including those being transported by navies size_t PROPERTY(land_regiment_count, 0); Timespan PROPERTY(occupation_duration); diff --git a/src/openvic-simulation/military/Deployment.cpp b/src/openvic-simulation/military/Deployment.cpp index 49640eda2..6959d7b54 100644 --- a/src/openvic-simulation/military/Deployment.cpp +++ b/src/openvic-simulation/military/Deployment.cpp @@ -20,7 +20,7 @@ UnitDeployment::UnitDeployment(std::string_view new_name, template UnitDeploymentGroup::UnitDeploymentGroup( - std::string_view new_name, ProvinceDefinition const* new_location, memory::vector<_Unit>&& new_units, + std::string_view new_name, ProvinceDefinition const& new_location, memory::vector<_Unit>&& new_units, std::optional new_leader_index ) : name { new_name }, location { new_location }, units { std::move(new_units) }, leader_index { new_leader_index } {} @@ -169,7 +169,7 @@ bool DeploymentManager::load_oob_file( const size_t starting_general_count = general_count; - const bool ret = expect_dictionary_keys( + if(!expect_dictionary_keys( "name", ONE_EXACTLY, expect_string(assign_variable_callback(army_name)), "location", ONE_EXACTLY, map_definition.expect_province_definition_identifier( assign_variable_callback_pointer(army_location) @@ -201,14 +201,20 @@ bool DeploymentManager::load_oob_file( return ret; }, "leader", ZERO_OR_ONE, leader_callback - )(node); + )(node)) { + return false; + } armies.emplace_back( - army_name, army_location, std::move(army_regiments), - starting_general_count < general_count ? std::optional { general_count - 1 } : std::nullopt + army_name, + *army_location, + std::move(army_regiments), + starting_general_count < general_count + ? std::optional { general_count - 1 } + : std::nullopt ); - return ret; + return true; }, "navy", ZERO_OR_MORE, [&admiral_count, &map_definition, &military_manager, &leader_callback](ast::NodeCPtr node) -> bool { std::string_view navy_name {}; @@ -217,7 +223,7 @@ bool DeploymentManager::load_oob_file( const size_t starting_admiral_count = admiral_count; - const bool ret = expect_dictionary_keys( + if(!expect_dictionary_keys( "name", ONE_EXACTLY, expect_string(assign_variable_callback(navy_name)), "location", ONE_EXACTLY, map_definition.expect_province_definition_identifier( assign_variable_callback_pointer(navy_location) @@ -242,14 +248,20 @@ bool DeploymentManager::load_oob_file( return ret; }, "leader", ZERO_OR_ONE, leader_callback - )(node); + )(node)) { + return false; + } navies.emplace_back( - navy_name, navy_location, std::move(navy_ships), - starting_admiral_count < admiral_count ? std::optional { admiral_count - 1 } : std::nullopt + navy_name, + *navy_location, + std::move(navy_ships), + starting_admiral_count < admiral_count + ? std::optional { admiral_count - 1 } + : std::nullopt ); - return ret; + return true; } )(Dataloader::parse_defines(lookedup_path).get_file_node()); diff --git a/src/openvic-simulation/military/Deployment.hpp b/src/openvic-simulation/military/Deployment.hpp index 5f6ad07ed..c3c1a073b 100644 --- a/src/openvic-simulation/military/Deployment.hpp +++ b/src/openvic-simulation/military/Deployment.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -61,13 +62,13 @@ namespace OpenVic { private: memory::string PROPERTY(name); - ProvinceDefinition const* PROPERTY(location); + std::reference_wrapper PROPERTY(location); memory::vector<_Unit> SPAN_PROPERTY(units); std::optional PROPERTY(leader_index); public: UnitDeploymentGroup( - std::string_view new_name, ProvinceDefinition const* new_location, memory::vector<_Unit>&& new_units, + std::string_view new_name, ProvinceDefinition const& new_location, memory::vector<_Unit>&& new_units, std::optional new_leader_index ); UnitDeploymentGroup(UnitDeploymentGroup&&) = default; diff --git a/src/openvic-simulation/military/Leader.hpp b/src/openvic-simulation/military/Leader.hpp index b3cabc1ce..25c4245cf 100644 --- a/src/openvic-simulation/military/Leader.hpp +++ b/src/openvic-simulation/military/Leader.hpp @@ -52,11 +52,15 @@ namespace OpenVic { private: UnitInstanceGroup* PROPERTY_PTR(unit_instance_group, nullptr); bool PROPERTY_RW(can_be_used, true); - - LeaderInstance(unique_id_t new_unique_id, LeaderBase const& leader_base, CountryInstance const& new_country); public: const unique_id_t unique_id; CountryInstance const& country; + + LeaderInstance(unique_id_t new_unique_id, LeaderBase const& leader_base, CountryInstance const& new_country); + + constexpr bool operator==(LeaderInstance const& rhs) const { + return unique_id == rhs.unique_id; + } }; } diff --git a/src/openvic-simulation/military/UnitInstance.hpp b/src/openvic-simulation/military/UnitInstance.hpp index daf2506a6..9b3a57d6d 100644 --- a/src/openvic-simulation/military/UnitInstance.hpp +++ b/src/openvic-simulation/military/UnitInstance.hpp @@ -39,6 +39,10 @@ namespace OpenVic { } void set_name(std::string_view new_name); + + constexpr bool operator==(UnitInstance const& rhs) const { + return unique_id == rhs.unique_id; + } }; struct Pop; diff --git a/src/openvic-simulation/military/UnitInstanceGroup.cpp b/src/openvic-simulation/military/UnitInstanceGroup.cpp index bc3b3429b..6bb28d70f 100644 --- a/src/openvic-simulation/military/UnitInstanceGroup.cpp +++ b/src/openvic-simulation/military/UnitInstanceGroup.cpp @@ -2,6 +2,8 @@ #include +#include + #include "openvic-simulation/country/CountryInstance.hpp" #include "openvic-simulation/defines/MilitaryDefines.hpp" #include "openvic-simulation/map/MapInstance.hpp" @@ -12,7 +14,6 @@ #include "openvic-simulation/population/PopType.hpp" #include "openvic-simulation/types/OrderedContainersMath.hpp" #include "openvic-simulation/utility/Containers.hpp" -#include "openvic-simulation/core/FormatValidate.hpp" using namespace OpenVic; @@ -21,10 +22,16 @@ using enum unit_branch_t; UnitInstanceGroup::UnitInstanceGroup( unique_id_t new_unique_id, unit_branch_t new_branch, - std::string_view new_name + std::string_view new_name, + CountryInstance& new_country, + ProvinceInstance& new_location ) : unique_id { new_unique_id }, branch { new_branch }, - name { new_name } {} + name { new_name }, + country { new_country }, + location { new_location } { + new_country.add_unit_instance_group(*this); + } void UnitInstanceGroup::update_gamestate() { total_organisation = 0; @@ -32,11 +39,11 @@ void UnitInstanceGroup::update_gamestate() { total_strength = 0; total_max_strength = 0; - for (UnitInstance const* unit : units) { - total_organisation += unit->get_organisation(); - total_max_organisation += unit->get_max_organisation(); - total_strength += unit->get_strength(); - total_max_strength += unit->get_max_strength(); + for (UnitInstance const& unit : units) { + total_organisation += unit.get_organisation(); + total_max_organisation += unit.get_max_organisation(); + total_strength += unit.get_strength(); + total_max_strength += unit.get_max_strength(); } } @@ -53,8 +60,8 @@ bool UnitInstanceGroup::empty() const { } size_t UnitInstanceGroup::get_unit_category_count(UnitType::unit_category_t unit_category) const { - return std::count_if(units.begin(), units.end(), [unit_category](UnitInstance const* unit) { - return unit->unit_type.unit_category == unit_category; + return std::count_if(units.begin(), units.end(), [unit_category](UnitInstance const& unit) { + return unit.unit_type.unit_category == unit_category; }); } @@ -65,8 +72,8 @@ UnitType const* UnitInstanceGroup::get_display_unit_type() const { fixed_point_map_t weighted_unit_types; - for (UnitInstance const* unit : units) { - UnitType const& unit_type = unit->unit_type; + for (UnitInstance const& unit : units) { + UnitType const& unit_type = unit.unit_type; weighted_unit_types[&unit_type] += unit_type.weighted_value; } @@ -80,7 +87,7 @@ UnitType const* UnitInstanceGroup::get_display_unit_type() const { bool UnitInstanceGroup::add_unit(UnitInstance& unit) { if (unit.get_branch() == branch) { - units.push_back(&unit); + units.emplace_back(unit); return true; } else { spdlog::error_s( @@ -92,7 +99,7 @@ bool UnitInstanceGroup::add_unit(UnitInstance& unit) { } bool UnitInstanceGroup::remove_unit(UnitInstance const& unit) { - const memory::vector::const_iterator it = std::find(units.begin(), units.end(), &unit); + auto it = std::find(units.begin(), units.end(), unit); if (it != units.end()) { units.erase(it); @@ -110,37 +117,25 @@ void UnitInstanceGroup::set_name(std::string_view new_name) { name = new_name; } -bool UnitInstanceGroup::set_position(ProvinceInstance* new_position) { +bool UnitInstanceGroup::set_location(ProvinceInstance& new_location) { bool ret = true; - if (position != new_position) { - if (position != nullptr) { - ret &= position->remove_unit_instance_group(*this); - } - - position = new_position; - - if (position != nullptr) { - ret &= position->add_unit_instance_group(*this); - } + if (location != new_location) { + ret &= location.get().remove_unit_instance_group(*this); + location = new_location; + ret &= new_location.add_unit_instance_group(*this); } return ret; } -bool UnitInstanceGroup::set_country(CountryInstance* new_country) { +bool UnitInstanceGroup::set_country(CountryInstance& new_country) { bool ret = true; if (country != new_country) { - if (country != nullptr) { - ret &= country->remove_unit_instance_group(*this); - } - + ret &= country.get().remove_unit_instance_group(*this); country = new_country; - - if (country != nullptr) { - ret &= country->add_unit_instance_group(*this); - } + ret &= new_country.add_unit_instance_group(*this); } return ret; @@ -175,7 +170,7 @@ bool UnitInstanceGroup::set_leader(LeaderInstance* new_leader) { return false; } - if (OV_unlikely(&new_leader->country != country)) { + if (OV_unlikely(new_leader->country != country)) { spdlog::error_s( "Trying to assign {} \"{}\" of country \"{}\" to {} \"{}\" of country \"{}\"", get_branched_leader_name(new_leader->branch), @@ -183,7 +178,7 @@ bool UnitInstanceGroup::set_leader(LeaderInstance* new_leader) { new_leader->country, get_branched_unit_group_name(branch), name, - ovfmt::validate(country) + country ); return false; } @@ -230,7 +225,7 @@ bool UnitInstanceGroup::is_moving() const { } ProvinceInstance const* UnitInstanceGroup::get_movement_destination_province() const { - return !path.empty() ? path.back() : nullptr; + return !path.empty() ? &path.back().get() : nullptr; } Date UnitInstanceGroup::get_movement_arrival_date() const { @@ -245,8 +240,10 @@ bool UnitInstanceGroup::is_in_combat() const { UnitInstanceGroupBranched::UnitInstanceGroupBranched( unique_id_t new_unique_id, - std::string_view new_name -) : UnitInstanceGroup { new_unique_id, LAND, new_name } {} + std::string_view new_name, + CountryInstance& new_country, + ProvinceInstance& new_location +) : UnitInstanceGroup { new_unique_id, LAND, new_name, new_country, new_location } {} void UnitInstanceGroupBranched::update_gamestate() { UnitInstanceGroup::update_gamestate(); @@ -258,8 +255,10 @@ void UnitInstanceGroupBranched::tick() { UnitInstanceGroupBranched::UnitInstanceGroupBranched( unique_id_t new_unique_id, - std::string_view new_name -) : UnitInstanceGroup { new_unique_id, NAVAL, new_name } {} + std::string_view new_name, + CountryInstance& new_country, + ProvinceInstance& new_location +) : UnitInstanceGroup { new_unique_id, NAVAL, new_name, new_country, new_location } {} void UnitInstanceGroupBranched::update_gamestate() { UnitInstanceGroup::update_gamestate(); @@ -272,8 +271,8 @@ void UnitInstanceGroupBranched::tick() { fixed_point_t UnitInstanceGroupBranched::get_total_consumed_supply() const { fixed_point_t total_consumed_supply = 0; - for (ShipInstance const* ship : get_ship_instances()) { - total_consumed_supply += ship->get_ship_type().supply_consumption_score; + for (ShipInstance const& ship : get_ship_instances()) { + total_consumed_supply += ship.get_ship_type().supply_consumption_score; } return total_consumed_supply; @@ -353,7 +352,7 @@ UnitInstanceBranched& UnitInstanceManager::generate_unit_instance( }() ); - unit_instance_map.emplace(unit_instance.unique_id, &unit_instance); + unit_instance_map.emplace(unit_instance.unique_id, unit_instance); return unit_instance; } @@ -369,39 +368,34 @@ bool UnitInstanceManager::generate_unit_instance_group( ); return false; } - - if (unit_deployment_group.get_location() == nullptr) { - spdlog::error_s( - "Trying to generate unit group \"{}\" with no location for country \"{}\"", - unit_deployment_group.get_name(), country - ); - return false; - } - - UnitInstanceGroupBranched& unit_instance_group = *get_unit_instance_groups().insert({ - unique_id_counter++, unit_deployment_group.get_name() - }); - unit_instance_group_map.emplace(unit_instance_group.unique_id, &unit_instance_group); + + ProvinceInstance& location = map_instance.get_province_instance_by_definition(unit_deployment_group.get_location()); + UnitInstanceGroupBranched& unit_instance_group = *get_unit_instance_groups().emplace( + unique_id_counter++, + unit_deployment_group.get_name(), + country, + location + ); + unit_instance_group_map.emplace(unit_instance_group.unique_id, unit_instance_group); bool ret = true; for (UnitDeployment const& unit_deployment : unit_deployment_group.get_units()) { - ret &= unit_instance_group.add_unit(generate_unit_instance(unit_deployment, map_instance, country.is_rebel_country())); + ret &= unit_instance_group.add_unit( + generate_unit_instance(unit_deployment, map_instance, country.is_rebel_country()) + ); } - ret &= unit_instance_group.set_position( - &map_instance.get_province_instance_by_definition(*unit_deployment_group.get_location()) - ); - ret &= unit_instance_group.set_country(&country); + ret &= unit_instance_group.set_country(country); if (unit_deployment_group.get_leader_index().has_value()) { - memory::vector& leaders = country.get_leaders(); - typename memory::vector::const_iterator it = leaders.begin(); + memory::vector>& leaders = country.get_leaders(); + auto it = leaders.begin(); advance(it, *unit_deployment_group.get_leader_index()); if (it < leaders.end()) { - ret &= unit_instance_group.set_leader(*it); + ret &= unit_instance_group.set_leader(&it->get()); } else { spdlog::error_s( "Invalid leader index {} for unit group \"{}\" for country \"{}\"", @@ -414,16 +408,19 @@ bool UnitInstanceManager::generate_unit_instance_group( return ret; } -void UnitInstanceManager::generate_leader(CountryInstance& country, LeaderBase const& leader) { - LeaderInstance& leader_instance = *leaders.insert({ - unique_id_counter++, leader, country - }); - leader_instance_map.emplace(leader_instance.unique_id, &leader_instance); +template +void UnitInstanceManager::generate_leader(CountryInstance& country, T&& leader_base) { + LeaderInstance& leader_instance = *leaders.emplace( + unique_id_counter++, + std::forward(leader_base), + country + ); + leader_instance_map.emplace(leader_instance.unique_id, leader_instance); country.add_leader(leader_instance); if (leader_instance.get_picture().empty() && country.get_primary_culture() != nullptr) { leader_instance.set_picture(culture_manager.get_leader_picture_name( - country.get_primary_culture()->group.get_leader(), leader.branch + country.get_primary_culture()->group.get_leader(), leader_instance.branch )); } } @@ -437,21 +434,16 @@ UnitInstanceManager::UnitInstanceManager( military_defines { new_military_defines } {} bool UnitInstanceManager::generate_deployment( - MapInstance& map_instance, CountryInstance& country, Deployment const* deployment + MapInstance& map_instance, CountryInstance& country, Deployment const& deployment ) { - if (deployment == nullptr) { - spdlog::error_s("Trying to generate null deployment for {}", country); - return false; - } - bool ret = true; - for (LeaderBase const& leader : deployment->get_leaders()) { + for (LeaderBase const& leader : deployment.get_leaders()) { generate_leader(country, leader); } - const auto generate_group = [this, &map_instance, &country, &ret, deployment]() -> void { - for (UnitDeploymentGroup const& unit_deployment_group : deployment->get_unit_deployment_groups()) { + const auto generate_group = [this, &map_instance, &country, &ret, &deployment]() -> void { + for (UnitDeploymentGroup const& unit_deployment_group : deployment.get_unit_deployment_groups()) { ret &= generate_unit_instance_group(map_instance, country, unit_deployment_group); } }; @@ -484,7 +476,7 @@ LeaderInstance* UnitInstanceManager::get_leader_instance_by_unique_id(unique_id_ const decltype(leader_instance_map)::const_iterator it = leader_instance_map.find(unique_id); if (it != leader_instance_map.end()) { - return it->second; + return &it->second.get(); } else { return nullptr; } @@ -494,7 +486,7 @@ UnitInstance* UnitInstanceManager::get_unit_instance_by_unique_id(unique_id_t un const decltype(unit_instance_map)::const_iterator it = unit_instance_map.find(unique_id); if (it != unit_instance_map.end()) { - return it->second; + return &it->second.get(); } else { return nullptr; } @@ -504,7 +496,7 @@ UnitInstanceGroup* UnitInstanceManager::get_unit_instance_group_by_unique_id(uni const decltype(unit_instance_group_map)::const_iterator it = unit_instance_group_map.find(unique_id); if (it != unit_instance_group_map.end()) { - return it->second; + return &it->second.get(); } else { return nullptr; } @@ -578,7 +570,7 @@ bool UnitInstanceManager::create_leader( const fixed_point_t starting_prestige = military_defines.get_leader_max_random_prestige() * static_cast(item_selection_counter++ % 11) / 10; - generate_leader(country, { + generate_leader(country, LeaderBase{ name, branch, creation_date, @@ -589,4 +581,4 @@ bool UnitInstanceManager::create_leader( }); return true; -} +} \ No newline at end of file diff --git a/src/openvic-simulation/military/UnitInstanceGroup.hpp b/src/openvic-simulation/military/UnitInstanceGroup.hpp index bf49bda88..cbd94049d 100644 --- a/src/openvic-simulation/military/UnitInstanceGroup.hpp +++ b/src/openvic-simulation/military/UnitInstanceGroup.hpp @@ -1,5 +1,6 @@ #pragma once +#include #include #include @@ -22,10 +23,10 @@ namespace OpenVic { struct UnitInstanceGroup { private: memory::string PROPERTY(name); - memory::vector SPAN_PROPERTY(units); + memory::vector> SPAN_PROPERTY(units); LeaderInstance* PROPERTY_PTR(leader, nullptr); - ProvinceInstance* PROPERTY_PTR(position, nullptr); - CountryInstance* PROPERTY_PTR(country, nullptr); + std::reference_wrapper PROPERTY(location); + std::reference_wrapper PROPERTY(country); fixed_point_t PROPERTY(total_organisation); fixed_point_t PROPERTY(total_max_organisation); @@ -34,8 +35,8 @@ namespace OpenVic { // Movement attributes // Ordered list of provinces making up the path the unit is trying to move along, - // the front province should always be adjacent to the unit's current position. - memory::vector SPAN_PROPERTY(path); + // the front province should always be adjacent to the unit's current location. + memory::vector> SPAN_PROPERTY(path); // Measured in distance travelled, increases each day by unit speed (after modifiers have been applied) until // it reaches the required distance/movement cost to move to the next province in the path. fixed_point_t PROPERTY(movement_progress); @@ -44,7 +45,9 @@ namespace OpenVic { UnitInstanceGroup( unique_id_t new_unique_id, unit_branch_t new_branch, - std::string_view new_name + std::string_view new_name, + CountryInstance& new_country, + ProvinceInstance& new_location ); void update_gamestate(); @@ -66,8 +69,8 @@ namespace OpenVic { bool remove_unit(UnitInstance const& unit); void set_name(std::string_view new_name); - bool set_position(ProvinceInstance* new_position); - bool set_country(CountryInstance* new_country); + bool set_location(ProvinceInstance& new_location); + bool set_country(CountryInstance& new_country); bool set_leader(LeaderInstance* new_leader); fixed_point_t get_organisation_proportion() const; @@ -82,12 +85,14 @@ namespace OpenVic { Date get_movement_arrival_date() const; bool is_in_combat() const; + + constexpr bool operator==(UnitInstanceGroup const& rhs) const { + return unique_id == rhs.unique_id; + } }; template<> struct UnitInstanceGroupBranched : UnitInstanceGroup { - friend struct UnitInstanceManager; - using dig_in_level_t = uint8_t; private: @@ -96,49 +101,49 @@ namespace OpenVic { bool PROPERTY_RW_CUSTOM_NAME(exiled, is_exiled, set_is_exiled, false); + public: UnitInstanceGroupBranched( unique_id_t new_unique_id, - std::string_view new_name + std::string_view new_name, + CountryInstance& new_country, + ProvinceInstance& new_location ); - - public: UnitInstanceGroupBranched(UnitInstanceGroupBranched&&) = default; void update_gamestate(); void tick(); // TODO - do these work fine when units is empty? - std::span get_regiment_instances() { - return { reinterpret_cast(get_units().data()), get_units().size() }; + std::span> get_regiment_instances() { + return { reinterpret_cast const*>(get_units().data()), get_units().size() }; } - std::span get_regiment_instances() const { - return { reinterpret_cast(get_units().data()), get_units().size() }; + std::span> get_regiment_instances() const { + return { reinterpret_cast const*>(get_units().data()), get_units().size() }; } }; template<> struct UnitInstanceGroupBranched : UnitInstanceGroup { - friend struct UnitInstanceManager; - private: - memory::vector SPAN_PROPERTY(carried_armies); + memory::vector> SPAN_PROPERTY(carried_armies); + public: UnitInstanceGroupBranched( unique_id_t new_unique_id, - std::string_view new_name + std::string_view new_name, + CountryInstance& new_country, + ProvinceInstance& new_location ); - - public: UnitInstanceGroupBranched(UnitInstanceGroupBranched&&) = default; void update_gamestate(); void tick(); - std::span get_ship_instances() { - return { reinterpret_cast(get_units().data()), get_units().size() }; + std::span> get_ship_instances() { + return { reinterpret_cast const*>(get_units().data()), get_units().size() }; } - std::span get_ship_instances() const { - return { reinterpret_cast(get_units().data()), get_units().size() }; + std::span> get_ship_instances() const { + return { reinterpret_cast const*>(get_units().data()), get_units().size() }; } fixed_point_t get_total_consumed_supply() const; @@ -171,17 +176,17 @@ namespace OpenVic { // TODO - maps from unique_ids to leader/unit/unit group pointers (one big map or multiple maps?) memory::colony PROPERTY(leaders); - ordered_map PROPERTY(leader_instance_map); + ordered_map> PROPERTY(leader_instance_map); memory::colony PROPERTY(regiments); memory::colony PROPERTY(ships); - ordered_map PROPERTY(unit_instance_map); + ordered_map> PROPERTY(unit_instance_map); OV_UNIT_BRANCHED_GETTER(get_unit_instances, regiments, ships); memory::colony PROPERTY(armies); memory::colony PROPERTY(navies); - ordered_map PROPERTY(unit_instance_group_map); + ordered_map> PROPERTY(unit_instance_group_map); OV_UNIT_BRANCHED_GETTER(get_unit_instance_groups, armies, navies); @@ -196,7 +201,8 @@ namespace OpenVic { bool generate_unit_instance_group( MapInstance& map_instance, CountryInstance& country, UnitDeploymentGroup const& unit_deployment_group ); - void generate_leader(CountryInstance& country, LeaderBase const& leader); + template + void generate_leader(CountryInstance& country, T&& leader_base); public: UnitInstanceManager( @@ -205,7 +211,7 @@ namespace OpenVic { MilitaryDefines const& new_military_defines ); - bool generate_deployment(MapInstance& map_instance, CountryInstance& country, Deployment const* deployment); + bool generate_deployment(MapInstance& map_instance, CountryInstance& country, Deployment const& deployment); void update_gamestate(); void tick(); diff --git a/src/openvic-simulation/pathfinding/AStarPathing.cpp b/src/openvic-simulation/pathfinding/AStarPathing.cpp index a19550d00..a4d314b20 100644 --- a/src/openvic-simulation/pathfinding/AStarPathing.cpp +++ b/src/openvic-simulation/pathfinding/AStarPathing.cpp @@ -131,7 +131,7 @@ bool ArmyAStarPathing::_is_point_enabled(search_const_iterator it) const { return true; } - return army_instance->get_country()->can_army_units_enter(*province_owner); + return army_instance->get_country().can_army_units_enter(*province_owner); } NavyAStarPathing::NavyAStarPathing( @@ -166,5 +166,5 @@ bool NavyAStarPathing::_is_point_enabled(search_const_iterator it) const { return true; } - return navy_instance->get_country()->can_navy_units_enter(*province_controller); + return navy_instance->get_country().can_navy_units_enter(*province_controller); }