summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2024-03-03 17:34:36 +0100
committerStanislaw Halik <sthalik@misaki.pl>2024-03-04 06:58:14 +0100
commit542d03a49fc5fc8a3aa0bb301973f68b199274e5 (patch)
treea06ec8e800ef445e652f49f722223c7ed4a164b5 /test
parente18740b132b10604f7f76f67d92eaff81453436e (diff)
a?
Diffstat (limited to 'test')
-rw-r--r--test/critter.cpp164
1 files changed, 120 insertions, 44 deletions
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{} << "";
}