diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-03-03 17:34:36 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-03-04 06:58:14 +0100 |
commit | 542d03a49fc5fc8a3aa0bb301973f68b199274e5 (patch) | |
tree | a06ec8e800ef445e652f49f722223c7ed4a164b5 | |
parent | e18740b132b10604f7f76f67d92eaff81453436e (diff) |
a?
-rw-r--r-- | src/timer-test.cpp | 5 | ||||
-rw-r--r-- | src/timer.hpp | 14 | ||||
-rw-r--r-- | test/critter.cpp | 164 |
3 files changed, 126 insertions, 57 deletions
diff --git a/src/timer-test.cpp b/src/timer-test.cpp index 36d31b30..5c764da0 100644 --- a/src/timer-test.cpp +++ b/src/timer-test.cpp @@ -4,9 +4,8 @@ namespace floormat { namespace { -constexpr auto MAX = 18446744073709551615u, HALF = 9223372036854775808u; -static_assert(std::is_same_v<uint64_t, std::decay_t<decltype(MAX)>>); -static_assert(std::is_same_v<uint64_t, std::decay_t<decltype(HALF)>>); +constexpr uint64_t MAX{18446744073709551615ULL} , HALF{9223372036854775808ULL}; +static_assert(sizeof MAX == 8); static_assert(MAX == (uint64_t)-1); static_assert(HALF + (HALF - 1) == MAX); static_assert(MAX - HALF == HALF - 1); diff --git a/src/timer.hpp b/src/timer.hpp index 1835d7e4..faf92a3e 100644 --- a/src/timer.hpp +++ b/src/timer.hpp @@ -4,6 +4,8 @@ namespace floormat { +// todo! move to .inl + struct Ns { explicit constexpr Ns(): stamp{0} {} @@ -70,14 +72,6 @@ struct Ns } #endif - static constexpr Ns from_millis(uint64_t a) - { - constexpr auto b = uint64_t(1e6); - const auto x = a * b; - fm_assert(a == 0 || x / a == b); - return Ns{x}; - } - friend constexpr Ns operator+(const Ns& lhs, const Ns& rhs) { constexpr auto max = (uint64_t)-1; @@ -186,8 +180,8 @@ struct Ns uint64_t stamp; }; -constexpr inline Ns Second{1000000000}, Millisecond{1000000}, Microsecond{1000}; -constexpr inline const Ns& Seconds{Second}, Milliseconds{Millisecond}, Microseconds{Microsecond}; +constexpr inline Ns Minute{60000000000}, Second{1000000000}, Millisecond{1000000}, Microsecond{1000}; +constexpr inline const Ns& Minutes{Minute}, Seconds{Second}, Milliseconds{Millisecond}, Microseconds{Microsecond}; struct Time final { diff --git a/test/critter.cpp b/test/critter.cpp index db974eb7..89c494fc 100644 --- a/test/critter.cpp +++ b/test/critter.cpp @@ -2,18 +2,25 @@ #include <cinttypes> #include "compat/debug.hpp" #include "compat/shared-ptr-wrapper.hpp" +#include "compat/function2.hpp" #include "src/critter.hpp" #include "src/world.hpp" #include "src/wall-atlas.hpp" #include "src/timer.hpp" #include "src/log.hpp" +#include "src/point.inl" #include "loader/loader.hpp" #include <iostream> +// todo! find all places where singed division is used + namespace floormat { namespace { +using enum rotation; +using fu2::function_view; + constexpr auto constantly(const auto& x) noexcept { return [x]<typename... Ts> (const Ts&...) constexpr -> const auto& { return x; }; } @@ -31,70 +38,126 @@ critter_proto make_proto(int accel) return proto; } -template<typename F> -void run(StringView name, const F& make_dt, critter& npc, - const point start, const rotation r, - const point end, const Ns expected_time, - const uint32_t fuzz_pixels, const Ns fuzz_time, - const Ns max_time = Second*300, bool no_crash = false) +struct Start { - constexpr uint32_t max_steps = 10'000; - fm_assert(max_time <= Second*300); + StringView name, instance; + point pt; + enum rotation rotation = N; +}; + +struct Expected +{ + point pt; + Ns time; +}; + +struct Grace +{ + Ns max_time = 600*Seconds; + uint32_t distance_L2 = 24; + uint32_t max_steps = 10'000; + bool no_crash = false; +}; + +bool run(StringView subtest_name, critter& npc, const function_view<Ns() const>& make_dt, + Start start, Expected expected, Grace grace = {}) +{ + //validate_start(start); + //validate_expected(expected); + //validate_grace(grace); + fm_assert(start.name); + fm_assert(start.instance); + fm_assert(start.rotation < rotation_COUNT); + fm_assert(expected.time > Ns{}); + fm_assert(expected.time <= grace.max_time); + fm_assert(grace.max_time <= 10*Minutes); + fm_assert(grace.max_time > Ns{}); + fm_assert(grace.distance_L2 <= (uint32_t)Vector2((iTILE_SIZE2 * TILE_MAX_DIM)).length()); + fm_assert(grace.max_steps > 0); + fm_assert(grace.max_steps <= 1000'00); auto index = npc.index(); - npc.teleport_to(index, start, rotation_COUNT); + npc.teleport_to(index, start.pt, rotation_COUNT); char buf[81]; Ns time{0}; - Debug{} << name << npc.position(); - + auto last_pos = npc.position(); uint32_t i; bool stopped = false; - constexpr auto bar = Second*1000; + if (subtest_name) + Debug{} << "-----" << start.name << "->" << start.instance << Debug::nospace << subtest_name << "-----"; + else + Debug{} << "-----" << start.name << subtest_name << "-----"; + + constexpr auto print_pos = [](StringView prefix, point start, point pos, Ns time, Ns dt) { + DBG_nospace << prefix << " " << pos << "--" + << " time:" << time + << " dt:" << dt + << " dist:" << point::distance_l2(pos, start); + }; - for (i = 0; i <= max_steps; i++) + for (i = 0; i <= grace.max_steps; i++) { - auto dt = Ns{make_dt()}; - //fm_assert(dt == Millisecond * 100); - const auto last_pos = npc.position(); - Debug{} << "-" << last_pos << colon(',') - << "time" << time - << Debug::nospace << ", dt" << dt; + const auto dt = Ns{make_dt()}; + if (dt == Ns{}) [[unlikely]] + { + Debug{} << "| dt == 0, breaking"; + break; + } + print_pos("-", expected.pt, npc.position(), time, dt); fm_assert(dt >= Millisecond*1e-1); fm_assert(dt <= Second * 1000); - npc.update_movement(index, dt, r); + npc.update_movement(index, dt, start.rotation); const auto pos = npc.position(); + const bool same_pos = pos == last_pos; + last_pos = pos; + time += dt; - if (pos == last_pos) + + if (same_pos) [[unlikely]] { - stopped = true; - Debug{} << "-" << last_pos << colon(',') - << "time" << time << Debug::nospace - << ", dt" << dt; - Debug{} << "break!"; + print_pos("-", expected.pt, pos, time, dt); + Debug{} << "===>" << i << "iters" << colon(',') << time; + fm_assert(i != 0); break; } - if (time > max_time) [[unlikely]] + if (time > grace.max_time) [[unlikely]] { - Error{&std::cerr} << "timeout:" << max_time << "reached!"; - if (no_crash) - return; + print_pos("*", start.pt, last_pos, time, dt); + Error{&std::cerr} << "!!! fatal: timeout" << grace.max_time << "reached!"; + if (grace.no_crash) + return false; else - fm_EMIT_ABORT(); + fm_assert(false); + } + if (i > grace.max_steps) [[unlikely]] + { + print_pos("*", start.pt, last_pos, time, dt); + Error{&std::cerr} << "!!! fatal: position doesn't converge after" << i << "iterations!"; + if (grace.no_crash) + return false; + else + fm_assert(false); } - - fm_assert(i != max_steps); } - if (stopped) + + + if (const auto dist_l2 = point::distance_l2(last_pos, expected.pt); + dist_l2 > grace.distance_L2) { - Debug{} << "===>" << i << "iters" << colon(',') << time; - // todo! calc distance + Error{&std::cerr} << "!!! error: distance" << dist_l2 << "pixels" << "over grace distance of" << grace.distance_L2; + if (grace.no_crash) + fm_assert(false); + else + fm_assert(false); } else - Debug{} << "!!! error: position doesn't converge after" << i << "iterations!"; + Debug{} << "*" << "distance:" << dist_l2 << "pixels"; + + return true; } /* ***** TEST 1 ***** @@ -113,9 +176,7 @@ void run(StringView name, const F& make_dt, critter& npc, * time=6800ms */ -using enum rotation; - -template<typename F> void test1(const F& make_dt, int accel) +template<typename F> void test1(StringView instance_name, const F& make_dt, int accel) { const auto W = wall_image_proto{ loader.wall_atlas("empty"), 0 }; @@ -132,7 +193,21 @@ template<typename F> void test1(const F& make_dt, int accel) w[chunk_coords_{0,0,0}].mark_modified(); w[chunk_coords_{0,1,0}].mark_modified(); - run("test1"_s, make_dt, *player, init, N, end, Second*7, 16, Second*60); + bool ret = run("test1", *player, make_dt, + Start{ + .name = "test1", + .instance = instance_name, + .pt = init, + .rotation = N, + }, + Expected{ + .pt = end, + .time = Millisecond*6950, + }, + Grace{}); + fm_assert(ret); + + //run("test1"_s, make_dt, *player, init, N, end, Second*7, Millisecond*16.667, Second*60); } /* ***** TEST 2 ***** @@ -151,9 +226,10 @@ void test_app::test_critter() Debug{} << ""; Debug{} << "--"; Debug{} << ""; - test1(constantly(Millisecond * 100), 1); - test1(constantly(Millisecond * 10), 1); - test1(constantly(Millisecond * 1), 1); + test1("dt=1000 ms",constantly(Millisecond * 1000), 1); + test1("dt=100 ms", constantly(Millisecond * 100), 1); + test1("dt=50 ms", constantly(Millisecond * 50), 1); + test1("dt=16.667 ms", constantly(Millisecond * 16.667), 1); Debug{} << ""; } |