Skip to content
Open
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
72 changes: 35 additions & 37 deletions src/headless/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,44 +261,42 @@ static bool run_headless(fs::path const& root, memory::vector<memory::string>& m
print_memory_usage("Game Session Post-Start");

// TODO - REMOVE TEST CODE
InstanceManager& instance_manager = *game_manager.get_instance_manager();
SPDLOG_INFO("===== Ranking system test... =====");
if (game_manager.get_instance_manager()) {
const auto print_ranking_list = [ //
](std::string_view title, OpenVic::forwardable_span<const std::reference_wrapper<CountryInstance>> countries) -> void {
memory::string countries_str;
for (CountryInstance& country : countries) {
countries_str += fmt::format(
"\n\t{} - Total #{} ({:.1}), Prestige #{} ({:.1}), Industry #{} ({:.1}), Military #{} ({:.1})", //
country, //
country.get_total_rank(), country.total_score.get_untracked(), //
country.get_prestige_rank(), country.get_prestige_untracked(),
country.get_industrial_rank(), country.get_industrial_power_untracked(),
country.get_military_rank(), country.military_power.get_untracked()
);
}
SPDLOG_INFO("{}:{}", title, countries_str);
};

CountryInstanceManager const& country_instance_manager = game_manager.get_instance_manager()->get_country_instance_manager();

OpenVic::forwardable_span<const std::reference_wrapper<CountryInstance>> great_powers = country_instance_manager.get_great_powers();
print_ranking_list("Great Powers", great_powers);
print_ranking_list("Secondary Powers", country_instance_manager.get_secondary_powers());
print_ranking_list("All countries", country_instance_manager.get_total_ranking());

SPDLOG_INFO("===== RGO test... =====");
for (size_t i = 0; i < std::min<size_t>(3, great_powers.size()); ++i) {
CountryInstance const& great_power = great_powers[i];
ProvinceInstance const* const capital_province = great_power.get_capital();
if (capital_province == nullptr) {
spdlog::warn_s("{} has no capital ProvinceInstance set.", great_power);
} else {
print_rgo(*capital_province);
}
const auto print_ranking_list = [](
std::string_view title,
OpenVic::forwardable_span<const std::reference_wrapper<CountryInstance>> countries
) -> void {
memory::string countries_str;
for (CountryInstance& country : countries) {
countries_str += fmt::format(
"\n\t{} - Total #{} ({:.1}), Prestige #{} ({:.1}), Industry #{} ({:.1}), Military #{} ({:.1})", //
country, //
country.get_total_rank(), country.total_score.get_untracked(), //
country.get_prestige_rank(), country.get_prestige_untracked(),
country.get_industrial_rank(), country.get_industrial_power_untracked(),
country.get_military_rank(), country.military_power.get_untracked()
);
}
SPDLOG_INFO("{}:{}", title, countries_str);
};

CountryInstanceManager const& country_instance_manager = game_manager.get_instance_manager()->get_country_instance_manager();

OpenVic::forwardable_span<const std::reference_wrapper<CountryInstance>> great_powers = country_instance_manager.get_great_powers();
print_ranking_list("Great Powers", great_powers);
print_ranking_list("Secondary Powers", country_instance_manager.get_secondary_powers());
print_ranking_list("All countries", country_instance_manager.get_total_ranking());

SPDLOG_INFO("===== RGO test... =====");
for (size_t i = 0; i < std::min<size_t>(3, great_powers.size()); ++i) {
CountryInstance const& great_power = great_powers[i];
ProvinceInstance const* const capital_province = great_power.get_capital();
if (capital_province == nullptr) {
spdlog::warn_s("{} has no capital ProvinceInstance set.", great_power);
} else {
print_rgo(*capital_province);
}
} else {
spdlog::error_s("Instance manager not available!");
ret = false;
}

if (ret) {
Expand All @@ -308,7 +306,7 @@ static bool run_headless(fs::path const& root, memory::vector<memory::string>& m

using test_time_units_t = std::chrono::milliseconds;

MapInstance& map_instance = game_manager.get_instance_manager()->get_map_instance();
MapInstance& map_instance = instance_manager.get_map_instance();

SPDLOG_INFO("===== Land Pathfinding test... =====");
test_duration_t duration = std::chrono::duration_cast<test_time_units_t>( //
Expand Down
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
};
}
8 changes: 5 additions & 3 deletions src/openvic-simulation/core/Hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,9 +47,11 @@ namespace OpenVic {
s = h(v) << (sizeof(T) * CHAR_BIT);
(
[&] {
// If args is not last pointer of args
if (static_cast<void const*>(&(std::get<sizeof...(args) - 1>(arg_tuple))) !=
static_cast<void const*>(&args)) {
void const* const args_ptr = static_cast<void const*>(&args);
void const* const last_pointer_of_args = static_cast<void const*>(
&(std::get<sizeof...(args) - 1>(arg_tuple))
);
if (args_ptr != last_pointer_of_args) {
s <<= sizeof(Args) * CHAR_BIT;
}
s |= std::hash<Args> {}(args);
Expand Down
Loading
Loading