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
37 changes: 21 additions & 16 deletions src/openvic-simulation/InstanceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "openvic-simulation/misc/GameAction.hpp"
#include "openvic-simulation/types/TypedSpan.hpp"
#include "openvic-simulation/utility/Logger.hpp"
#include "openvic-simulation/utility/ThreadDeps.hpp"

using namespace OpenVic;

Expand Down Expand Up @@ -168,8 +169,8 @@ void InstanceManager::update_gamestate() {
update_modifier_sums();

// Update gamestate...
map_instance.update_gamestate(*this);
country_instance_manager.update_gamestate(today, map_instance);
map_instance.update_gamestate();
country_instance_manager.update_gamestate_after_map(today);
unit_instance_manager.update_gamestate();

gamestate_updated();
Expand Down Expand Up @@ -234,12 +235,19 @@ bool InstanceManager::setup() {
}

thread_pool.initialise_threadpool(
game_rules_manager,
good_instance_manager,
definition_manager.get_modifier_manager().get_modifier_effect_cache(),
definition_manager.get_define_manager().get_pops_defines(),
definition_manager.get_economy_manager().get_production_type_manager(),
strata_index_t(definition_manager.get_pop_manager().get_strata_count()),
ThreadDeps{
game_rules_manager,
good_instance_manager,
map_instance,
definition_manager.get_define_manager().get_military_defines(),
definition_manager.get_modifier_manager().get_modifier_effect_cache(),
definition_manager.get_define_manager().get_pops_defines(),
definition_manager.get_economy_manager().get_production_type_manager(),
definition_manager.get_modifier_manager().get_static_modifier_cache(),
country_index_t(definition_manager.get_country_definition_manager().get_country_definition_count()),
good_index_t(definition_manager.get_economy_manager().get_good_definition_manager().get_good_definition_count()),
strata_index_t(definition_manager.get_pop_manager().get_strata_count())
},
good_instance_manager.get_good_instances(),
country_instance_manager.get_country_instances(),
map_instance.get_province_instances()
Expand Down Expand Up @@ -305,8 +313,8 @@ bool InstanceManager::load_bookmark(Bookmark const& new_bookmark) {
OV_ERR_FAIL_COND_V_MSG(!all_has_state, false, "At least one land province has no state");

update_modifier_sums();
map_instance.initialise_for_new_game(*this);
country_instance_manager.update_gamestate(today, map_instance);
map_instance.initialise_for_new_game();
country_instance_manager.update_gamestate_after_map(today);
market_instance.execute_orders();

return ret;
Expand Down Expand Up @@ -359,12 +367,9 @@ void InstanceManager::update_modifier_sums() {
// full copy of all the modifiers affecting them in their modifier sum, but provinces only having their directly/locally
// applied modifiers in their modifier sum, hence requiring owner country modifier effect values to be looked up when
// determining the value of a global effect on the province.
country_instance_manager.update_modifier_sums(
today, definition_manager.get_modifier_manager().get_static_modifier_cache()
);
map_instance.update_modifier_sums(
today, definition_manager.get_modifier_manager().get_static_modifier_cache()
);
country_instance_manager.update_modifier_sums_before_map();
map_instance.update_modifier_sums(today);
country_instance_manager.update_modifier_sums_after_map();
}

bool InstanceManager::queue_game_action(game_action_t&& game_action) {
Expand Down
201 changes: 201 additions & 0 deletions src/openvic-simulation/core/BulkInsertWrapper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
#pragma once

#include <algorithm>
#include <atomic>
#include <cassert>
#include <iterator>
#include <memory>
#include <type_traits>
#include <utility>

#include "openvic-simulation/core/Assert.hpp"

namespace OpenVic {
// not thread safe
template <typename Container>
struct bulk_insert_wrapper {
public:
// Member types based on std::vector
using container_type = Container;
using value_type = typename container_type::value_type;
using allocator_type = typename container_type::allocator_type;
using size_type = typename container_type::size_type;
using difference_type = typename container_type::difference_type;
using reference = typename container_type::reference;
using const_reference = typename container_type::const_reference;
using pointer = typename container_type::pointer;
using const_pointer = typename container_type::const_pointer;
using iterator = typename container_type::iterator;
using const_iterator = typename container_type::const_iterator;
using reverse_iterator = typename container_type::reverse_iterator;
using const_reverse_iterator = typename container_type::const_reverse_iterator;

static_assert(std::is_default_constructible_v<value_type>);
static_assert(std::is_trivially_destructible_v<value_type>);

private:
Container container;
std::atomic<size_type> pending_extra_size {};

constexpr void flush_pending_room() {
if (pending_extra_size > size_type{}) {
size_type valid_size { size() };
container.resize(valid_size + pending_extra_size);
container.resize(valid_size);
pending_extra_size = size_type{};
}
}

public:
constexpr allocator_type get_allocator() const {
return container.get_allocator();
}

constexpr bulk_insert_wrapper() noexcept {};

// Forwarding constructor for custom allocators or initial capacities
template <typename... Args>
constexpr explicit bulk_insert_wrapper(Args&&... args)
: container(std::forward<Args>(args)...) {}

// thread safe
constexpr void make_room_for(const size_type count) noexcept {
pending_extra_size += count;
}

// Element access based on std::vector
constexpr reference operator[](const size_type pos) {
OV_HARDEN_ASSERT_ACCESS(pos, "operator[]");
return container[pos];
}
constexpr const_reference operator[](const size_type pos) const {
OV_HARDEN_ASSERT_ACCESS(pos, "operator[]");
return container[pos];
}

constexpr reference front() {
OV_HARDEN_ASSERT_NONEMPTY("front");
return container[0];
}
constexpr const_reference front() const {
OV_HARDEN_ASSERT_NONEMPTY("front");
return container[0];
}

constexpr reference back() {
OV_HARDEN_ASSERT_NONEMPTY("back");
return container[size()-1];
}
constexpr const_reference back() const {
OV_HARDEN_ASSERT_NONEMPTY("back");
return container[size()-1];
}

constexpr value_type* data() noexcept { return container.data(); }
constexpr value_type const* data() const noexcept { return container.data(); }

// Iterators based on std::vector
constexpr iterator begin() noexcept {
return container.begin();
}
constexpr const_iterator begin() const noexcept {
return container.begin();
}
constexpr const_iterator cbegin() const noexcept {
return container.cbegin();
}

constexpr iterator end() noexcept {
return container.end();
}
constexpr const_iterator end() const noexcept {
return container.end();
}
constexpr const_iterator cend() const noexcept {
return container.cend();
}

constexpr reverse_iterator rbegin() noexcept {
return container.rbegin();
}
constexpr const_reverse_iterator rbegin() const noexcept {
return container.rbegin();
}
constexpr const_reverse_iterator crbegin() const noexcept {
return container.crbegin();
}

constexpr reverse_iterator rend() noexcept {
return container.rend();
}
constexpr const_reverse_iterator rend() const noexcept {
return container.rend();
}
constexpr const_reverse_iterator crend() const noexcept {
return container.crend();
}

// Capacity based on std::vector
constexpr bool empty() const noexcept { return size() <= size_type{}; }
constexpr size_type size() const noexcept { return container.size(); }
constexpr size_type max_size() const noexcept { return container.max_size(); }
// reserve() is omitted as we manage that via make_room_for
constexpr size_type capacity() const noexcept { return container.capacity(); }
constexpr void shrink_to_fit() {
pending_extra_size = size_type{};
container.shrink_to_fit();
}

// Modifiers based on std::vector
constexpr void clear() noexcept {
pending_extra_size = size_type{};
container.clear();
}

// the following could be implemented:
// - insert
// - insert_range
// - emplace
// - erase
// - append_range (C++23)
// - pop_back
// - swap

constexpr void push_back(value_type const& value) {
flush_pending_room();
container.push_back(value);

}
constexpr void push_back(value_type&& value) {
flush_pending_room();
container.push_back(std::move(value));
}

template<typename... Args>
requires std::is_trivially_destructible_v<value_type>
constexpr reference emplace_back(Args&&... args) {
return container.emplace_back(std::forward<Args>(args)...);
}

template <typename OtherContainerT>
constexpr void append_range(OtherContainerT const& other) {
append_range(other.begin(), other.end());
}

template <typename InputIt>
constexpr void append_range(const InputIt first, const InputIt last) {
flush_pending_room();

const size_type new_valid_size = size() + std::distance(first, last);
if (new_valid_size > container.capacity()) {
assert(!"append_range called without make_room_for");
container.reserve(new_valid_size);
}

std::uninitialized_copy(first, last, end());
container.resize(new_valid_size);
}

// resize() is omitted as we manage that via make_room_for
};
}
56 changes: 32 additions & 24 deletions src/openvic-simulation/country/CountryInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1781,7 +1781,7 @@ static constexpr Modifier const& get_country_status_static_effect(
}
}

void CountryInstance::update_modifier_sum(Date today, StaticModifierCache const& static_modifier_cache) {
void CountryInstance::update_modifier_sum_before_map(Date today, StaticModifierCache const& static_modifier_cache) {
// Update sum of national modifiers
modifier_sum.clear();

Expand Down Expand Up @@ -1855,15 +1855,23 @@ void CountryInstance::update_modifier_sum(Date today, StaticModifierCache const&
// TODO - calculate stats for each unit type (locked and unlocked)
}

void CountryInstance::contribute_province_modifier_sum(ModifierSum const& province_modifier_sum) {
modifier_sum.add_modifier_sum(province_modifier_sum);
void CountryInstance::update_modifier_sum_after_map(Date today) {
for (ProvinceInstance const* const province_ptr : controlled_provinces) {
if (OV_likely(province_ptr != nullptr)) {
modifier_sum.add_modifier_sum(province_ptr->get_modifier_sum());
}
}
}

void CountryInstance::make_room_for_province_modifier_sum(ModifierSum const& province_modifier_sum) {
modifier_sum.make_room_for(province_modifier_sum);
}

fixed_point_t CountryInstance::get_modifier_effect_value(ModifierEffect const& effect) const {
return modifier_sum.get_modifier_effect_value(effect);
}

void CountryInstance::update_gamestate(const Date today, MapInstance& map_instance) {
void CountryInstance::update_gamestate_after_map(const Date today) {
if (is_civilised()) {
civilisation_progress = 0;
} else {
Expand Down Expand Up @@ -1927,14 +1935,14 @@ void CountryInstance::update_gamestate(const Date today, MapInstance& map_instan
province->set_connected_to_capital(false);
province->set_is_overseas(province_definition.get_continent() != capital_continent);

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();
if (neighbour != nullptr && neighbour != this) {
neighbouring_countries.insert(neighbour);
}
}
// 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();
// if (neighbour != nullptr && neighbour != this) {
// neighbouring_countries.insert(neighbour);
// }
// }
}

if (occupied_provinces_proportion != 0) {
Expand All @@ -1944,21 +1952,21 @@ void CountryInstance::update_gamestate(const Date today, MapInstance& map_instan

if (capital != nullptr) {
capital->set_connected_to_capital(true);
memory::vector<std::reference_wrapper<const ProvinceInstance>> province_checklist { *capital };
// memory::vector<std::reference_wrapper<const ProvinceInstance>> 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());
// for (ProvinceDefinition::adjacency_t const& adjacency : province.province_definition.get_adjacencies()) {
// 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.emplace_back(adjacent_province);
}
}
}
// 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.emplace_back(adjacent_province);
// }
// }
// }
}

// Order of updates might need to be changed/functions split up to account for dependencies
Expand Down
7 changes: 4 additions & 3 deletions src/openvic-simulation/country/CountryInstance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,16 +685,17 @@ namespace OpenVic {
bool update_rule_set();

public:
void update_modifier_sum(Date today, StaticModifierCache const& static_modifier_cache);
void contribute_province_modifier_sum(ModifierSum const& province_modifier_sum);
void update_modifier_sum_before_map(Date today, StaticModifierCache const& static_modifier_cache);
void update_modifier_sum_after_map(Date today);
void make_room_for_province_modifier_sum(ModifierSum const& province_modifier_sum);
fixed_point_t get_modifier_effect_value(ModifierEffect const& effect) const;
constexpr void for_each_contributing_modifier(
ModifierEffect const& effect, ContributingModifierCallback auto callback
) const {
return modifier_sum.for_each_contributing_modifier(effect, std::move(callback));
}

void update_gamestate(const Date today, MapInstance& map_instance);
void update_gamestate_after_map(const Date today);
void country_tick_before_map(
TypedSpan<good_index_t, char> reusable_goods_mask,
forwardable_span<
Expand Down
Loading
Loading