aboutsummaryrefslogtreecommitdiff
path: root/src/openvic-simulation/misc/SimulationClock.cpp
blob: 324811c19cc49b7aaccd707c8cb30630232bd96a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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();
}