aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/misc/SimulationClock.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/openvic-simulation/misc/SimulationClock.hpp')
-rw-r--r--src/openvic-simulation/misc/SimulationClock.hpp59
1 files changed, 59 insertions, 0 deletions
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();
+ };
+}