Skip to content

Commit

Permalink
Add market placeholder
Browse files Browse the repository at this point in the history
  • Loading branch information
wvpm committed Nov 19, 2024
1 parent dda680c commit 6cca419
Show file tree
Hide file tree
Showing 15 changed files with 215 additions and 34 deletions.
7 changes: 6 additions & 1 deletion src/openvic-simulation/InstanceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ InstanceManager::InstanceManager(
DefinitionManager const& new_definition_manager, gamestate_updated_func_t gamestate_updated_callback,
SimulationClock::state_changed_function_t clock_state_changed_callback
) : definition_manager { new_definition_manager },
market_instance { good_instance_manager },
map_instance { new_definition_manager.get_map_definition() },
simulation_clock {
std::bind(&InstanceManager::tick, this), std::bind(&InstanceManager::update_gamestate, this),
Expand All @@ -21,7 +22,8 @@ InstanceManager::InstanceManager(
today {},
gamestate_updated { gamestate_updated_callback ? std::move(gamestate_updated_callback) : []() {} },
gamestate_needs_update { false },
currently_updating_gamestate { false } {}
currently_updating_gamestate { false }
{}

void InstanceManager::set_gamestate_needs_update() {
if (!currently_updating_gamestate) {
Expand Down Expand Up @@ -62,6 +64,7 @@ void InstanceManager::tick() {

// Tick...
map_instance.map_tick(today);
market_instance.execute_orders();

set_gamestate_needs_update();
}
Expand All @@ -75,6 +78,7 @@ bool InstanceManager::setup() {
bool ret = good_instance_manager.setup(definition_manager.get_economy_manager().get_good_definition_manager());
ret &= map_instance.setup(
definition_manager.get_economy_manager().get_building_type_manager(),
market_instance,
definition_manager.get_modifier_manager().get_modifier_effect_cache(),
definition_manager.get_pop_manager().get_pop_types(),
definition_manager.get_politics_manager().get_ideology_manager().get_ideologies()
Expand Down Expand Up @@ -145,6 +149,7 @@ bool InstanceManager::load_bookmark(Bookmark const* new_bookmark) {
today,
definition_manager.get_define_manager()
);
market_instance.execute_orders();
}

return ret;
Expand Down
2 changes: 2 additions & 0 deletions src/openvic-simulation/InstanceManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "openvic-simulation/country/CountryInstance.hpp"
#include "openvic-simulation/diplomacy/CountryRelation.hpp"
#include "openvic-simulation/economy/GoodInstance.hpp"
#include "openvic-simulation/economy/trading/MarketInstance.hpp"
#include "openvic-simulation/map/MapInstance.hpp"
#include "openvic-simulation/map/Mapmode.hpp"
#include "openvic-simulation/military/UnitInstanceGroup.hpp"
Expand All @@ -24,6 +25,7 @@ namespace OpenVic {
CountryInstanceManager PROPERTY_REF(country_instance_manager);
CountryRelationManager PROPERTY_REF(country_relation_manager);
GoodInstanceManager PROPERTY_REF(good_instance_manager);
MarketInstance PROPERTY_REF(market_instance);
UnitInstanceManager PROPERTY_REF(unit_instance_manager);
/* Near the end so it is freed after other managers that may depend on it,
* e.g. if we want to remove military units from the province they're in when they're destructed. */
Expand Down
40 changes: 38 additions & 2 deletions src/openvic-simulation/economy/GoodInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,36 @@
using namespace OpenVic;

GoodInstance::GoodInstance(GoodDefinition const& new_good_definition)
: HasIdentifierAndColour { new_good_definition }, good_definition { new_good_definition },
price { new_good_definition.get_base_price() }, is_available { new_good_definition.get_is_available_from_start() } {}
: HasIdentifierAndColour { new_good_definition },
sell_lock { std::make_unique<std::mutex>() },
good_definition { new_good_definition },
price { new_good_definition.get_base_price() },
is_available { new_good_definition.get_is_available_from_start() },
total_supply_yesterday { fixed_point_t::_0() },
market_sell_orders {}
{}

void GoodInstance::add_market_sell_order(GoodMarketSellOrder&& market_sell_order) {
const std::lock_guard<std::mutex> lock {*sell_lock};
market_sell_orders.push_back(std::move(market_sell_order));
}

void GoodInstance::execute_orders() {
const fixed_point_t price = get_price();

fixed_point_t supply_running_total = fixed_point_t::_0();
for(GoodMarketSellOrder const& market_sell_order : market_sell_orders) {
const fixed_point_t market_sell_quantity = market_sell_order.get_quantity();
supply_running_total += market_sell_quantity;
market_sell_order.get_after_trade()({
market_sell_quantity,
market_sell_quantity * price
});
}

total_supply_yesterday = supply_running_total;
market_sell_orders.clear();
}

bool GoodInstanceManager::setup(GoodDefinitionManager const& good_definition_manager) {
if (good_instances_are_locked()) {
Expand All @@ -24,3 +52,11 @@ bool GoodInstanceManager::setup(GoodDefinitionManager const& good_definition_man

return ret;
}

GoodInstance& GoodInstanceManager::get_good_instance_from_definition(GoodDefinition const& good) {
return good_instances.get_items()[good.get_index()];
}

GoodInstance const& GoodInstanceManager::get_good_instance_from_definition(GoodDefinition const& good) const {
return good_instances.get_items()[good.get_index()];
}
22 changes: 20 additions & 2 deletions src/openvic-simulation/economy/GoodInstance.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
#pragma once

#include <deque>
#include <memory>
#include <mutex>

#include "openvic-simulation/economy/GoodDefinition.hpp"
#include "openvic-simulation/economy/trading/MarketSellOrder.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/types/HasIdentifier.hpp"
#include "openvic-simulation/types/IdentifierRegistry.hpp"
#include "openvic-simulation/utility/Getters.hpp"
Expand All @@ -12,22 +18,34 @@ namespace OpenVic {
friend struct GoodInstanceManager;

private:
std::unique_ptr<std::mutex> sell_lock;
GoodDefinition const& PROPERTY(good_definition);
fixed_point_t PROPERTY(price);
bool PROPERTY(is_available);
// TODO - supply, demand, actual bought

fixed_point_t PROPERTY(total_supply_yesterday);
std::deque<GoodMarketSellOrder> market_sell_orders;

GoodInstance(GoodDefinition const& new_good_definition);

public:
GoodInstance(GoodInstance&&) = default;

//thread safe
void add_market_sell_order(GoodMarketSellOrder&& market_sell_order);

//not thread safe
void execute_orders();
};

struct GoodInstanceManager {
private:
IdentifierRegistry<GoodInstance> IDENTIFIER_REGISTRY(good_instance);

public:
IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(good_instance);
bool setup(GoodDefinitionManager const& good_definition_manager);

GoodInstance& get_good_instance_from_definition(GoodDefinition const& good);
GoodInstance const& get_good_instance_from_definition(GoodDefinition const& good) const;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "openvic-simulation/economy/production/Employee.hpp"
#include "openvic-simulation/economy/production/ProductionType.hpp"
#include "openvic-simulation/economy/trading/SellResult.hpp"
#include "openvic-simulation/map/ProvinceInstance.hpp"
#include "openvic-simulation/map/State.hpp"
#include "openvic-simulation/modifier/ModifierEffectCache.hpp"
Expand All @@ -14,6 +15,7 @@
using namespace OpenVic;

ResourceGatheringOperation::ResourceGatheringOperation(
MarketInstance& new_market_instance,
ModifierEffectCache const& new_modifier_effect_cache,
ProductionType const* new_production_type_nullable,
fixed_point_t new_size_multiplier,
Expand All @@ -22,7 +24,8 @@ ResourceGatheringOperation::ResourceGatheringOperation(
fixed_point_t new_unsold_quantity_yesterday,
std::vector<Employee>&& new_employees,
decltype(employee_count_per_type_cache)::keys_t const& pop_type_keys
) : modifier_effect_cache { new_modifier_effect_cache },
) : market_instance { new_market_instance },
modifier_effect_cache { new_modifier_effect_cache },
location_ptr { nullptr },
production_type_nullable { new_production_type_nullable },
revenue_yesterday { new_revenue_yesterday },
Expand All @@ -39,9 +42,11 @@ ResourceGatheringOperation::ResourceGatheringOperation(
{ }

ResourceGatheringOperation::ResourceGatheringOperation(
MarketInstance& new_market_instance,
ModifierEffectCache const& new_modifier_effect_cache,
decltype(employee_count_per_type_cache)::keys_t const& pop_type_keys
) : ResourceGatheringOperation {
new_market_instance,
new_modifier_effect_cache,
nullptr, fixed_point_t::_0(),
fixed_point_t::_0(), fixed_point_t::_0(),
Expand Down Expand Up @@ -134,27 +139,33 @@ void ResourceGatheringOperation::rgo_tick() {
hire(total_worker_count_in_province);

pop_size_t total_owner_count_in_state_cache = 0;
std::vector<Pop*> const* owner_pops_cache = nullptr;
std::vector<Pop*> const* owner_pops_cache_nullable = nullptr;

if (production_type.get_owner().has_value()) {
PopType const& owner_pop_type = *production_type.get_owner()->get_pop_type();
total_owner_count_in_state_cache = location.get_state()->get_pop_type_distribution()[owner_pop_type];
owner_pops_cache = &location.get_state()->get_pops_cache_by_type()[owner_pop_type];
owner_pops_cache_nullable = &location.get_state()->get_pops_cache_by_type()[owner_pop_type];
}

output_quantity_yesterday = produce(
owner_pops_cache,
total_owner_count_in_state_cache
);

revenue_yesterday = output_quantity_yesterday * production_type.get_output_good().get_base_price(); //TODO sell on market

pay_employees(
revenue_yesterday,
total_worker_count_in_province,
owner_pops_cache,
total_owner_count_in_state_cache
);
output_quantity_yesterday = produce(total_owner_count_in_state_cache);
market_instance.place_market_sell_order({
production_type.get_output_good(),
output_quantity_yesterday,
[
this,
total_worker_count_in_province,
owner_pops_cache_nullable,
total_owner_count_in_state_cache
](const SellResult sell_result) -> void {
revenue_yesterday = sell_result.get_money_gained();
pay_employees(
revenue_yesterday,
total_worker_count_in_province,
owner_pops_cache_nullable,
total_owner_count_in_state_cache
);
}
});
}

void ResourceGatheringOperation::hire(const pop_size_t available_worker_count) {
Expand Down Expand Up @@ -199,10 +210,7 @@ void ResourceGatheringOperation::hire(const pop_size_t available_worker_count) {
}
}

fixed_point_t ResourceGatheringOperation::produce(
std::vector<Pop*> const* const owner_pops_cache,
const pop_size_t total_owner_count_in_state_cache
) {
fixed_point_t ResourceGatheringOperation::produce(const pop_size_t total_owner_count_in_state_cache) {
const fixed_point_t size_modifier = calculate_size_modifier();
if (size_modifier == fixed_point_t::_0()){
return fixed_point_t::_0();
Expand Down Expand Up @@ -304,7 +312,7 @@ fixed_point_t ResourceGatheringOperation::produce(
void ResourceGatheringOperation::pay_employees(
const fixed_point_t revenue,
const pop_size_t total_worker_count_in_province,
std::vector<Pop*> const* const owner_pops_cache,
std::vector<Pop*> const* const owner_pops_cache_nullable,
const pop_size_t total_owner_count_in_state_cache
) {
ProvinceInstance& location = *location_ptr;
Expand All @@ -325,7 +333,7 @@ void ResourceGatheringOperation::pay_employees(
owner_share = upper_limit;
}

for(Pop* owner_pop_ptr : *owner_pops_cache) {
for(Pop* owner_pop_ptr : *owner_pops_cache_nullable) {
Pop& owner_pop = *owner_pop_ptr;
const fixed_point_t income_for_this_pop = revenue_left * owner_share * owner_pop.get_size() / total_owner_count_in_state_cache;
owner_pop.add_rgo_owner_income(income_for_this_pop);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "openvic-simulation/economy/production/Employee.hpp"
#include "openvic-simulation/economy/production/ProductionType.hpp"
#include "openvic-simulation/economy/trading/MarketInstance.hpp"
#include "openvic-simulation/pop/Pop.hpp"
#include "openvic-simulation/types/fixed_point/FixedPoint.hpp"
#include "openvic-simulation/utility/Getters.hpp"
Expand All @@ -12,6 +13,7 @@ namespace OpenVic {

struct ResourceGatheringOperation {
private:
MarketInstance& market_instance;
ModifierEffectCache const& modifier_effect_cache;
ProvinceInstance* location_ptr;
ProductionType const* PROPERTY_RW(production_type_nullable);
Expand All @@ -29,19 +31,17 @@ namespace OpenVic {

fixed_point_t calculate_size_modifier() const;
void hire(const pop_size_t available_worker_count);
fixed_point_t produce(
std::vector<Pop*> const* const owner_pops_cache,
const pop_size_t total_owner_count_in_state_cache
);
fixed_point_t produce(const pop_size_t total_owner_count_in_state_cache);
void pay_employees(
const fixed_point_t revenue,
const pop_size_t total_worker_count_in_province,
std::vector<Pop*> const* const owner_pops_cache,
std::vector<Pop*> const* const owner_pops_cache_nullable,
const pop_size_t total_owner_count_in_state_cache
);

public:
ResourceGatheringOperation(
MarketInstance& new_market_instance,
ModifierEffectCache const& new_modifier_effect_cache,
ProductionType const* new_production_type_nullable,
fixed_point_t new_size_multiplier,
Expand All @@ -53,6 +53,7 @@ namespace OpenVic {
);

ResourceGatheringOperation(
MarketInstance& new_market_instance,
ModifierEffectCache const& new_modifier_effect_cache,
decltype(employee_count_per_type_cache)::keys_t const& pop_type_keys
);
Expand Down
19 changes: 19 additions & 0 deletions src/openvic-simulation/economy/trading/MarketInstance.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "MarketInstance.hpp"

using namespace OpenVic;

MarketInstance::MarketInstance(GoodInstanceManager& new_good_instance_manager)
: good_instance_manager { new_good_instance_manager} {}

void MarketInstance::place_market_sell_order(MarketSellOrder&& market_sell_order) {
GoodDefinition const& good = market_sell_order.get_good();
GoodInstance& good_instance = good_instance_manager.get_good_instance_from_definition(good);
good_instance.add_market_sell_order(std::move(market_sell_order));
}

void MarketInstance::execute_orders() {
std::vector<GoodInstance>& good_instances = good_instance_manager.get_good_instances();
for (GoodInstance& good_instance : good_instances) {
good_instance.execute_orders();
}
}
15 changes: 15 additions & 0 deletions src/openvic-simulation/economy/trading/MarketInstance.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#pragma once

#include "openvic-simulation/economy/GoodInstance.hpp"
#include "openvic-simulation/economy/trading/MarketSellOrder.hpp"

namespace OpenVic {
struct MarketInstance {
private:
GoodInstanceManager& PROPERTY(good_instance_manager);
public:
MarketInstance(GoodInstanceManager& new_good_instance_manager);
void place_market_sell_order(MarketSellOrder&& market_sell_order);
void execute_orders();
};
}
19 changes: 19 additions & 0 deletions src/openvic-simulation/economy/trading/MarketSellOrder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "MarketSellOrder.hpp"

using namespace OpenVic;

GoodMarketSellOrder::GoodMarketSellOrder(
const fixed_point_t new_quantity,
std::function<void(const SellResult)>&& new_after_trade
):
quantity { new_quantity },
after_trade { std::move(new_after_trade) }
{}

MarketSellOrder::MarketSellOrder(
GoodDefinition const& new_good,
const fixed_point_t new_quantity,
std::function<void(const SellResult)>&& new_after_trade
): GoodMarketSellOrder(new_quantity, std::move(new_after_trade)),
good { new_good }
{}
Loading

0 comments on commit 6cca419

Please sign in to comment.