diff options
-rw-r--r-- | src/object.cpp | 2 | ||||
-rw-r--r-- | src/timer.hpp | 51 | ||||
-rw-r--r-- | test/critter.cpp | 23 | ||||
-rw-r--r-- | test/serializer.cpp | 3 |
4 files changed, 51 insertions, 28 deletions
diff --git a/src/object.cpp b/src/object.cpp index db3c5b67..e881e5d0 100644 --- a/src/object.cpp +++ b/src/object.cpp @@ -289,7 +289,7 @@ bool object::move_to(Magnum::Vector2i delta) uint32_t object::allocate_frame_time(Ns dt, uint16_t& accum, uint32_t hz, float speed) { - constexpr auto ns_in_sec = Ns(1e9); + constexpr auto ns_in_sec = Ns((int)1e9); constexpr auto u16_max = uint64_t{65535}; fm_assert(hz > 0); diff --git a/src/timer.hpp b/src/timer.hpp index a1e8c1ac..96b652f7 100644 --- a/src/timer.hpp +++ b/src/timer.hpp @@ -7,8 +7,17 @@ namespace floormat { struct Ns { explicit constexpr Ns(): stamp{0} {} - explicit constexpr Ns(uint64_t x) : stamp{x} {} + + template<typename T> + requires (std::is_integral_v<T> && std::is_unsigned_v<T>) + explicit constexpr Ns(T x) : stamp{x} {} + + template<typename T> + requires (std::is_integral_v<T> && !std::is_unsigned_v<T>) + explicit constexpr Ns(T x) : stamp{uint64_t(x)} { fm_assert(x >= T{0}); } + +#if 0 template<typename T> requires std::is_same_v<T, float> explicit constexpr Ns(T x) : stamp{} @@ -16,7 +25,7 @@ struct Ns constexpr float max{uint64_t{1} << 24}; fm_assert(x >= 0); fm_assert(x <= max); - stamp = uint64_t(x * 1e-9); + stamp = uint64_t(x); } template<typename T> @@ -26,23 +35,30 @@ struct Ns constexpr double max{uint64_t{1} << 54}; fm_assert(x >= 0); fm_assert(x <= max); - stamp = uint64_t(x * 1e-9); + stamp = uint64_t(x); } +#endif explicit constexpr operator uint64_t() const { return stamp; } - //explicit constexpr operator double() const { return stamp; } + + explicit constexpr operator double() const = delete; explicit constexpr operator float() const = delete; template<typename T> - requires (std::is_same_v<T, float>) - static Ns from_nonzero(T seconds) + requires (std::is_same_v<T, double>) + friend Ns operator*(const Ns& lhs, T b) { - constexpr float max{uint64_t{1} << 24}; - fm_assert(seconds >= 0); - fm_assert (seconds <= max); - return Ns((uint64_t)seconds); + constexpr double max{uint64_t{1} << 54}; + auto a = lhs.stamp; + fm_assert(b >= 0); + fm_assert(b <= max); + auto x = double(a) * b; + fm_assert(x <= max); + fm_assert(x >= 0); + return Ns{(uint64_t)x}; } +#if 0 template<typename T> requires (std::is_same_v<T, double>) static Ns from_nonzero(T seconds) @@ -52,6 +68,7 @@ struct Ns fm_assert(seconds <= max); return Ns((uint64_t)seconds); } +#endif static constexpr Ns from_millis(uint64_t a) { @@ -61,8 +78,6 @@ struct Ns return Ns{x}; } - // ----- - friend constexpr Ns operator+(const Ns& lhs, const Ns& rhs) { constexpr auto max = (uint64_t)-1; @@ -95,7 +110,10 @@ struct Ns friend constexpr Ns operator*(const Ns& lhs, T rhs) { fm_assert(rhs >= T{0}); - return lhs * uint64_t(rhs); + auto b = uint64_t(rhs); + auto x = lhs.stamp * b; + fm_assert(b == 0 || x / b == lhs.stamp); + return Ns{x}; } template<typename T> @@ -113,9 +131,10 @@ struct Ns return Ns{uint64_t(x)}; } - template<typename T> - requires std::is_same_v<float, T> - friend constexpr inline Ns operator*(T lhs, const Ns& rhs) { return rhs * lhs; } +#if 0 + template<typename T> requires (!std::is_same_v<Ns, T>) + friend constexpr Ns operator*(const T& lhs, const Ns& rhs) { return rhs * lhs; } +#endif friend constexpr uint64_t operator/(const Ns& lhs, const Ns& rhs) { diff --git a/test/critter.cpp b/test/critter.cpp index 0a959317..4e215ab2 100644 --- a/test/critter.cpp +++ b/test/critter.cpp @@ -22,11 +22,10 @@ template<typename F> void run(StringView name, const F& make_dt, critter& npc, const Ns max_time, const point start, const rotation r, const point end, const Ns expected_time, - const uint32_t fuzz_pixels, const Ns fuzz_time) + const uint32_t fuzz_pixels, const Ns fuzz_time, bool no_crash = false) { constexpr uint32_t max_steps = 10'000; - const bool verbose = is_log_verbose(); - fm_assert(max_time < Second*200); + fm_assert(max_time < Second*300); auto index = npc.index(); npc.teleport_to(index, start, rotation_COUNT); @@ -41,26 +40,32 @@ void run(StringView name, const F& make_dt, critter& npc, const Ns max_time, uint32_t i; bool stopped = false; + constexpr auto bar = Second*1000; + for (i = 0; i <= max_steps; i++) { auto dt = Ns{make_dt()}; - fm_assert(dt <= Ns(1e9)); + fm_assert(dt == Millisecond * 100); + const auto pos = npc.position(); + Debug{} << "-" << pos << colon(',') << "time" << time << Debug::nospace << ", dt" << dt; + fm_assert(dt >= Millisecond*1e-1); + fm_assert(dt <= Second * 1000); npc.update_movement(index, dt, r); time += dt; - const auto pos = npc.position(); if (pos == last_pos) { stopped = true; break; } last_pos = pos; - Debug{} << "-" << pos << colon(',') << time; if (time > max_time) [[unlikely]] { - if (verbose) - Error{&std::cerr} << "timeout:" << max_time << "reached!"; - fm_EMIT_ABORT(); + Error{&std::cerr} << "timeout:" << max_time << "reached!"; + if (no_crash) + return; + else + fm_EMIT_ABORT(); } fm_assert(i != max_steps); diff --git a/test/serializer.cpp b/test/serializer.cpp index 61a5d509..e85f7892 100644 --- a/test/serializer.cpp +++ b/test/serializer.cpp @@ -53,8 +53,7 @@ chunk& test_app::make_test_chunk(world& w, chunk_coords_ ch) auto& e = *w.make_object<scenery>(w.make_id(), {ch, {K+3, K+1}}, door); const auto index = e.index(); const auto end = e.atlas->info().nframes-1; - constexpr auto second = Ns(1e9); - constexpr auto dt = Ns{second.stamp / 60}; + constexpr Ns dt = Second / 60; fm_assert(e.frame == end); { auto& x = std::get<door_scenery>(e.subtype); fm_assert(!x.active); |