aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules2
-rw-r--r--src/headless/main.cpp2
-rw-r--r--src/openvic-simulation/GameManager.cpp46
-rw-r--r--src/openvic-simulation/GameManager.hpp19
-rw-r--r--src/openvic-simulation/economy/BuildingInstance.cpp2
-rw-r--r--src/openvic-simulation/economy/BuildingInstance.hpp2
-rw-r--r--src/openvic-simulation/interface/GFX.cpp4
-rw-r--r--src/openvic-simulation/map/Map.cpp9
-rw-r--r--src/openvic-simulation/map/Map.hpp2
-rw-r--r--src/openvic-simulation/map/Province.cpp4
-rw-r--r--src/openvic-simulation/map/Province.hpp3
-rw-r--r--src/openvic-simulation/misc/GameAdvancementHook.cpp72
-rw-r--r--src/openvic-simulation/misc/GameAdvancementHook.hpp47
-rw-r--r--src/openvic-simulation/misc/SimulationClock.cpp69
-rw-r--r--src/openvic-simulation/misc/SimulationClock.hpp59
-rw-r--r--src/openvic-simulation/types/Vector.hpp2
16 files changed, 180 insertions, 164 deletions
diff --git a/.gitmodules b/.gitmodules
index 301d555..2309e93 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -6,4 +6,4 @@
url = https://github.com/OpenVicProject/scripts
[submodule "deps/lexy-vdf"]
path = deps/lexy-vdf
- url = https://github.com/OpenVicProject/lexy-vdf.git
+ url = https://github.com/OpenVicProject/lexy-vdf
diff --git a/src/headless/main.cpp b/src/headless/main.cpp
index 0400302..d4c316a 100644
--- a/src/headless/main.cpp
+++ b/src/headless/main.cpp
@@ -52,7 +52,7 @@ static bool run_headless(Dataloader::path_vector_t const& roots, bool run_tests)
GameManager game_manager { []() {
Logger::info("State updated");
- } };
+ }, nullptr };
ret &= headless_load(game_manager, dataloader);
diff --git a/src/openvic-simulation/GameManager.cpp b/src/openvic-simulation/GameManager.cpp
index 0471263..3f66352 100644
--- a/src/openvic-simulation/GameManager.cpp
+++ b/src/openvic-simulation/GameManager.cpp
@@ -5,29 +5,31 @@
using namespace OpenVic;
using namespace OpenVic::colour_literals;
-GameManager::GameManager(state_updated_func_t state_updated_callback)
- : clock {
- [this]() {
- tick();
- },
- [this]() {
- update_state();
- } }, state_updated { state_updated_callback } {}
-
-void GameManager::set_needs_update() {
- needs_update = true;
+GameManager::GameManager(
+ gamestate_updated_func_t gamestate_updated_callback, SimulationClock::state_changed_function_t clock_state_changed_callback
+) : simulation_clock {
+ std::bind(&GameManager::tick, this), std::bind(&GameManager::update_gamestate, this), clock_state_changed_callback
+ }, gamestate_updated { gamestate_updated_callback ? std::move(gamestate_updated_callback) : []() {} },
+ session_start { 0 }, today {}, gamestate_needs_update { false }, currently_updating_gamestate { false } {}
+
+void GameManager::set_gamestate_needs_update() {
+ if (!currently_updating_gamestate) {
+ gamestate_needs_update = true;
+ } else {
+ Logger::error("Attempted to queue a gamestate update already updating the gamestate!");
+ }
}
-void GameManager::update_state() {
- if (!needs_update) {
+void GameManager::update_gamestate() {
+ if (!gamestate_needs_update) {
return;
}
+ currently_updating_gamestate = true;
Logger::info("Update: ", today);
- map.update_state(today);
- if (state_updated) {
- state_updated();
- }
- needs_update = false;
+ map.update_gamestate(today);
+ gamestate_updated();
+ gamestate_needs_update = false;
+ currently_updating_gamestate = false;
}
/* REQUIREMENTS:
@@ -37,16 +39,16 @@ void GameManager::tick() {
today++;
Logger::info("Tick: ", today);
map.tick(today);
- set_needs_update();
+ set_gamestate_needs_update();
}
bool GameManager::reset() {
session_start = time(nullptr);
- clock.reset();
+ simulation_clock.reset();
today = {};
economy_manager.get_good_manager().reset_to_defaults();
bool ret = map.reset(economy_manager.get_building_type_manager());
- set_needs_update();
+ set_gamestate_needs_update();
return ret;
}
@@ -69,7 +71,7 @@ bool GameManager::load_bookmark(Bookmark const* new_bookmark) {
}
bool GameManager::expand_selected_province_building(size_t building_index) {
- set_needs_update();
+ set_gamestate_needs_update();
Province* province = map.get_selected_province();
if (province == nullptr) {
Logger::error("Cannot expand building index ", building_index, " - no province selected!");
diff --git a/src/openvic-simulation/GameManager.hpp b/src/openvic-simulation/GameManager.hpp
index 864b5bf..33be9d3 100644
--- a/src/openvic-simulation/GameManager.hpp
+++ b/src/openvic-simulation/GameManager.hpp
@@ -9,8 +9,8 @@
#include "openvic-simulation/map/Map.hpp"
#include "openvic-simulation/military/MilitaryManager.hpp"
#include "openvic-simulation/misc/Define.hpp"
-#include "openvic-simulation/misc/GameAdvancementHook.hpp"
#include "openvic-simulation/misc/Modifier.hpp"
+#include "openvic-simulation/misc/SimulationClock.hpp"
#include "openvic-simulation/politics/PoliticsManager.hpp"
#include "openvic-simulation/pop/Pop.hpp"
#include "openvic-simulation/research/ResearchManager.hpp"
@@ -19,7 +19,7 @@
namespace OpenVic {
struct GameManager {
- using state_updated_func_t = std::function<void()>;
+ using gamestate_updated_func_t = std::function<void()>;
private:
Map PROPERTY_REF(map);
@@ -36,20 +36,23 @@ namespace OpenVic {
EventManager PROPERTY_REF(event_manager);
DecisionManager PROPERTY_REF(decision_manager);
UIManager PROPERTY_REF(ui_manager);
- GameAdvancementHook PROPERTY_REF(clock);
+ SimulationClock PROPERTY_REF(simulation_clock);
time_t session_start; /* SS-54, as well as allowing time-tracking */
Bookmark const* PROPERTY(bookmark);
Date PROPERTY(today);
- state_updated_func_t state_updated;
- bool needs_update;
+ gamestate_updated_func_t gamestate_updated;
+ bool gamestate_needs_update, currently_updating_gamestate;
- void set_needs_update();
- void update_state();
+ void set_gamestate_needs_update();
+ void update_gamestate();
void tick();
public:
- GameManager(state_updated_func_t state_updated_callback);
+ GameManager(
+ gamestate_updated_func_t gamestate_updated_callback,
+ SimulationClock::state_changed_function_t clock_state_changed_callback
+ );
bool reset();
bool load_bookmark(Bookmark const* new_bookmark);
diff --git a/src/openvic-simulation/economy/BuildingInstance.cpp b/src/openvic-simulation/economy/BuildingInstance.cpp
index 047b759..f72c713 100644
--- a/src/openvic-simulation/economy/BuildingInstance.cpp
+++ b/src/openvic-simulation/economy/BuildingInstance.cpp
@@ -22,7 +22,7 @@ bool BuildingInstance::expand() {
/* REQUIREMENTS:
* MAP-71, MAP-74, MAP-77
*/
-void BuildingInstance::update_state(Date today) {
+void BuildingInstance::update_gamestate(Date today) {
switch (expansion_state) {
case ExpansionState::Preparing:
start_date = today;
diff --git a/src/openvic-simulation/economy/BuildingInstance.hpp b/src/openvic-simulation/economy/BuildingInstance.hpp
index 00e2dd6..e027a69 100644
--- a/src/openvic-simulation/economy/BuildingInstance.hpp
+++ b/src/openvic-simulation/economy/BuildingInstance.hpp
@@ -25,7 +25,7 @@ namespace OpenVic {
BuildingInstance(BuildingInstance&&) = default;
bool expand();
- void update_state(Date today);
+ void update_gamestate(Date today);
void tick(Date today);
};
}
diff --git a/src/openvic-simulation/interface/GFX.cpp b/src/openvic-simulation/interface/GFX.cpp
index 3624655..d7b9042 100644
--- a/src/openvic-simulation/interface/GFX.cpp
+++ b/src/openvic-simulation/interface/GFX.cpp
@@ -61,8 +61,8 @@ ProgressBar::ProgressBar() : back_colour {}, progress_colour {} {}
bool ProgressBar::_fill_key_map(key_map_t& key_map) {
bool ret = Sprite::_fill_key_map(key_map);
ret &= add_key_map_entries(key_map,
- "color", ONE_EXACTLY, expect_colour(assign_variable_callback(back_colour)),
- "colortwo", ONE_EXACTLY, expect_colour(assign_variable_callback(progress_colour)),
+ "color", ONE_EXACTLY, expect_colour(assign_variable_callback(progress_colour)),
+ "colortwo", ONE_EXACTLY, expect_colour(assign_variable_callback(back_colour)),
"textureFile1", ZERO_OR_ONE, expect_string(assign_variable_callback_string(progress_texture_file)),
"textureFile2", ZERO_OR_ONE, expect_string(assign_variable_callback_string(back_texture_file)),
"size", ONE_EXACTLY, expect_ivec2(assign_variable_callback(size)),
diff --git a/src/openvic-simulation/map/Map.cpp b/src/openvic-simulation/map/Map.cpp
index 67e91cd..39d4870 100644
--- a/src/openvic-simulation/map/Map.cpp
+++ b/src/openvic-simulation/map/Map.cpp
@@ -286,9 +286,9 @@ bool Map::apply_history_to_provinces(ProvinceHistoryManager const& history_manag
return ret;
}
-void Map::update_state(Date today) {
+void Map::update_gamestate(Date today) {
for (Province& province : provinces.get_items()) {
- province.update_state(today);
+ province.update_gamestate(today);
}
update_highest_province_population();
update_total_map_population();
@@ -684,11 +684,14 @@ bool Map::load_climate_file(ModifierManager const& modifier_manager, ast::NodeCP
return true;
}
))(node);
- cur_climate->lock();
}
return ret;
})(root);
+ for (Climate& climate : climates.get_items()) {
+ climate.lock();
+ }
+
lock_climates();
return ret;
diff --git a/src/openvic-simulation/map/Map.hpp b/src/openvic-simulation/map/Map.hpp
index 2575324..0025cf4 100644
--- a/src/openvic-simulation/map/Map.hpp
+++ b/src/openvic-simulation/map/Map.hpp
@@ -124,7 +124,7 @@ namespace OpenVic {
void update_highest_province_population();
void update_total_map_population();
- void update_state(Date today);
+ void update_gamestate(Date today);
void tick(Date today);
bool load_province_definitions(std::vector<ovdl::csv::LineObject> const& lines);
diff --git a/src/openvic-simulation/map/Province.cpp b/src/openvic-simulation/map/Province.cpp
index 2d301e8..1285b0d 100644
--- a/src/openvic-simulation/map/Province.cpp
+++ b/src/openvic-simulation/map/Province.cpp
@@ -112,9 +112,9 @@ void Province::update_pops() {
}
}
-void Province::update_state(Date today) {
+void Province::update_gamestate(Date today) {
for (BuildingInstance& building : buildings.get_items()) {
- building.update_state(today);
+ building.update_gamestate(today);
}
update_pops();
}
diff --git a/src/openvic-simulation/map/Province.hpp b/src/openvic-simulation/map/Province.hpp
index 431b4c2..7a42666 100644
--- a/src/openvic-simulation/map/Province.hpp
+++ b/src/openvic-simulation/map/Province.hpp
@@ -20,7 +20,6 @@ namespace OpenVic {
using Climate = ProvinceSetModifier;
using Continent = ProvinceSetModifier;
-
/* REQUIREMENTS:
* MAP-5, MAP-7, MAP-8, MAP-43, MAP-47
* POP-22
@@ -143,7 +142,7 @@ namespace OpenVic {
size_t get_pop_count() const;
void update_pops();
- void update_state(Date today);
+ void update_gamestate(Date today);
void tick(Date today);
private:
diff --git a/src/openvic-simulation/misc/GameAdvancementHook.cpp b/src/openvic-simulation/misc/GameAdvancementHook.cpp
deleted file mode 100644
index f4c0adc..0000000
--- a/src/openvic-simulation/misc/GameAdvancementHook.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-#include "GameAdvancementHook.hpp"
-
-using namespace OpenVic;
-
-const std::vector<std::chrono::milliseconds> GameAdvancementHook::GAME_SPEEDS = {
- std::chrono::milliseconds { 3000 }, std::chrono::milliseconds { 2000 }, std::chrono::milliseconds { 1000 },
- std::chrono::milliseconds { 100 }, std::chrono::milliseconds { 1 }
-};
-
-GameAdvancementHook::GameAdvancementHook(
- AdvancementFunction tick_function, RefreshFunction update_function, bool start_paused, speed_t starting_speed
-)
- : trigger_function { tick_function }, refresh_function { update_function }, is_paused { start_paused } {
- last_polled_time = std::chrono::high_resolution_clock::now();
- set_simulation_speed(starting_speed);
-}
-
-void GameAdvancementHook::set_simulation_speed(speed_t speed) {
- if (speed < 0) {
- current_speed = 0;
- } else if (speed >= GAME_SPEEDS.size()) {
- current_speed = GAME_SPEEDS.size() - 1;
- } else {
- current_speed = speed;
- }
-}
-
-void GameAdvancementHook::increase_simulation_speed() {
- set_simulation_speed(current_speed + 1);
-}
-
-void GameAdvancementHook::decrease_simulation_speed() {
- set_simulation_speed(current_speed - 1);
-}
-
-bool GameAdvancementHook::can_increase_simulation_speed() const {
- return current_speed + 1 < GAME_SPEEDS.size();
-}
-
-bool GameAdvancementHook::can_decrease_simulation_speed() const {
- return current_speed > 0;
-}
-
-GameAdvancementHook& GameAdvancementHook::operator++() {
- increase_simulation_speed();
- return *this;
-};
-
-GameAdvancementHook& GameAdvancementHook::operator--() {
- decrease_simulation_speed();
- return *this;
-};
-
-void GameAdvancementHook::conditionally_advance_game() {
- if (!is_paused) {
- time_point_t currentTime = std::chrono::high_resolution_clock::now();
- if (std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - last_polled_time) >= GAME_SPEEDS[current_speed]) {
- last_polled_time = currentTime;
- if (trigger_function) {
- trigger_function();
- }
- }
- }
- if (refresh_function) {
- refresh_function();
- }
-}
-
-void GameAdvancementHook::reset() {
- is_paused = true;
- current_speed = 0;
-}
diff --git a/src/openvic-simulation/misc/GameAdvancementHook.hpp b/src/openvic-simulation/misc/GameAdvancementHook.hpp
deleted file mode 100644
index 75af718..0000000
--- a/src/openvic-simulation/misc/GameAdvancementHook.hpp
+++ /dev/null
@@ -1,47 +0,0 @@
-#pragma once
-
-#include <chrono>
-#include <functional>
-#include <vector>
-#include "openvic-simulation/utility/Getters.hpp"
-
-namespace OpenVic {
- // Conditionally advances game with provided behaviour
- // Class governs game speed and pause state
- class GameAdvancementHook {
- public:
- using AdvancementFunction = std::function<void()>;
- using RefreshFunction = std::function<void()>;
- using speed_t = int8_t;
-
- // Minimum number of miliseconds before the simulation advances
- static const std::vector<std::chrono::milliseconds> GAME_SPEEDS;
-
- private:
- using time_point_t = std::chrono::time_point<std::chrono::high_resolution_clock>;
-
- time_point_t last_polled_time;
- // A function pointer that advances the simulation, intended to be a capturing
- // lambda or something similar. May need to be reworked later
- AdvancementFunction trigger_function;
- RefreshFunction refresh_function;
- speed_t PROPERTY_CUSTOM_NAME(current_speed, get_simulation_speed);
-
- public:
- bool is_paused;
-
- GameAdvancementHook(
- AdvancementFunction tick_function, RefreshFunction update_function, bool start_paused = true, speed_t starting_speed = 0
- );
-
- void set_simulation_speed(speed_t speed);
- void increase_simulation_speed();
- void decrease_simulation_speed();
- bool can_increase_simulation_speed() const;
- bool can_decrease_simulation_speed() const;
- GameAdvancementHook& operator++();
- GameAdvancementHook& operator--();
- void conditionally_advance_game();
- void reset();
- };
-}
diff --git a/src/openvic-simulation/misc/SimulationClock.cpp b/src/openvic-simulation/misc/SimulationClock.cpp
new file mode 100644
index 0000000..324811c
--- /dev/null
+++ b/src/openvic-simulation/misc/SimulationClock.cpp
@@ -0,0 +1,69 @@
+#include "SimulationClock.hpp"
+
+#include <algorithm>
+
+using namespace OpenVic;
+
+SimulationClock::SimulationClock(
+ tick_function_t new_tick_function, update_function_t new_update_function,
+ state_changed_function_t new_state_changed_function
+) : tick_function { new_tick_function ? std::move(new_tick_function) : []() {} },
+ update_function { new_update_function ? std::move(new_update_function) : []() {} },
+ state_changed_function { new_state_changed_function ? std::move(new_state_changed_function) : []() {} } {
+ reset();
+}
+
+void SimulationClock::set_paused(bool new_paused) {
+ if (paused != new_paused) {
+ toggle_paused();
+ }
+}
+
+void SimulationClock::toggle_paused() {
+ paused = !paused;
+ state_changed_function();
+}
+
+void SimulationClock::set_simulation_speed(speed_t speed) {
+ speed = std::clamp(speed, MIN_SPEED, MAX_SPEED);
+ if (current_speed != speed) {
+ current_speed = speed;
+ state_changed_function();
+ }
+}
+
+void SimulationClock::increase_simulation_speed() {
+ set_simulation_speed(current_speed + 1);
+}
+
+void SimulationClock::decrease_simulation_speed() {
+ set_simulation_speed(current_speed - 1);
+}
+
+bool SimulationClock::can_increase_simulation_speed() const {
+ return current_speed < MAX_SPEED;
+}
+
+bool SimulationClock::can_decrease_simulation_speed() const {
+ return current_speed > MIN_SPEED;
+}
+
+void SimulationClock::conditionally_advance_game() {
+ if (!paused) {
+ const time_point_t current_time = std::chrono::high_resolution_clock::now();
+ const std::chrono::milliseconds time_since_last_tick =
+ std::chrono::duration_cast<std::chrono::milliseconds>(current_time - last_tick_time);
+ if (time_since_last_tick >= GAME_SPEEDS[current_speed]) {
+ last_tick_time = current_time;
+ tick_function();
+ }
+ }
+ update_function();
+}
+
+void SimulationClock::reset() {
+ paused = true;
+ current_speed = 0;
+ last_tick_time = std::chrono::high_resolution_clock::now();
+ state_changed_function();
+}
diff --git a/src/openvic-simulation/misc/SimulationClock.hpp b/src/openvic-simulation/misc/SimulationClock.hpp
new file mode 100644
index 0000000..fbf7930
--- /dev/null
+++ b/src/openvic-simulation/misc/SimulationClock.hpp
@@ -0,0 +1,59 @@
+#pragma once
+
+#include <chrono>
+#include <functional>
+#include <vector>
+
+#include "openvic-simulation/utility/Getters.hpp"
+
+namespace OpenVic {
+ /* Conditionally advances game depending on speed and pause state. */
+ class SimulationClock {
+ public:
+ using tick_function_t = std::function<void()>;
+ using update_function_t = std::function<void()>;
+ using state_changed_function_t = std::function<void()>;
+ using speed_t = int8_t;
+
+ /* Minimum number of miliseconds before the simulation advances
+ * (in descending duration order, hence increasing speed order). */
+ static constexpr std::chrono::milliseconds GAME_SPEEDS[] {
+ std::chrono::milliseconds { 3000 }, std::chrono::milliseconds { 2000 }, std::chrono::milliseconds { 1000 },
+ std::chrono::milliseconds { 100 }, std::chrono::milliseconds { 1 }
+ };
+ static constexpr speed_t MIN_SPEED = 0, MAX_SPEED = std::size(GAME_SPEEDS) - 1;
+
+ private:
+ using time_point_t = std::chrono::time_point<std::chrono::high_resolution_clock>;
+
+ /* Advance simulation (triggered while unpaused at interval determined by speed). */
+ tick_function_t tick_function;
+ /* Refresh game state (triggered with every call to conditionally_advance_game). */
+ update_function_t update_function;
+ /* Callback for when speed or pause state is changed. */
+ state_changed_function_t state_changed_function;
+
+ time_point_t last_tick_time;
+ speed_t PROPERTY_CUSTOM_NAME(current_speed, get_simulation_speed);
+ bool PROPERTY_CUSTOM_PREFIX(paused, is);
+
+ public:
+
+ SimulationClock(
+ tick_function_t new_tick_function, update_function_t new_update_function,
+ state_changed_function_t new_state_changed_function
+ );
+
+ void set_paused(bool new_paused);
+ void toggle_paused();
+
+ void set_simulation_speed(speed_t speed);
+ void increase_simulation_speed();
+ void decrease_simulation_speed();
+ bool can_increase_simulation_speed() const;
+ bool can_decrease_simulation_speed() const;
+
+ void conditionally_advance_game();
+ void reset();
+ };
+}
diff --git a/src/openvic-simulation/types/Vector.hpp b/src/openvic-simulation/types/Vector.hpp
index 89fe12f..5514cc3 100644
--- a/src/openvic-simulation/types/Vector.hpp
+++ b/src/openvic-simulation/types/Vector.hpp
@@ -20,7 +20,7 @@ namespace OpenVic {
constexpr vec2_t& operator=(vec2_t&&) = default;
template<typename S>
- constexpr explicit operator vec2_t<S>() {
+ constexpr explicit operator vec2_t<S>() const {
return { static_cast<S>(x), static_cast<S>(y) };
}