2424
2525using namespace OpenVic ;
2626
27- inline static void print_bytes (std::string_view prefix, const std::source_location& location = std::source_location::current()) {
27+ inline static void print_memory_usage (
28+ std::string_view prefix, std::source_location const & location = std::source_location::current()
29+ ) {
2830#ifdef DEBUG_ENABLED // memory tracking will return 0 without DEBUG_ENABLED
2931 Logger::info<std::string_view&, const char (&)[16 ], uint64_t &&, const char (&)[7 ]>(
3032 prefix, " Memory Usage: " , OpenVic::utility::MemoryTracker::get_memory_usage (), " Bytes" , location
@@ -79,8 +81,12 @@ static void print_rgo(ProvinceInstance const& province) {
7981using pathing_rng_t = std::mt19937;
8082using pathing_rng_seed_t = pathing_rng_t ::result_type;
8183
84+ using testing_clock_t = std::chrono::high_resolution_clock;
85+ using test_time_point_t = testing_clock_t ::time_point;
86+ using test_duration_t = testing_clock_t ::duration;
87+
8288template <size_t TestCount>
83- static std::chrono::nanoseconds run_pathing_test (AStarPathing& pathing, std::optional<pathing_rng_seed_t > seed) {
89+ static test_duration_t run_pathing_test (AStarPathing& pathing, std::optional<pathing_rng_seed_t > seed) {
8490 PointMap const & points = pathing.get_point_map ();
8591
8692 if (!seed.has_value ()) {
@@ -107,11 +113,11 @@ static std::chrono::nanoseconds run_pathing_test(AStarPathing& pathing, std::opt
107113 from_to_tests[index] = { from, to };
108114 }
109115
110- auto start_time = std::chrono::high_resolution_clock ::now ();
116+ const test_time_point_t start_time = testing_clock_t ::now ();
111117 for (auto [index, pair] : from_to_tests | ranges::views::enumerate) {
112118 test_results[index] = pathing.get_id_path (pair.first .key (), pair.second .key ());
113119 }
114- auto end_time = std::chrono::high_resolution_clock ::now ();
120+ const test_time_point_t end_time = testing_clock_t ::now ();
115121
116122 for (auto [index, test] : test_results | ranges::views::enumerate) {
117123 Logger::info (" -Start Test " , index + 1 , " -" );
@@ -162,7 +168,7 @@ static bool run_headless(fs::path const& root, memory::vector<memory::string>& m
162168 }
163169 );
164170
165- print_bytes (" Definition Setup" );
171+ print_memory_usage (" Definition Setup" );
166172
167173 if (run_tests) {
168174 Testing testing { game_manager.get_definition_manager () };
@@ -177,15 +183,15 @@ static bool run_headless(fs::path const& root, memory::vector<memory::string>& m
177183 game_manager.get_definition_manager ().get_history_manager ().get_bookmark_manager ().get_bookmark_by_index (0 )
178184 );
179185
180- print_bytes (" Instance Setup" );
186+ print_memory_usage (" Instance Setup" );
181187
182188 Logger::info (" ===== Starting game session... =====" );
183189 ret &= game_manager.start_game_session ();
184190
185191 // This triggers a gamestate update
186192 ret &= game_manager.update_clock ();
187193
188- print_bytes (" Game Session Post-Start" );
194+ print_memory_usage (" Game Session Post-Start" );
189195
190196 // TODO - REMOVE TEST CODE
191197 Logger::info (" ===== Ranking system test... =====" );
@@ -232,29 +238,60 @@ static bool run_headless(fs::path const& root, memory::vector<memory::string>& m
232238 // Set to std::nullopt to use a different random seed on each run
233239 static constexpr std::optional<pathing_rng_seed_t > LAND_SEED = 1836 , SEA_SEED = 1861 ;
234240
241+ using test_time_units_t = std::chrono::milliseconds;
242+
235243 Logger::info (" ===== Land Pathfinding test... =====" );
236- std::chrono::nanoseconds ns = run_pathing_test<TESTS>(
244+ test_duration_t duration = std::chrono::duration_cast< test_time_units_t >( run_pathing_test<TESTS>(
237245 game_manager.get_instance_manager ()->get_map_instance ().get_land_pathing (), LAND_SEED
238- );
239- Logger::info (" Ran " , TESTS, " land pathing tests in " , ns );
246+ )) ;
247+ Logger::info (" Ran " , TESTS, " land pathing tests in " , duration );
240248
241249 Logger::info (" ===== Sea Pathfinding test... =====" );
242- ns = run_pathing_test<TESTS>(
250+ duration = std::chrono::duration_cast< test_time_units_t >( run_pathing_test<TESTS>(
243251 game_manager.get_instance_manager ()->get_map_instance ().get_sea_pathing (), SEA_SEED
244- );
245- Logger::info (" Ran " , TESTS, " sea pathing tests in " , ns );
252+ )) ;
253+ Logger::info (" Ran " , TESTS, " sea pathing tests in " , duration );
246254 }
247255
248256 if (ret) {
257+ static constexpr size_t TICK_COUNT = 10 ;
258+
249259 Logger::info (" ===== Game Tick test... =====" );
250260 size_t ticks_passed = 0 ;
251- auto start_time = std::chrono::high_resolution_clock::now ();
252- while (ticks_passed++ < 10 ) {
261+ test_duration_t min_tick_duration = test_duration_t::max (), max_tick_duration = test_duration_t::min (),
262+ total_tick_duration;
263+ const test_time_point_t start_time = testing_clock_t::now ();
264+ while (++ticks_passed < TICK_COUNT) {
265+ const test_time_point_t tick_start = testing_clock_t::now ();
253266 game_manager.get_instance_manager ()->force_tick_and_update ();
254- print_bytes (" Tick Finished" );
267+ const test_time_point_t tick_end = testing_clock_t::now ();
268+
269+ const test_duration_t tick_duration = tick_end - tick_start;
270+
271+ min_tick_duration = std::min (min_tick_duration, tick_duration);
272+ max_tick_duration = std::max (max_tick_duration, tick_duration);
273+
274+ total_tick_duration += tick_duration;
275+
276+ print_memory_usage (fmt::format (" Tick {} finished" , ticks_passed));
277+ }
278+ const test_time_point_t end_time = testing_clock_t::now ();
279+ const test_duration_t duration = end_time - start_time;
280+
281+ if (ticks_passed != 0 && duration != test_duration_t::zero ()) {
282+ const test_duration_t tick_tps = total_tick_duration / ticks_passed;
283+ const test_duration_t total_tps = duration / ticks_passed;
284+ Logger::info (
285+ " Ran " , ticks_passed, " / " , TICK_COUNT, " ticks, total time " , duration, " at, " , total_tps,
286+ " per tick, tick time only " , total_tick_duration, " at " , tick_tps, " per tick. Tick lengths ranged from " ,
287+ min_tick_duration, " to " , max_tick_duration, " ."
288+ );
289+ } else {
290+ Logger::error (
291+ " No ticks passed (" , ticks_passed, " , expected " , TICK_COUNT, " ) or zero duration measured (" , duration, " )!"
292+ );
293+ ret = false ;
255294 }
256- auto end_time = std::chrono::high_resolution_clock::now ();
257- Logger::info (" Ran " , --ticks_passed, " ticks in " , end_time - start_time);
258295 }
259296
260297 Logger::info (" ===== Ending game session... =====" );
@@ -283,7 +320,8 @@ int main(int argc, char const* argv[]) {
283320 * message and the help text are displayed, along with returning false to signify the program should exit.
284321 */
285322 const auto _read = [&root, &argn, argc, argv, program_name](
286- std::string_view command, std::string_view path_use, auto path_transform) -> bool {
323+ std::string_view command, std::string_view path_use, std::invocable<fs::path> auto path_transform
324+ ) -> bool {
287325 if (root.empty ()) {
288326 if (++argn < argc) {
289327 char const * path = argv[argn];
0 commit comments