From 212d591c31f4200b06d38e98b23c5c2bccde1772 Mon Sep 17 00:00:00 2001 From: Hop311 Date: Mon, 22 May 2023 10:26:37 +0100 Subject: Formatting / style cleanup --- src/openvic/Date.cpp | 11 ++++---- src/openvic/Date.hpp | 6 ++++- src/openvic/GameAdvancementHook.cpp | 22 +++++++++------- src/openvic/GameAdvancementHook.hpp | 18 +++++++------ src/openvic/GameManager.cpp | 3 ++- src/openvic/GameManager.hpp | 4 ++- src/openvic/Logger.hpp | 50 +++++++++++++++++++------------------ src/openvic/Types.cpp | 4 +-- src/openvic/Types.hpp | 9 +++++-- src/openvic/economy/Good.cpp | 14 +++++++---- src/openvic/economy/Good.hpp | 5 +++- src/openvic/map/Building.cpp | 12 ++++++--- src/openvic/map/Building.hpp | 14 +++++++++-- src/openvic/map/Map.cpp | 15 +++++++---- src/openvic/map/Map.hpp | 9 ++++--- src/openvic/map/Province.cpp | 10 +++++--- src/openvic/map/Province.hpp | 1 + src/openvic/map/Region.cpp | 2 +- src/openvic/map/Region.hpp | 3 +++ 19 files changed, 133 insertions(+), 79 deletions(-) (limited to 'src') diff --git a/src/openvic/Date.cpp b/src/openvic/Date.cpp index d25e99f..db1633f 100644 --- a/src/openvic/Date.cpp +++ b/src/openvic/Date.cpp @@ -1,13 +1,13 @@ #include "Date.hpp" -#include #include +#include #include "Logger.hpp" using namespace OpenVic; -Timespan::Timespan(day_t value) : days{value} {} +Timespan::Timespan(day_t value) : days { value } {} bool Timespan::operator<(Timespan other) const { return days < other.days; }; bool Timespan::operator>(Timespan other) const { return days > other.days; }; @@ -67,14 +67,14 @@ Timespan Date::_dateToTimespan(year_t year, month_t month, day_t day) { return year * DAYS_IN_YEAR + DAYS_UP_TO_MONTH[month - 1] + day - 1; } -Date::Date(Timespan total_days) : timespan{ total_days } { +Date::Date(Timespan total_days) : timespan { total_days } { if (timespan < 0) { Logger::error("Invalid timespan for date: ", timespan, " (cannot be negative)"); timespan = 0; } } -Date::Date(year_t year, month_t month, day_t day) : timespan{ _dateToTimespan(year, month, day) } {} +Date::Date(year_t year, month_t month, day_t day) : timespan { _dateToTimespan(year, month, day) } {} Date::year_t Date::getYear() const { return static_cast(timespan) / DAYS_IN_YEAR; @@ -89,7 +89,6 @@ Date::day_t Date::getDay() const { return days_in_year - DAYS_UP_TO_MONTH[days_in_year / 32] + 1; } - bool Date::operator<(Date other) const { return timespan < other.timespan; }; bool Date::operator>(Date other) const { return timespan > other.timespan; }; bool Date::operator<=(Date other) const { return timespan <= other.timespan; }; @@ -129,7 +128,7 @@ Date::operator std::string() const { } std::ostream& OpenVic::operator<<(std::ostream& out, Date const& date) { - return out << (int) date.getYear() << '.' << (int) date.getMonth() << '.' << (int) date.getDay(); + return out << (int)date.getYear() << '.' << (int)date.getMonth() << '.' << (int)date.getDay(); } // Parsed from string of the form YYYY.MM.DD diff --git a/src/openvic/Date.hpp b/src/openvic/Date.hpp index 61de9ba..151b4e5 100644 --- a/src/openvic/Date.hpp +++ b/src/openvic/Date.hpp @@ -1,15 +1,17 @@ #pragma once #include -#include #include +#include namespace OpenVic { // A relative period between points in time, measured in days struct Timespan { using day_t = int64_t; + private: day_t days; + public: Timespan(day_t value = 0); @@ -46,11 +48,13 @@ namespace OpenVic { static constexpr Timespan::day_t DAYS_IN_YEAR = 365; static constexpr Timespan::day_t DAYS_IN_MONTH[MONTHS_IN_YEAR] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static constexpr Timespan::day_t DAYS_UP_TO_MONTH[MONTHS_IN_YEAR] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; + private: // Number of days since Jan 1st, Year 0 Timespan timespan; static Timespan _dateToTimespan(year_t year, month_t month, day_t day); + public: // The Timespan is considered to be the number of days since Jan 1st, Year 0 Date(Timespan total_days); diff --git a/src/openvic/GameAdvancementHook.cpp b/src/openvic/GameAdvancementHook.cpp index 0fcdd03..ac16158 100644 --- a/src/openvic/GameAdvancementHook.cpp +++ b/src/openvic/GameAdvancementHook.cpp @@ -3,15 +3,19 @@ using namespace OpenVic; const std::vector GameAdvancementHook::GAME_SPEEDS = { - std::chrono::milliseconds{ 4000 }, - std::chrono::milliseconds{ 3000 }, - std::chrono::milliseconds{ 2000 }, - std::chrono::milliseconds{ 1000 }, - std::chrono::milliseconds{ 100 }, - std::chrono::milliseconds{ 1 } }; + std::chrono::milliseconds { 4000 }, + std::chrono::milliseconds { 3000 }, + std::chrono::milliseconds { 2000 }, + std::chrono::milliseconds { 1000 }, + std::chrono::milliseconds { 100 }, + std::chrono::milliseconds { 1 } +}; -GameAdvancementHook::GameAdvancementHook(AdvancementFunction tickFunction, RefreshFunction updateFunction, bool startPaused, speed_t startingSpeed) - : triggerFunction{ tickFunction }, refreshFunction{ updateFunction }, isPaused{ startPaused } { +GameAdvancementHook::GameAdvancementHook(AdvancementFunction tickFunction, + RefreshFunction updateFunction, bool startPaused, speed_t startingSpeed) + : triggerFunction { tickFunction }, + refreshFunction { updateFunction }, + isPaused { startPaused } { lastPolledTime = std::chrono::high_resolution_clock::now(); setSimulationSpeed(startingSpeed); } @@ -57,7 +61,7 @@ GameAdvancementHook& GameAdvancementHook::operator--() { void GameAdvancementHook::conditionallyAdvanceGame() { if (!isPaused) { - std::chrono::time_point currentTime = std::chrono::high_resolution_clock::now(); + time_point_t currentTime = std::chrono::high_resolution_clock::now(); if (std::chrono::duration_cast(currentTime - lastPolledTime) >= GAME_SPEEDS[currentSpeed]) { lastPolledTime = currentTime; if (triggerFunction) triggerFunction(); diff --git a/src/openvic/GameAdvancementHook.hpp b/src/openvic/GameAdvancementHook.hpp index 5d904bc..59e43a4 100644 --- a/src/openvic/GameAdvancementHook.hpp +++ b/src/openvic/GameAdvancementHook.hpp @@ -5,25 +5,27 @@ #include namespace OpenVic { - //Conditionally advances game with provided behaviour - //Class governs game speed and pause state + // Conditionally advances game with provided behaviour + // Class governs game speed and pause state class GameAdvancementHook { - public: + public: using AdvancementFunction = std::function; using RefreshFunction = std::function; using speed_t = int8_t; - //Minimum number of miliseconds before the simulation advances + // Minimum number of miliseconds before the simulation advances static const std::vector GAME_SPEEDS; - private: - std::chrono::time_point lastPolledTime; - //A function pointer that advances the simulation, intended to be a capturing lambda or something similar. May need to be reworked later + private: + using time_point_t = std::chrono::time_point; + + time_point_t lastPolledTime; + // A function pointer that advances the simulation, intended to be a capturing lambda or something similar. May need to be reworked later AdvancementFunction triggerFunction; RefreshFunction refreshFunction; speed_t currentSpeed; - public: + public: bool isPaused; GameAdvancementHook(AdvancementFunction tickFunction, RefreshFunction updateFunction, bool startPaused = true, speed_t startingSpeed = 0); diff --git a/src/openvic/GameManager.cpp b/src/openvic/GameManager.cpp index 50d7358..6b32e09 100644 --- a/src/openvic/GameManager.cpp +++ b/src/openvic/GameManager.cpp @@ -5,7 +5,8 @@ using namespace OpenVic; GameManager::GameManager(state_updated_func_t state_updated_callback) - : clock{ [this]() { tick(); }, [this]() { update_state(); } }, state_updated{ state_updated_callback } {} + : clock { [this]() { tick(); }, [this]() { update_state(); } }, + state_updated { state_updated_callback } {} void GameManager::set_needs_update() { needs_update = true; diff --git a/src/openvic/GameManager.hpp b/src/openvic/GameManager.hpp index e1a9e9b..b8dfbf6 100644 --- a/src/openvic/GameManager.hpp +++ b/src/openvic/GameManager.hpp @@ -1,8 +1,8 @@ #pragma once #include "GameAdvancementHook.hpp" -#include "map/Map.hpp" #include "economy/Good.hpp" +#include "map/Map.hpp" namespace OpenVic { struct GameManager { @@ -12,6 +12,7 @@ namespace OpenVic { BuildingManager building_manager; GoodManager good_manager; GameAdvancementHook clock; + private: time_t session_start; /* SS-54, as well as allowing time-tracking */ Date today; @@ -21,6 +22,7 @@ namespace OpenVic { void set_needs_update(); void update_state(); void tick(); + public: GameManager(state_updated_func_t state_updated_callback); diff --git a/src/openvic/Logger.hpp b/src/openvic/Logger.hpp index 2c603e2..923087e 100644 --- a/src/openvic/Logger.hpp +++ b/src/openvic/Logger.hpp @@ -8,76 +8,78 @@ namespace OpenVic { - #ifndef __cpp_lib_source_location - #include - //Implementation of std::source_location for compilers that do not support it - //Note: uses non-standard extensions that are supported by Clang, GCC, and MSVC - //https://clang.llvm.org/docs/LanguageExtensions.html#source-location-builtins - //https://stackoverflow.com/a/67970107 +#ifndef __cpp_lib_source_location +#include + // Implementation of std::source_location for compilers that do not support it + // Note: uses non-standard extensions that are supported by Clang, GCC, and MSVC + // https://clang.llvm.org/docs/LanguageExtensions.html#source-location-builtins + // https://stackoverflow.com/a/67970107 class source_location { std::string _file; int _line; std::string _function; - public: - source_location(std::string f, int l, std::string n) : _file(f), _line(l), _function(n) {} + public: + source_location(std::string f, int l, std::string n) : _file(f), _line(l), _function(n) {} static source_location current(std::string f = __builtin_FILE(), int l = __builtin_LINE(), std::string n = __builtin_FUNCTION()) { return source_location(f, l, n); } inline char const* file_name() const { return _file.c_str(); } - inline int line() const {return _line; } + inline int line() const { return _line; } inline char const* function_name() const { return _function.c_str(); } }; - #endif +#endif class Logger { using log_func_t = std::function; - #ifdef __cpp_lib_source_location +#ifdef __cpp_lib_source_location using source_location = std::source_location; - #else +#else using source_location = OpenVic::source_location; - #endif +#endif static log_func_t info_func, error_func; static char const* get_filename(char const* filepath); - template + template struct log { - log(log_func_t log_func, Ts&&... ts, const source_location& location) { + log(log_func_t log_func, Ts&&... ts, source_location const& location) { if (log_func) { std::stringstream stream; - stream << std::endl << get_filename(location.file_name()) << "(" << location.line() << ") `" << location.function_name() << "`: "; + stream << "\n" << get_filename(location.file_name()) << "(" + << location.line() << ") `" << location.function_name() << "`: "; ((stream << std::forward(ts)), ...); stream << std::endl; log_func(stream.str()); } } }; + public: static void set_info_func(log_func_t log_func); static void set_error_func(log_func_t log_func); - template + template struct info { - info(Ts&&... ts, const source_location& location = source_location::current()) { - log{ info_func, std::forward(ts)..., location }; + info(Ts&&... ts, source_location const& location = source_location::current()) { + log { info_func, std::forward(ts)..., location }; } }; - template + template info(Ts&&...) -> info; - template + template struct error { - error(Ts&&... ts, const source_location& location = source_location::current()) { - log{ error_func, std::forward(ts)..., location }; + error(Ts&&... ts, source_location const& location = source_location::current()) { + log { error_func, std::forward(ts)..., location }; } }; - template + template error(Ts&&...) -> error; }; } diff --git a/src/openvic/Types.cpp b/src/openvic/Types.cpp index 829770b..ab5d12a 100644 --- a/src/openvic/Types.cpp +++ b/src/openvic/Types.cpp @@ -1,12 +1,12 @@ #include "Types.hpp" #include -#include #include +#include using namespace OpenVic; -HasIdentifier::HasIdentifier(std::string const& new_identifier) : identifier{ new_identifier } { +HasIdentifier::HasIdentifier(std::string const& new_identifier) : identifier { new_identifier } { assert(!identifier.empty()); } diff --git a/src/openvic/Types.hpp b/src/openvic/Types.hpp index c528ac0..e332bf2 100644 --- a/src/openvic/Types.hpp +++ b/src/openvic/Types.hpp @@ -1,9 +1,9 @@ #pragma once -#include -#include #include +#include #include +#include #include "Logger.hpp" @@ -44,8 +44,10 @@ namespace OpenVic { */ class HasIdentifier { const std::string identifier; + protected: HasIdentifier(std::string const& new_identifier); + public: HasIdentifier(HasIdentifier const&) = delete; HasIdentifier(HasIdentifier&&) = default; @@ -60,8 +62,10 @@ namespace OpenVic { */ class HasColour { const colour_t colour; + protected: HasColour(colour_t const new_colour, bool can_be_null = false); + public: HasColour(HasColour const&) = delete; HasColour(HasColour&&) = default; @@ -87,6 +91,7 @@ namespace OpenVic { std::vector items; bool locked = false; identifier_index_map_t identifier_index_map; + public: IdentifierRegistry(std::string const& new_name) : name(new_name) {} return_t add_item(T&& item) { diff --git a/src/openvic/economy/Good.cpp b/src/openvic/economy/Good.cpp index b4fa060..6d515d5 100644 --- a/src/openvic/economy/Good.cpp +++ b/src/openvic/economy/Good.cpp @@ -6,9 +6,14 @@ using namespace OpenVic; Good::Good(std::string const& new_identifier, std::string const& new_category, colour_t new_colour, price_t new_base_price, bool new_default_available, bool new_tradeable, bool new_currency, bool new_overseas_maintenance) - : HasIdentifier{ new_identifier }, HasColour{ new_colour, true }, category{ new_category }, base_price{ new_base_price }, - default_available{ new_default_available }, tradeable{ new_tradeable }, currency{ new_currency }, - overseas_maintenance{ new_overseas_maintenance } { + : HasIdentifier { new_identifier }, + HasColour { new_colour, true }, + category { new_category }, + base_price { new_base_price }, + default_available { new_default_available }, + tradeable { new_tradeable }, + currency { new_currency }, + overseas_maintenance { new_overseas_maintenance } { assert(base_price > NULL_PRICE); } @@ -37,7 +42,7 @@ void Good::reset_to_defaults() { price = base_price; } -GoodManager::GoodManager() : goods{ "goods" } {} +GoodManager::GoodManager() : goods { "goods" } {} return_t GoodManager::add_good(std::string const& identifier, std::string const& category, colour_t colour, price_t base_price, bool default_available, bool tradeable, bool currency, bool overseas_maintenance) { @@ -76,4 +81,3 @@ size_t GoodManager::get_good_count() const { std::vector const& GoodManager::get_goods() const { return goods.get_items(); } - diff --git a/src/openvic/economy/Good.hpp b/src/openvic/economy/Good.hpp index 75f5a73..577280d 100644 --- a/src/openvic/economy/Good.hpp +++ b/src/openvic/economy/Good.hpp @@ -9,7 +9,7 @@ namespace OpenVic { * ECON-15, ECON-16, ECON-17, ECON-18, ECON-19, ECON-20, ECON-21, ECON-22, ECON-23, ECON-24, ECON-25, ECON-26, * ECON-27, ECON-28, ECON-29, ECON-30, ECON-31, ECON-32, ECON-33, ECON-34, ECON-35, ECON-36, ECON-37, ECON-38, * ECON-39, ECON-40, ECON-41, ECON-42, ECON-43, ECON-44, ECON-45, ECON-46, ECON-47, ECON-48, ECON-49, ECON-50 - * + * * ECON-123, ECON-124, ECON-125, ECON-126, ECON-127, ECON-128, ECON-129, ECON-130, ECON-131, ECON-132, ECON-133, ECON-134, * ECON-135, ECON-136, ECON-137, ECON-138, ECON-139, ECON-140, ECON-141, ECON-142, ECON-234, ECON-235, ECON-236, ECON-237, * ECON-238, ECON-239, ECON-240, ECON-241, ECON-242, ECON-243, ECON-244, ECON-245, ECON-246, ECON-247, ECON-248, ECON-249, @@ -17,6 +17,7 @@ namespace OpenVic { */ struct Good : HasIdentifier, HasColour { friend struct GoodManager; + private: const std::string category; const price_t base_price; @@ -26,6 +27,7 @@ namespace OpenVic { Good(std::string const& new_identifier, std::string const& new_category, colour_t new_colour, price_t new_base_price, bool new_default_available, bool new_tradeable, bool new_currency, bool new_overseas_maintenance); + public: Good(Good&&) = default; @@ -40,6 +42,7 @@ namespace OpenVic { struct GoodManager { private: IdentifierRegistry goods; + public: GoodManager(); diff --git a/src/openvic/map/Building.cpp b/src/openvic/map/Building.cpp index ccd5ad7..1513e06 100644 --- a/src/openvic/map/Building.cpp +++ b/src/openvic/map/Building.cpp @@ -7,7 +7,9 @@ using namespace OpenVic; -Building::Building(BuildingType const& new_type) : HasIdentifier{ new_type.get_identifier() }, type{ new_type } {} +Building::Building(BuildingType const& new_type) + : HasIdentifier { new_type.get_identifier() }, + type { new_type } {} bool Building::_can_expand() const { return level < type.get_max_level(); @@ -74,8 +76,10 @@ void Building::tick(Date const& today) { } } -BuildingType::BuildingType(std::string const& new_identifier, Building::level_t new_max_level, Timespan new_build_time) : - HasIdentifier{ new_identifier }, max_level{ new_max_level }, build_time{ new_build_time } { +BuildingType::BuildingType(std::string const& new_identifier, Building::level_t new_max_level, Timespan new_build_time) + : HasIdentifier { new_identifier }, + max_level { new_max_level }, + build_time { new_build_time } { assert(max_level >= 0); assert(build_time >= 0); } @@ -88,7 +92,7 @@ Timespan BuildingType::get_build_time() const { return build_time; } -BuildingManager::BuildingManager() : building_types{ "building types" } {} +BuildingManager::BuildingManager() : building_types { "building types" } {} return_t BuildingManager::add_building_type(std::string const& identifier, Building::level_t max_level, Timespan build_time) { if (identifier.empty()) { diff --git a/src/openvic/map/Building.hpp b/src/openvic/map/Building.hpp index ca5c196..98c3991 100644 --- a/src/openvic/map/Building.hpp +++ b/src/openvic/map/Building.hpp @@ -2,8 +2,8 @@ #include -#include "../Types.hpp" #include "../Date.hpp" +#include "../Types.hpp" namespace OpenVic { struct Province; @@ -19,7 +19,13 @@ namespace OpenVic { using level_t = int8_t; - enum class ExpansionState { CannotExpand, CanExpand, Preparing, Expanding }; + enum class ExpansionState { + CannotExpand, + CanExpand, + Preparing, + Expanding + }; + private: BuildingType const& type; level_t level = 0; @@ -30,6 +36,7 @@ namespace OpenVic { Building(BuildingType const& new_type); bool _can_expand() const; + public: Building(Building&&) = default; @@ -49,11 +56,13 @@ namespace OpenVic { struct BuildingType : HasIdentifier { friend struct BuildingManager; + private: const Building::level_t max_level; const Timespan build_time; BuildingType(std::string const& new_identifier, Building::level_t new_max_level, Timespan new_build_time); + public: BuildingType(BuildingType&&) = default; @@ -64,6 +73,7 @@ namespace OpenVic { struct BuildingManager { private: IdentifierRegistry building_types; + public: BuildingManager(); diff --git a/src/openvic/map/Map.cpp b/src/openvic/map/Map.cpp index af1ea8a..8d5b9e7 100644 --- a/src/openvic/map/Map.cpp +++ b/src/openvic/map/Map.cpp @@ -9,7 +9,9 @@ using namespace OpenVic; Mapmode::Mapmode(index_t new_index, std::string const& new_identifier, colour_func_t new_colour_func) - : HasIdentifier{ new_identifier }, index{ new_index }, colour_func{ new_colour_func } { + : HasIdentifier { new_identifier }, + index { new_index }, + colour_func { new_colour_func } { assert(colour_func != nullptr); } @@ -21,7 +23,9 @@ colour_t Mapmode::get_colour(Map const& map, Province const& province) const { return colour_func ? colour_func(map, province) : NULL_COLOUR; } -Map::Map() : provinces{ "provinces" }, regions{ "regions" }, mapmodes{ "mapmodes" } {} +Map::Map() : provinces { "provinces" }, + regions { "regions" }, + mapmodes { "mapmodes" } {} return_t Map::add_province(std::string const& identifier, colour_t colour) { if (provinces.get_item_count() >= MAX_INDEX) { @@ -36,7 +40,7 @@ return_t Map::add_province(std::string const& identifier, colour_t colour) { Logger::error("Invalid province colour: ", Province::colour_to_hex_string(colour)); return FAILURE; } - Province new_province{ static_cast(provinces.get_item_count() + 1), identifier, colour }; + Province new_province { static_cast(provinces.get_item_count() + 1), identifier, colour }; const index_t index = get_index_from_colour(colour); if (index != NULL_INDEX) { Logger::error("Duplicate province colours: ", get_province_by_index(index)->to_string(), " and ", new_province.to_string()); @@ -79,7 +83,7 @@ return_t Map::add_region(std::string const& identifier, std::vector Logger::error("Invalid region identifier - empty!"); return FAILURE; } - Region new_region{ identifier }; + Region new_region { identifier }; return_t ret = SUCCESS; for (std::string const& province_identifier : province_identifiers) { Province* province = get_province_by_identifier(province_identifier); @@ -330,7 +334,8 @@ return_t Map::generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) return_t Map::setup(GoodManager const& good_manager, BuildingManager const& building_manager) { return_t ret = SUCCESS; for (Province& province : provinces.get_items()) { - if (!province.is_water()) // Set all land provinces to have an RGO based on their index to test them + // Set all land provinces to have an RGO based on their index to test them + if (!province.is_water()) province.rgo = good_manager.get_good_by_index(province.get_index() % good_manager.get_good_count()); if (building_manager.generate_province_buildings(province) != SUCCESS) ret = FAILURE; } diff --git a/src/openvic/map/Map.hpp b/src/openvic/map/Map.hpp index 39c37c0..a7c29bb 100644 --- a/src/openvic/map/Map.hpp +++ b/src/openvic/map/Map.hpp @@ -9,13 +9,15 @@ namespace OpenVic { struct Mapmode : HasIdentifier { friend struct Map; - using colour_func_t = std::function; + using colour_func_t = std::function; using index_t = size_t; + private: const index_t index; const colour_func_t colour_func; Mapmode(index_t new_index, std::string const& new_identifier, colour_func_t new_colour_func); + public: index_t get_index() const; colour_t get_colour(Map const& map, Province const& province) const; @@ -30,12 +32,12 @@ namespace OpenVic { using terrain_t = uint8_t; using terrain_variant_map_t = std::map; - #pragma pack(push, 1) +#pragma pack(push, 1) struct shape_pixel_t { index_t index; terrain_t terrain; }; - #pragma pack(pop) +#pragma pack(pop) private: using colour_index_map_t = std::map; @@ -51,6 +53,7 @@ namespace OpenVic { index_t selected_province = NULL_INDEX; index_t get_index_from_colour(colour_t colour) const; + public: Map(); diff --git a/src/openvic/map/Province.cpp b/src/openvic/map/Province.cpp index b169021..d2a5ecf 100644 --- a/src/openvic/map/Province.cpp +++ b/src/openvic/map/Province.cpp @@ -1,13 +1,16 @@ #include "Province.hpp" #include -#include #include +#include using namespace OpenVic; -Province::Province(index_t new_index, std::string const& new_identifier, colour_t new_colour) : - HasIdentifier{ new_identifier }, HasColour{ new_colour }, index{ new_index }, buildings{ "buildings" } { +Province::Province(index_t new_index, std::string const& new_identifier, colour_t new_colour) + : HasIdentifier { new_identifier }, + HasColour { new_colour }, + index { new_index }, + buildings { "buildings" } { assert(index != NULL_INDEX); } @@ -66,7 +69,6 @@ std::string Province::to_string() const { void Province::update_state(Date const& today) { for (Building& building : buildings.get_items()) building.update_state(today); - } void Province::tick(Date const& today) { diff --git a/src/openvic/map/Province.hpp b/src/openvic/map/Province.hpp index cc11046..f1f87a2 100644 --- a/src/openvic/map/Province.hpp +++ b/src/openvic/map/Province.hpp @@ -25,6 +25,7 @@ namespace OpenVic { Good const* rgo = nullptr; Province(index_t new_index, std::string const& new_identifier, colour_t new_colour); + public: Province(Province&&) = default; diff --git a/src/openvic/map/Region.cpp b/src/openvic/map/Region.cpp index d546ff9..b83f556 100644 --- a/src/openvic/map/Region.cpp +++ b/src/openvic/map/Region.cpp @@ -16,7 +16,7 @@ std::vector const& ProvinceSet::get_provinces() const { return provinces; } -Region::Region(std::string const& new_identifier) : HasIdentifier{ new_identifier } {} +Region::Region(std::string const& new_identifier) : HasIdentifier { new_identifier } {} colour_t Region::get_colour() const { if (provinces.empty()) return FULL_COLOUR << 16; diff --git a/src/openvic/map/Region.hpp b/src/openvic/map/Region.hpp index 953a3cc..331d883 100644 --- a/src/openvic/map/Region.hpp +++ b/src/openvic/map/Region.hpp @@ -7,6 +7,7 @@ namespace OpenVic { struct ProvinceSet { protected: std::vector provinces; + public: size_t get_province_count() const; bool contains_province(Province const* province) const; @@ -18,8 +19,10 @@ namespace OpenVic { */ struct Region : HasIdentifier, ProvinceSet { friend struct Map; + private: Region(std::string const& new_identifier); + public: Region(Region&&) = default; -- cgit v1.2.3-56-ga3b1 From 7874702f30d5855319faf197b10aed31f07f5e27 Mon Sep 17 00:00:00 2001 From: Hop311 Date: Mon, 22 May 2023 10:36:23 +0100 Subject: BMP palette parser + Logger macro --- src/openvic/Date.cpp | 8 +- src/openvic/GameManager.cpp | 2 +- src/openvic/Logger.cpp | 26 ------- src/openvic/Logger.hpp | 85 --------------------- src/openvic/Types.hpp | 2 +- src/openvic/map/Building.cpp | 2 +- src/openvic/map/Map.cpp | 22 ++++-- src/openvic/map/Map.hpp | 2 + src/openvic/utility/BMP.cpp | 162 +++++++++++++++++++++++++++++++++++++++++ src/openvic/utility/BMP.hpp | 48 ++++++++++++ src/openvic/utility/Logger.cpp | 18 +++++ src/openvic/utility/Logger.hpp | 80 ++++++++++++++++++++ 12 files changed, 333 insertions(+), 124 deletions(-) delete mode 100644 src/openvic/Logger.cpp delete mode 100644 src/openvic/Logger.hpp create mode 100644 src/openvic/utility/BMP.cpp create mode 100644 src/openvic/utility/BMP.hpp create mode 100644 src/openvic/utility/Logger.cpp create mode 100644 src/openvic/utility/Logger.hpp (limited to 'src') diff --git a/src/openvic/Date.cpp b/src/openvic/Date.cpp index db1633f..f7bf9a3 100644 --- a/src/openvic/Date.cpp +++ b/src/openvic/Date.cpp @@ -3,7 +3,7 @@ #include #include -#include "Logger.hpp" +#include "utility/Logger.hpp" using namespace OpenVic; @@ -139,17 +139,17 @@ Date Date::from_string(std::string const& date) { size_t first_pos = 0; while (first_pos < date.length() && std::isdigit(date[first_pos++])); - year = atoi(date.substr(0, first_pos).c_str()); + year = stoi(date.substr(0, first_pos)); if (first_pos < date.length()) { if (date[first_pos] == '.') { size_t second_pos = first_pos + 1; while (second_pos < date.length() && std::isdigit(date[second_pos++])); - month = atoi(date.substr(first_pos, second_pos - first_pos).c_str()); + month = stoi(date.substr(first_pos, second_pos - first_pos)); if (second_pos < date.length()) { if (date[second_pos] == '.') { size_t third_pos = second_pos + 1; while (third_pos < date.length() && std::isdigit(date[third_pos++])); - day = atoi(date.substr(second_pos, third_pos - second_pos).c_str()); + day = stoi(date.substr(second_pos, third_pos - second_pos)); if (third_pos < date.length()) Logger::error("Unexpected string \"", date.substr(third_pos), "\" at the end of date ", date); } else Logger::error("Unexpected character \"", date[second_pos], "\" in date ", date); diff --git a/src/openvic/GameManager.cpp b/src/openvic/GameManager.cpp index 6b32e09..b2a9c27 100644 --- a/src/openvic/GameManager.cpp +++ b/src/openvic/GameManager.cpp @@ -1,6 +1,6 @@ #include "GameManager.hpp" -#include "Logger.hpp" +#include "utility/Logger.hpp" using namespace OpenVic; diff --git a/src/openvic/Logger.cpp b/src/openvic/Logger.cpp deleted file mode 100644 index f93b8f1..0000000 --- a/src/openvic/Logger.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "Logger.hpp" - -#include - -using namespace OpenVic; - -Logger::log_func_t Logger::info_func = [](std::string&& str) { std::cout << str; }; -Logger::log_func_t Logger::error_func = [](std::string&& str) { std::cerr << str; }; - -char const* Logger::get_filename(char const* filepath) { - if (filepath == nullptr) return nullptr; - char const* last_slash = filepath; - while (*filepath != '\0') { - if (*filepath == '\\' || *filepath == '/') last_slash = filepath + 1; - filepath++; - } - return last_slash; -} - -void Logger::set_info_func(log_func_t log_func) { - info_func = log_func; -} - -void Logger::set_error_func(log_func_t log_func) { - error_func = log_func; -} diff --git a/src/openvic/Logger.hpp b/src/openvic/Logger.hpp deleted file mode 100644 index 923087e..0000000 --- a/src/openvic/Logger.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once - -#include -#include -#ifdef __cpp_lib_source_location -#include -#endif - -namespace OpenVic { - -#ifndef __cpp_lib_source_location -#include - // Implementation of std::source_location for compilers that do not support it - // Note: uses non-standard extensions that are supported by Clang, GCC, and MSVC - // https://clang.llvm.org/docs/LanguageExtensions.html#source-location-builtins - // https://stackoverflow.com/a/67970107 - class source_location { - std::string _file; - int _line; - std::string _function; - - public: - source_location(std::string f, int l, std::string n) : _file(f), _line(l), _function(n) {} - static source_location current(std::string f = __builtin_FILE(), int l = __builtin_LINE(), std::string n = __builtin_FUNCTION()) { - return source_location(f, l, n); - } - - inline char const* file_name() const { return _file.c_str(); } - inline int line() const { return _line; } - inline char const* function_name() const { return _function.c_str(); } - }; -#endif - - class Logger { - using log_func_t = std::function; - -#ifdef __cpp_lib_source_location - using source_location = std::source_location; -#else - using source_location = OpenVic::source_location; -#endif - - static log_func_t info_func, error_func; - - static char const* get_filename(char const* filepath); - - template - struct log { - log(log_func_t log_func, Ts&&... ts, source_location const& location) { - if (log_func) { - std::stringstream stream; - stream << "\n" << get_filename(location.file_name()) << "(" - << location.line() << ") `" << location.function_name() << "`: "; - ((stream << std::forward(ts)), ...); - stream << std::endl; - log_func(stream.str()); - } - } - }; - - public: - static void set_info_func(log_func_t log_func); - static void set_error_func(log_func_t log_func); - - template - struct info { - info(Ts&&... ts, source_location const& location = source_location::current()) { - log { info_func, std::forward(ts)..., location }; - } - }; - - template - info(Ts&&...) -> info; - - template - struct error { - error(Ts&&... ts, source_location const& location = source_location::current()) { - log { error_func, std::forward(ts)..., location }; - } - }; - - template - error(Ts&&...) -> error; - }; -} diff --git a/src/openvic/Types.hpp b/src/openvic/Types.hpp index e332bf2..fe22dc9 100644 --- a/src/openvic/Types.hpp +++ b/src/openvic/Types.hpp @@ -5,7 +5,7 @@ #include #include -#include "Logger.hpp" +#include "utility/Logger.hpp" namespace OpenVic { // Represents a 24-bit RGB integer OR a 32-bit ARGB integer diff --git a/src/openvic/map/Building.cpp b/src/openvic/map/Building.cpp index 1513e06..317ccdf 100644 --- a/src/openvic/map/Building.cpp +++ b/src/openvic/map/Building.cpp @@ -2,7 +2,7 @@ #include -#include "../Logger.hpp" +#include "../utility/Logger.hpp" #include "Province.hpp" using namespace OpenVic; diff --git a/src/openvic/map/Map.cpp b/src/openvic/map/Map.cpp index 8d5b9e7..2efee32 100644 --- a/src/openvic/map/Map.cpp +++ b/src/openvic/map/Map.cpp @@ -3,8 +3,8 @@ #include #include -#include "../Logger.hpp" #include "../economy/Good.hpp" +#include "../utility/Logger.hpp" using namespace OpenVic; @@ -15,6 +15,8 @@ Mapmode::Mapmode(index_t new_index, std::string const& new_identifier, colour_fu assert(colour_func != nullptr); } +const Mapmode Mapmode::ERROR_MAPMODE { 0, "mapmode_error", [](Map const& map, Province const& province) -> colour_t { return 0xFFFF0000; } }; + Mapmode::index_t Mapmode::get_index() const { return index; } @@ -180,7 +182,8 @@ Region const* Map::get_region_by_identifier(std::string const& identifier) const } static colour_t colour_at(uint8_t const* colour_data, int32_t idx) { - return (colour_data[idx * 3] << 16) | (colour_data[idx * 3 + 1] << 8) | colour_data[idx * 3 + 2]; + idx *= 3; + return (colour_data[idx] << 16) | (colour_data[idx + 1] << 8) | colour_data[idx + 2]; } return_t Map::generate_province_shape_image(size_t new_width, size_t new_height, uint8_t const* colour_data, @@ -313,10 +316,17 @@ return_t Map::generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) Logger::error("Mapmode colour target pointer is null!"); return FAILURE; } + return_t ret = SUCCESS; Mapmode const* mapmode = mapmodes.get_item_by_index(index); if (mapmode == nullptr) { - Logger::error("Invalid mapmode index: ", index); - return FAILURE; + // Not an error if mapmodes haven't yet been loaded, + // e.g. if we want to allocate the province colour + // texture before mapmodes are loaded. + if (!(mapmodes.get_item_count() == 0 && index == 0)) { + Logger::error("Invalid mapmode index: ", index); + ret = FAILURE; + } + mapmode = &Mapmode::ERROR_MAPMODE; } // Skip past Province::NULL_INDEX for (size_t i = 0; i < MAPMODE_COLOUR_SIZE; ++i) @@ -328,14 +338,14 @@ return_t Map::generate_mapmode_colours(Mapmode::index_t index, uint8_t* target) *target++ = colour & FULL_COLOUR; *target++ = (colour >> 24) & FULL_COLOUR; } - return SUCCESS; + return ret; } return_t Map::setup(GoodManager const& good_manager, BuildingManager const& building_manager) { return_t ret = SUCCESS; for (Province& province : provinces.get_items()) { // Set all land provinces to have an RGO based on their index to test them - if (!province.is_water()) + if (!province.is_water() && good_manager.get_good_count() > 0) province.rgo = good_manager.get_good_by_index(province.get_index() % good_manager.get_good_count()); if (building_manager.generate_province_buildings(province) != SUCCESS) ret = FAILURE; } diff --git a/src/openvic/map/Map.hpp b/src/openvic/map/Map.hpp index a7c29bb..3533a14 100644 --- a/src/openvic/map/Map.hpp +++ b/src/openvic/map/Map.hpp @@ -19,6 +19,8 @@ namespace OpenVic { Mapmode(index_t new_index, std::string const& new_identifier, colour_func_t new_colour_func); public: + static const Mapmode ERROR_MAPMODE; + index_t get_index() const; colour_t get_colour(Map const& map, Province const& province) const; }; diff --git a/src/openvic/utility/BMP.cpp b/src/openvic/utility/BMP.cpp new file mode 100644 index 0000000..eb3e2b1 --- /dev/null +++ b/src/openvic/utility/BMP.cpp @@ -0,0 +1,162 @@ +#include "BMP.hpp" + +#include + +#include "Logger.hpp" + +using namespace OpenVic; + +BMP::~BMP() { + close(); +} + +return_t BMP::open(char const* filepath) { + reset(); + errno = 0; + file = fopen(filepath, "rb"); + if (file == nullptr || errno != 0) { + Logger::error("Failed to open BMP file \"", filepath, "\" (errno = ", errno, ")"); + file = nullptr; + return FAILURE; + } + return SUCCESS; +} + +return_t BMP::read_header() { + if (header_validated) { + Logger::error("BMP header already validated!"); + return FAILURE; + } + if (file == nullptr) { + Logger::error("Cannot read BMP header before opening a file"); + return FAILURE; + } + if (fseek(file, 0, SEEK_SET) != 0) { + Logger::error("Failed to move to the beginning of the BMP file!"); + return FAILURE; + } + if (fread(&header, sizeof(header), 1, file) != 1) { + Logger::error("Failed to read BMP header!"); + return FAILURE; + } + return_t ret = SUCCESS; + + // Validate constants + static constexpr uint16_t BMP_SIGNATURE = 0x4d42; + if (header.signature != BMP_SIGNATURE) { + Logger::error("Invalid BMP signature: ", header.signature, " (must be ", BMP_SIGNATURE, ")"); + ret = FAILURE; + } + static constexpr uint32_t DIB_HEADER_SIZE = 40; + if (header.dib_header_size != DIB_HEADER_SIZE) { + Logger::error("Invalid BMP DIB header size: ", header.dib_header_size, " (must be ", DIB_HEADER_SIZE, ")"); + ret = FAILURE; + } + static constexpr uint16_t NUM_PLANES = 1; + if (header.num_planes != NUM_PLANES) { + Logger::error("Invalid BMP plane count: ", header.num_planes, " (must be ", NUM_PLANES, ")"); + ret = FAILURE; + } + static constexpr uint16_t COMPRESSION = 0; // Only support uncompressed BMPs + if (header.compression != COMPRESSION) { + Logger::error("Invalid BMP compression method: ", header.compression, " (must be ", COMPRESSION, ")"); + ret = FAILURE; + } + + // Validate sizes and dimensions + // TODO - image_size_bytes can be 0 for non-compressed BMPs + if (header.file_size != header.offset + header.image_size_bytes) { + Logger::error("Invalid BMP memory sizes: file size = ", header.file_size, " != ", header.offset + header.image_size_bytes, + " = ", header.offset, " + ", header.image_size_bytes, " = image data offset + image data size"); + ret = FAILURE; + } + // TODO - support negative widths (i.e. horizontal flip) + if (header.width_px <= 0) { + Logger::error("Invalid BMP width: ", header.width_px, " (must be positive)"); + ret = FAILURE; + } + // TODO - support negative heights (i.e. vertical flip) + if (header.height_px <= 0) { + Logger::error("Invalid BMP height: ", header.height_px, " (must be positive)"); + ret = FAILURE; + } + // TODO - validate x_resolution_ppm + // TODO - validate y_resolution_ppm + + // Validate colours +#define VALID_BITS_PER_PIXEL 1, 2, 4, 8, 16, 24, 32 +#define STR(x) #x + static const std::set BITS_PER_PIXEL { VALID_BITS_PER_PIXEL }; + if (!BITS_PER_PIXEL.contains(header.bits_per_pixel)) { + Logger::error("Invalid BMP bits per pixel: ", header.bits_per_pixel, " (must be one of " STR(VALID_BITS_PER_PIXEL) ")"); + ret = FAILURE; + } +#undef VALID_BITS_PER_PIXEL +#undef STR + static constexpr uint16_t PALETTE_BITS_PER_PIXEL_LIMIT = 8; + if (header.num_colours != 0 && header.bits_per_pixel > PALETTE_BITS_PER_PIXEL_LIMIT) { + Logger::error("Invalid BMP palette size: ", header.num_colours, " (should be 0 as bits per pixel is ", header.bits_per_pixel, " > 8)"); + ret = FAILURE; + } + // TODO - validate important_colours + + palette_size = header.bits_per_pixel > PALETTE_BITS_PER_PIXEL_LIMIT ? 0 + // Use header.num_colours if it's greater than 0 and at most 1 << header.bits_per_pixel + : 0 < header.num_colours && header.num_colours - 1 >> header.bits_per_pixel == 0 ? header.num_colours + : 1 << header.bits_per_pixel; + + const uint32_t expected_offset = palette_size * PALETTE_COLOUR_SIZE + sizeof(header); + if (header.offset != expected_offset) { + Logger::error("Invalid BMP image data offset: ", header.offset, " (should be ", expected_offset, ")"); + ret = FAILURE; + } + + header_validated = ret == SUCCESS; + return ret; +} + +return_t BMP::read_palette() { + if (file == nullptr) { + Logger::error("Cannot read BMP palette before opening a file"); + return FAILURE; + } + if (!header_validated) { + Logger::error("Cannot read palette before BMP header is validated!"); + return FAILURE; + } + if (palette_size == 0) { + Logger::error("Cannot read BMP palette - header indicates this file doesn't have one"); + return FAILURE; + } + if (fseek(file, sizeof(header), SEEK_SET) != 0) { + Logger::error("Failed to move to the palette in the BMP file!"); + return FAILURE; + } + palette.resize(palette_size); + if (fread(palette.data(), palette_size * PALETTE_COLOUR_SIZE, 1, file) != 1) { + Logger::error("Failed to read BMP header!"); + palette.clear(); + return FAILURE; + } + return SUCCESS; +} + +void BMP::close() { + if (file != nullptr) { + if (fclose(file) != 0) + Logger::error("Failed to close BMP!"); + file = nullptr; + } +} + +void BMP::reset() { + close(); + memset(&header, 0, sizeof(header)); + header_validated = false; + palette_size = 0; + palette.clear(); +} + +std::vector const& BMP::get_palette() const { + return palette; +} diff --git a/src/openvic/utility/BMP.hpp b/src/openvic/utility/BMP.hpp new file mode 100644 index 0000000..c6f5815 --- /dev/null +++ b/src/openvic/utility/BMP.hpp @@ -0,0 +1,48 @@ +#pragma once + +#include "../Types.hpp" + +namespace OpenVic { + class BMP { +#pragma pack(push) +#pragma pack(1) + struct header_t { + uint16_t signature; // Signature: 0x4d42 (or 'B' 'M') + uint32_t file_size; // File size in bytes + uint16_t reserved1; // Not used + uint16_t reserved2; // Not used + uint32_t offset; // Offset to image data in bytes from beginning of file + uint32_t dib_header_size; // DIB header size in bytes + int32_t width_px; // Width of the image + int32_t height_px; // Height of image + uint16_t num_planes; // Number of colour planes + uint16_t bits_per_pixel; // Bits per pixel + uint32_t compression; // Compression type + uint32_t image_size_bytes; // Image size in bytes + int32_t x_resolution_ppm; // Pixels per meter + int32_t y_resolution_ppm; // Pixels per meter + uint32_t num_colours; // Number of colours + uint32_t important_colours; // Important colours + } header; +#pragma pack(pop) + + FILE* file = nullptr; + bool header_validated = false; + uint32_t palette_size = 0; + std::vector palette; + + public: + static constexpr uint32_t PALETTE_COLOUR_SIZE = sizeof(colour_t); + + BMP() = default; + ~BMP(); + + return_t open(char const* filepath); + return_t read_header(); + return_t read_palette(); + void close(); + void reset(); + + std::vector const& get_palette() const; + }; +} diff --git a/src/openvic/utility/Logger.cpp b/src/openvic/utility/Logger.cpp new file mode 100644 index 0000000..fe97473 --- /dev/null +++ b/src/openvic/utility/Logger.cpp @@ -0,0 +1,18 @@ +#include "Logger.hpp" + +#include + +using namespace OpenVic; + +Logger::log_func_t Logger::info_func = [](std::string&& str) { std::cout << str; }; +Logger::log_func_t Logger::error_func = [](std::string&& str) { std::cerr << str; }; + +char const* Logger::get_filename(char const* filepath) { + if (filepath == nullptr) return nullptr; + char const* last_slash = filepath; + while (*filepath != '\0') { + if (*filepath == '\\' || *filepath == '/') last_slash = filepath + 1; + filepath++; + } + return last_slash; +} diff --git a/src/openvic/utility/Logger.hpp b/src/openvic/utility/Logger.hpp new file mode 100644 index 0000000..ac82445 --- /dev/null +++ b/src/openvic/utility/Logger.hpp @@ -0,0 +1,80 @@ +#pragma once + +#include +#include +#ifdef __cpp_lib_source_location +#include +#endif + +namespace OpenVic { + +#ifndef __cpp_lib_source_location +#include + // Implementation of std::source_location for compilers that do not support it + // Note: uses non-standard extensions that are supported by Clang, GCC, and MSVC + // https://clang.llvm.org/docs/LanguageExtensions.html#source-location-builtins + // https://stackoverflow.com/a/67970107 + class source_location { + std::string _file; + int _line; + std::string _function; + + public: + source_location(std::string f, int l, std::string n) : _file(f), _line(l), _function(n) {} + static source_location current(std::string f = __builtin_FILE(), int l = __builtin_LINE(), std::string n = __builtin_FUNCTION()) { + return source_location(f, l, n); + } + + inline char const* file_name() const { return _file.c_str(); } + inline int line() const { return _line; } + inline char const* function_name() const { return _function.c_str(); } + }; +#endif + + class Logger { + using log_func_t = std::function; + +#ifdef __cpp_lib_source_location + using source_location = std::source_location; +#else + using source_location = OpenVic::source_location; +#endif + + static char const* get_filename(char const* filepath); + + template + struct log { + log(log_func_t log_func, Ts&&... ts, source_location const& location) { + if (log_func) { + std::stringstream stream; + stream << "\n" << get_filename(location.file_name()) << "(" + << location.line() << ") `" << location.function_name() << "`: "; + ((stream << std::forward(ts)), ...); + stream << std::endl; + log_func(stream.str()); + } + } + }; + +#define LOG_FUNC(name) \ + private: \ + static log_func_t name##_func; \ + public: \ + static void set_##name##_func(log_func_t log_func) { \ + name##_func = log_func; \ + } \ + template \ + struct name { \ + name(Ts&&... ts, source_location const& location = source_location::current()) { \ + log{ name##_func, std::forward(ts)..., location }; \ + } \ + }; \ + template \ + name(Ts&&...) -> name; + + LOG_FUNC(info) + LOG_FUNC(error) + +#undef LOG_FUNC + }; +} -- cgit v1.2.3-56-ga3b1