diff options
Diffstat (limited to 'src/openvic-simulation/economy')
10 files changed, 191 insertions, 14 deletions
diff --git a/src/openvic-simulation/economy/GoodInstance.cpp b/src/openvic-simulation/economy/GoodInstance.cpp index ac081c9..8844a6f 100644 --- a/src/openvic-simulation/economy/GoodInstance.cpp +++ b/src/openvic-simulation/economy/GoodInstance.cpp @@ -3,8 +3,34 @@ 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 }, + 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(const GoodMarketSellOrder market_sell_order) { + market_sell_orders.push_back(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()) { diff --git a/src/openvic-simulation/economy/GoodInstance.hpp b/src/openvic-simulation/economy/GoodInstance.hpp index 74ec939..dbb533d 100644 --- a/src/openvic-simulation/economy/GoodInstance.hpp +++ b/src/openvic-simulation/economy/GoodInstance.hpp @@ -1,6 +1,10 @@ #pragma once +#include <deque> + #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" @@ -15,12 +19,19 @@ namespace OpenVic { 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(const GoodMarketSellOrder market_sell_order); + + //not thread safe + void execute_orders(); }; struct GoodInstanceManager { @@ -28,6 +39,7 @@ namespace OpenVic { IdentifierRegistry<GoodInstance> IDENTIFIER_REGISTRY(good_instance); public: + IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(good_instance); bool setup(GoodDefinitionManager const& good_definition_manager); }; } diff --git a/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp b/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp index 8db74c1..410acf9 100644 --- a/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp +++ b/src/openvic-simulation/economy/production/ResourceGatheringOperation.cpp @@ -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" @@ -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, @@ -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 }, @@ -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(), @@ -146,15 +151,24 @@ void ResourceGatheringOperation::rgo_tick() { 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 - ); + market_instance.place_market_sell_order({ + production_type.get_output_good(), + output_quantity_yesterday, + [ + this, + total_worker_count_in_province, + owner_pops_cache = std::move(owner_pops_cache), + total_owner_count_in_state_cache + ](const SellResult sell_result) mutable -> void { + revenue_yesterday = sell_result.get_money_gained(); + pay_employees( + revenue_yesterday, + total_worker_count_in_province, + owner_pops_cache, + total_owner_count_in_state_cache + ); + } + }); } void ResourceGatheringOperation::hire(const Pop::pop_size_t available_worker_count) { diff --git a/src/openvic-simulation/economy/production/ResourceGatheringOperation.hpp b/src/openvic-simulation/economy/production/ResourceGatheringOperation.hpp index 878041e..449d41a 100644 --- a/src/openvic-simulation/economy/production/ResourceGatheringOperation.hpp +++ b/src/openvic-simulation/economy/production/ResourceGatheringOperation.hpp @@ -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/modifier/ModifierEffectCache.hpp" #include "openvic-simulation/pop/Pop.hpp" #include "openvic-simulation/types/fixed_point/FixedPoint.hpp" @@ -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); @@ -42,6 +44,7 @@ namespace OpenVic { public: ResourceGatheringOperation( + MarketInstance& new_market_instance, ModifierEffectCache const& new_modifier_effect_cache, ProductionType const* new_production_type_nullable, fixed_point_t new_size_multiplier, @@ -53,6 +56,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 ); diff --git a/src/openvic-simulation/economy/trading/MarketInstance.cpp b/src/openvic-simulation/economy/trading/MarketInstance.cpp new file mode 100644 index 0000000..06a470b --- /dev/null +++ b/src/openvic-simulation/economy/trading/MarketInstance.cpp @@ -0,0 +1,28 @@ +#include "MarketInstance.hpp" + +#include <execution> + +using namespace OpenVic; + +bool MarketInstance::setup(GoodInstanceManager& new_good_instance_manager) { + good_instance_manager = &new_good_instance_manager; + return true; +} + +void MarketInstance::place_market_sell_order(const MarketSellOrder market_sell_order) { + GoodDefinition const* const good = market_sell_order.get_good(); + GoodInstance* const good_instance = good_instance_manager->get_good_instance_by_identifier(good->get_identifier()); + good_instance->add_market_sell_order(market_sell_order); +} + +void MarketInstance::execute_orders() { + std::vector<GoodInstance>& good_instances = good_instance_manager->get_good_instances(); + std::for_each( + std::execution::par, + good_instances.begin(), + good_instances.end(), + [](GoodInstance& good_instance) -> void { + good_instance.execute_orders(); + } + ); +} diff --git a/src/openvic-simulation/economy/trading/MarketInstance.hpp b/src/openvic-simulation/economy/trading/MarketInstance.hpp new file mode 100644 index 0000000..2d8a651 --- /dev/null +++ b/src/openvic-simulation/economy/trading/MarketInstance.hpp @@ -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: + bool setup(GoodInstanceManager& new_good_instance_manager); + void place_market_sell_order(const MarketSellOrder market_sell_order); + void execute_orders(); + }; +}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/trading/MarketSellOrder.cpp b/src/openvic-simulation/economy/trading/MarketSellOrder.cpp new file mode 100644 index 0000000..8522c8c --- /dev/null +++ b/src/openvic-simulation/economy/trading/MarketSellOrder.cpp @@ -0,0 +1,19 @@ +#include "MarketSellOrder.hpp" + +using namespace OpenVic; + +GoodMarketSellOrder::GoodMarketSellOrder( + const fixed_point_t new_quantity, + const std::function<void(const SellResult)> new_after_trade +): + quantity { new_quantity }, + after_trade { new_after_trade } + {} + +MarketSellOrder::MarketSellOrder( + GoodDefinition const& new_good, + const fixed_point_t new_quantity, + const std::function<void(const SellResult)> new_after_trade +): GoodMarketSellOrder(new_quantity, new_after_trade), + good { &new_good } + {}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/trading/MarketSellOrder.hpp b/src/openvic-simulation/economy/trading/MarketSellOrder.hpp new file mode 100644 index 0000000..21c931d --- /dev/null +++ b/src/openvic-simulation/economy/trading/MarketSellOrder.hpp @@ -0,0 +1,32 @@ +#pragma once + +#include "openvic-simulation/economy/GoodDefinition.hpp" +#include "openvic-simulation/economy/trading/SellResult.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" +#include "openvic-simulation/utility/Getters.hpp" + +namespace OpenVic { + struct GoodMarketSellOrder { + private: + const fixed_point_t PROPERTY(quantity); + const std::function<void(const SellResult)> PROPERTY(after_trade); + + public: + GoodMarketSellOrder( + const fixed_point_t new_quantity, + const std::function<void(const SellResult)> new_after_trade + ); + }; + + struct MarketSellOrder : GoodMarketSellOrder { + private: + GoodDefinition const* const PROPERTY(good); + + public: + MarketSellOrder( + GoodDefinition const& new_good, + const fixed_point_t new_quantity, + const std::function<void(const SellResult)> new_after_trade + ); + }; +}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/trading/SellResult.cpp b/src/openvic-simulation/economy/trading/SellResult.cpp new file mode 100644 index 0000000..91de626 --- /dev/null +++ b/src/openvic-simulation/economy/trading/SellResult.cpp @@ -0,0 +1,11 @@ +#include "SellResult.hpp" + +using namespace OpenVic; + +SellResult::SellResult( + const fixed_point_t new_quantity_sold, + const fixed_point_t new_money_gained +) : + quantity_sold { new_quantity_sold }, + money_gained { new_money_gained } + {}
\ No newline at end of file diff --git a/src/openvic-simulation/economy/trading/SellResult.hpp b/src/openvic-simulation/economy/trading/SellResult.hpp new file mode 100644 index 0000000..f3a40ad --- /dev/null +++ b/src/openvic-simulation/economy/trading/SellResult.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" + +namespace OpenVic { + struct SellResult { + private: + fixed_point_t PROPERTY(quantity_sold); + fixed_point_t PROPERTY(money_gained); + public: + SellResult( + const fixed_point_t new_quantity_sold, + const fixed_point_t new_money_gained + ); + }; +}
\ No newline at end of file |