From 3d728f054e3c214f840b7e63539aea0c4c5246b5 Mon Sep 17 00:00:00 2001 From: Spartan322 Date: Thu, 19 Oct 2023 19:56:06 -0400 Subject: Add Defines Loading Caches start_date and end_date in DefineManager Add static `get_property` and HASID_PROPERTY macro to HasIdentifier --- src/openvic-simulation/GameManager.hpp | 3 + src/openvic-simulation/dataloader/Dataloader.cpp | 7 +- src/openvic-simulation/misc/Define.cpp | 121 +++++++++++++++++++++ src/openvic-simulation/misc/Define.hpp | 63 +++++++++++ .../types/IdentifierRegistry.hpp | 120 ++++++++++++-------- 5 files changed, 269 insertions(+), 45 deletions(-) create mode 100644 src/openvic-simulation/misc/Define.cpp create mode 100644 src/openvic-simulation/misc/Define.hpp diff --git a/src/openvic-simulation/GameManager.hpp b/src/openvic-simulation/GameManager.hpp index b2d42d3..0b2a40c 100644 --- a/src/openvic-simulation/GameManager.hpp +++ b/src/openvic-simulation/GameManager.hpp @@ -7,6 +7,7 @@ #include "openvic-simulation/history/HistoryManager.hpp" #include "openvic-simulation/map/Map.hpp" #include "openvic-simulation/military/MilitaryManager.hpp" +#include "openvic-simulation/misc/Define.hpp" #include "openvic-simulation/politics/PoliticsManager.hpp" namespace OpenVic { @@ -15,6 +16,7 @@ namespace OpenVic { private: Map map; + DefineManager define_manager; EconomyManager economy_manager; MilitaryManager military_manager; ModifierManager modifier_manager; @@ -37,6 +39,7 @@ namespace OpenVic { GameManager(state_updated_func_t state_updated_callback); REF_GETTERS(map) + REF_GETTERS(define_manager) REF_GETTERS(economy_manager) REF_GETTERS(military_manager) REF_GETTERS(modifier_manager) diff --git a/src/openvic-simulation/dataloader/Dataloader.cpp b/src/openvic-simulation/dataloader/Dataloader.cpp index cfc944d..7132d24 100644 --- a/src/openvic-simulation/dataloader/Dataloader.cpp +++ b/src/openvic-simulation/dataloader/Dataloader.cpp @@ -445,7 +445,7 @@ static bool _lua_parse(v2script::Parser& parser) { return parser.lua_defines_parse(); } -static ovdl::v2script::Parser parse_lua_defines(fs::path const& path) { +ovdl::v2script::Parser Dataloader::parse_lua_defines(fs::path const& path) { return _run_ovdl_parser(path); } @@ -613,6 +613,7 @@ bool Dataloader::load_defines(GameManager& game_manager) const { static const fs::path pop_type_directory = "poptypes"; static const fs::path units_directory = "units"; + static const fs::path defines_file = "common/defines.lua"; static const fs::path buildings_file = "common/buildings.txt"; static const fs::path bookmark_file = "common/bookmarks.txt"; static const fs::path culture_file = "common/cultures.txt"; @@ -633,6 +634,10 @@ bool Dataloader::load_defines(GameManager& game_manager) const { Logger::error("Failed to set up modifier effects!"); ret = false; } + if (!game_manager.get_define_manager().load_defines_file(parse_lua_defines(lookup_file(defines_file)).get_file_node())) { + Logger::error("Failed to load defines!"); + ret = false; + } if (!game_manager.get_economy_manager().get_good_manager().load_goods_file( parse_defines(lookup_file(goods_file)).get_file_node())) { Logger::error("Failed to load goods!"); diff --git a/src/openvic-simulation/misc/Define.cpp b/src/openvic-simulation/misc/Define.cpp new file mode 100644 index 0000000..509b0a5 --- /dev/null +++ b/src/openvic-simulation/misc/Define.cpp @@ -0,0 +1,121 @@ + +#include "Define.hpp" + +#include +#include +#include + +#include + +#include "openvic-simulation/dataloader/NodeTools.hpp" +#include "openvic-simulation/types/Date.hpp" +#include "openvic-simulation/types/IdentifierRegistry.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" + +using namespace OpenVic; +using namespace OpenVic::NodeTools; + +Define::Define( + std::string_view new_identifier, + std::string&& new_value, + Type new_type +) : HasIdentifier { new_identifier }, + value { std::move(new_value) }, + type { new_type } { +} + +fixed_point_t Define::get_value_as_fp() const { + return fixed_point_t::parse(value); +} + +int64_t Define::get_value_as_int() const { + return std::strtoll(value.data(), nullptr, 10); +} + +uint64_t Define::get_value_as_uint() const { + return std::strtoull(value.data(), nullptr, 10); +} + +DefineManager::DefineManager() : defines { "defines" } { +} + +bool DefineManager::add_define(std::string_view name, std::string&& value, Define::Type type) { + return defines.add_item({ name, std::move(value), type }, duplicate_warning_callback); +} + +const Date& DefineManager::get_start_date() const { + return *start_date; +} + +const Date& DefineManager::get_end_date() const { + return *end_date; +} + +bool DefineManager::add_date_define(std::string_view name, Date date) { + if (name != "start_date" && name != "end_date") return false; + + bool ret = defines.add_item({ name, date.to_string(), Define::Type::None }); + + if (name == "start_date") + start_date.reset(new Date(date)); + else if (name == "end_date") + end_date.reset(new Date(date)); + + return ret; +} + +bool DefineManager::load_defines_file(ast::NodeCPtr root) { + bool ret = expect_dictionary_keys( + "defines", ONE_EXACTLY, expect_dictionary([this](std::string_view key, ast::NodeCPtr value) -> bool { + if (key == "country" || key == "economy" || key == "military" || key == "diplomacy" || key == "pops" || key == "ai" || key == "graphics") { + return expect_dictionary([this, &key](std::string_view inner_key, ast::NodeCPtr value) -> bool { + std::string str_val; + + bool ret = expect_identifier_or_string(assign_variable_callback_string(str_val))(value); + + Define::Type type; + switch (key[0]) { + using enum Define::Type; + case 'c': // country + type = Country; + break; + case 'e': // economy + type = Economy; + break; + case 'm': // military + type = Military; + break; + case 'd': // diplomacy + type = Diplomacy; + break; + case 'p': // pops + type = Pops; + break; + case 'a': // ai + type = Ai; + break; + case 'g': // graphics + type = Graphics; + break; + default: + Logger::error("Unknown define type ", key, " found in defines!"); + return false; + } + + ret &= add_define(inner_key, std::move(str_val), type); + return ret; + })(value); + } else if (key == "start_date" || key == "end_date") { + using namespace std::placeholders; + + return expect_identifier_or_string(expect_date_str([this, &key](Date date) -> bool { + return add_date_define(key, date); + }))(value); + } else { + return false; + } + }) + )(root); + lock_defines(); + return ret; +} \ No newline at end of file diff --git a/src/openvic-simulation/misc/Define.hpp b/src/openvic-simulation/misc/Define.hpp new file mode 100644 index 0000000..9b768b7 --- /dev/null +++ b/src/openvic-simulation/misc/Define.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include +#include + +#include "openvic-simulation/types/IdentifierRegistry.hpp" +#include "openvic-simulation/types/fixed_point/FixedPoint.hpp" + +namespace OpenVic { + struct DefineManager; + + struct Define : HasIdentifier { + friend struct DefineManager; + + enum class Type : unsigned char { + None, + Country, + Economy, + Military, + Diplomacy, + Pops, + Ai, + Graphics + }; + + private: + std::string HASID_PROPERTY(value); + Type HASID_PROPERTY(type); + + Define( + std::string_view new_identifier, + std::string&& new_value, + Type new_type + ); + + public: + Define(Define&&) = default; + + fixed_point_t get_value_as_fp() const; + int64_t get_value_as_int() const; + uint64_t get_value_as_uint() const; + }; + + struct DefineManager { + private: + IdentifierRegistry defines; + + std::unique_ptr start_date = nullptr; + std::unique_ptr end_date = nullptr; + + public: + DefineManager(); + + bool add_define(std::string_view name, std::string&& value, Define::Type type); + bool add_date_define(std::string_view name, Date date); + IDENTIFIER_REGISTRY_ACCESSORS(define); + + const Date& get_start_date() const; + const Date& get_end_date() const; + + bool load_defines_file(ast::NodeCPtr root); + }; +} \ No newline at end of file diff --git a/src/openvic-simulation/types/IdentifierRegistry.hpp b/src/openvic-simulation/types/IdentifierRegistry.hpp index 70f55ff..f53d78b 100644 --- a/src/openvic-simulation/types/IdentifierRegistry.hpp +++ b/src/openvic-simulation/types/IdentifierRegistry.hpp @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include "openvic-simulation/dataloader/NodeTools.hpp" @@ -29,6 +31,25 @@ namespace OpenVic { HasIdentifier& operator=(HasIdentifier&&) = delete; std::string_view get_identifier() const; + + template + inline constexpr static decltype(auto) get_property(const T& property) { + if constexpr (std::same_as) { + return std::string_view(property); + } else if constexpr (sizeof(T) <= sizeof(void*)) { + return T(property); + } else { + return property; + } + } + +#define HASID_PROPERTY(NAME) \ + const NAME; \ +\ +public: \ + auto get_##NAME() const->decltype(get_property(NAME)) { return get_property(NAME); } \ +\ +private: }; std::ostream& operator<<(std::ostream& stream, HasIdentifier const& obj); @@ -90,13 +111,11 @@ namespace OpenVic { /* Callbacks for trying to add duplicate keys via UniqueKeyRegistry::add_item */ static bool duplicate_fail_callback(std::string_view registry_name, std::string_view duplicate_identifier) { - Logger::error("Failure adding item to the ", registry_name, " registry - an item with the identifier \"", - duplicate_identifier, "\" already exists!"); + Logger::error("Failure adding item to the ", registry_name, " registry - an item with the identifier \"", duplicate_identifier, "\" already exists!"); return false; } static bool duplicate_warning_callback(std::string_view registry_name, std::string_view duplicate_identifier) { - Logger::warning("Warning adding item to the ", registry_name, " registry - an item with the identifier \"", - duplicate_identifier, "\" already exists!"); + Logger::warning("Warning adding item to the ", registry_name, " registry - an item with the identifier \"", duplicate_identifier, "\" already exists!"); return true; } static bool duplicate_ignore_callback(std::string_view registry_name, std::string_view duplicate_identifier) { @@ -123,7 +142,7 @@ namespace OpenVic { using storage_type = _Storage; UniqueKeyRegistry(std::string_view new_name, bool new_log_lock = true, _GetIdentifier new_GetIdentifier = {}, _GetPointer new_GetPointer = {}) - : name { new_name }, log_lock { new_log_lock }, GetIdentifier { new_GetIdentifier }, GetPointer { new_GetPointer } {} + : name { new_name }, log_lock { new_log_lock }, GetIdentifier { new_GetIdentifier }, GetPointer { new_GetPointer } {} std::string_view get_name() const { return name; @@ -185,36 +204,36 @@ namespace OpenVic { } #define GETTERS \ - value_type _const* get_item_by_identifier(std::string_view identifier) _const { \ - const typename decltype(identifier_index_map)::const_iterator it = identifier_index_map.find(identifier); \ - if (it != identifier_index_map.end()) return GetPointer(items[it->second]); \ - return nullptr; \ - } \ - value_type _const* get_item_by_index(size_t index) _const { \ - return index < items.size() ? &items[index] : nullptr; \ - } \ - NodeTools::callback_t expect_item_str(NodeTools::callback_t callback) _const { \ - return [this, callback](std::string_view identifier) -> bool { \ - value_type _const* item = get_item_by_identifier(identifier); \ - if (item != nullptr) return callback(*item); \ - Logger::error("Invalid ", name, ": ", identifier); \ - return false; \ - }; \ - } \ - NodeTools::node_callback_t expect_item_identifier(NodeTools::callback_t callback) _const { \ - return NodeTools::expect_identifier(expect_item_str(callback)); \ - } \ - NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t callback) _const { \ - return NodeTools::expect_dictionary([this, callback](std::string_view key, ast::NodeCPtr value) -> bool { \ - return expect_item_str(std::bind(callback, std::placeholders::_1, value))(key); \ - }); \ - } + value_type _const* get_item_by_identifier(std::string_view identifier) _const { \ + const typename decltype(identifier_index_map)::const_iterator it = identifier_index_map.find(identifier); \ + if (it != identifier_index_map.end()) return GetPointer(items[it->second]); \ + return nullptr; \ + } \ + value_type _const* get_item_by_index(size_t index) _const { \ + return index < items.size() ? &items[index] : nullptr; \ + } \ + NodeTools::callback_t expect_item_str(NodeTools::callback_t callback) _const { \ + return [this, callback](std::string_view identifier) -> bool { \ + value_type _const* item = get_item_by_identifier(identifier); \ + if (item != nullptr) return callback(*item); \ + Logger::error("Invalid ", name, ": ", identifier); \ + return false; \ + }; \ + } \ + NodeTools::node_callback_t expect_item_identifier(NodeTools::callback_t callback) _const { \ + return NodeTools::expect_identifier(expect_item_str(callback)); \ + } \ + NodeTools::node_callback_t expect_item_dictionary(NodeTools::callback_t callback) _const { \ + return NodeTools::expect_dictionary([this, callback](std::string_view key, ast::NodeCPtr value) -> bool { \ + return expect_item_str(std::bind(callback, std::placeholders::_1, value))(key); \ + }); \ + } #define _const -GETTERS + GETTERS #undef _const #define _const const -GETTERS + GETTERS #undef _const #undef GETTERS @@ -298,33 +317,46 @@ GETTERS void lock_##plural() { plural.lock(); } \ bool plural##_are_locked() const { return plural.is_locked(); } \ decltype(plural)::value_type const* get_##singular##_by_identifier(std::string_view identifier) const { \ - return plural.get_item_by_identifier(identifier); } \ + return plural.get_item_by_identifier(identifier); \ + } \ bool has_##singular##_identifier(std::string_view identifier) const { \ - return plural.has_identifier(identifier); } \ + return plural.has_identifier(identifier); \ + } \ size_t get_##singular##_count() const { \ - return plural.size(); } \ + return plural.size(); \ + } \ std::vector const& get_##plural() const { \ - return plural.get_items(); } \ + return plural.get_items(); \ + } \ std::vector get_##singular##_identifiers() const { \ - return plural.get_item_identifiers(); } \ + return plural.get_item_identifiers(); \ + } \ NodeTools::callback_t expect_##singular##_str(NodeTools::callback_t callback) const { \ - return plural.expect_item_str(callback); } \ + return plural.expect_item_str(callback); \ + } \ NodeTools::node_callback_t expect_##singular##_identifier(NodeTools::callback_t callback) const { \ - return plural.expect_item_identifier(callback); } \ + return plural.expect_item_identifier(callback); \ + } \ NodeTools::node_callback_t expect_##singular##_dictionary(NodeTools::callback_t callback) const { \ - return plural.expect_item_dictionary(callback); } \ + return plural.expect_item_dictionary(callback); \ + } \ NodeTools::node_callback_t expect_##singular##_decimal_map(NodeTools::callback_t&&> callback) const { \ - return plural.expect_item_decimal_map(callback); } + return plural.expect_item_decimal_map(callback); \ + } #define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(singular, plural) \ decltype(plural)::value_type* get_##singular##_by_identifier(std::string_view identifier) { \ - return plural.get_item_by_identifier(identifier); } \ + return plural.get_item_by_identifier(identifier); \ + } \ NodeTools::callback_t expect_##singular##_str(NodeTools::callback_t callback) { \ - return plural.expect_item_str(callback); } \ + return plural.expect_item_str(callback); \ + } \ NodeTools::node_callback_t expect_##singular##_identifier(NodeTools::callback_t callback) { \ - return plural.expect_item_identifier(callback); } \ + return plural.expect_item_identifier(callback); \ + } \ NodeTools::node_callback_t expect_##singular##_dictionary(NodeTools::callback_t callback) { \ - return plural.expect_item_dictionary(callback); } + return plural.expect_item_dictionary(callback); \ + } #define IDENTIFIER_REGISTRY_ACCESSORS(name) IDENTIFIER_REGISTRY_ACCESSORS_CUSTOM_PLURAL(name, name##s) #define IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS(name) IDENTIFIER_REGISTRY_NON_CONST_ACCESSORS_CUSTOM_PLURAL(name, name##s) -- cgit v1.2.3-56-ga3b1