diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2024-02-29 21:29:56 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2024-03-01 06:06:53 +0100 |
commit | 486e591169af724107ffaf6f24cd1e81b24529a9 (patch) | |
tree | 012ec6c07c474d4695eb5c22b47dd35cfce2767c /src/timer.cpp | |
parent | 5afe42d6a81eeb81db08d4bd2107ac4c71f6671e (diff) |
time wip
It works now, but some functionality is lost in main/draw.cpp
Diffstat (limited to 'src/timer.cpp')
-rw-r--r-- | src/timer.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/timer.cpp b/src/timer.cpp new file mode 100644 index 00000000..0b87ac06 --- /dev/null +++ b/src/timer.cpp @@ -0,0 +1,76 @@ +#include "timer.hpp" +#include "compat/assert.hpp" +#include <ctime> +#include <cstdio> +#include <chrono> +#include <mg/Time.h> + +namespace floormat { + +using std::chrono::duration_cast; +using std::chrono::duration; + +using Clock = std::chrono::high_resolution_clock; +using SystemClock = std::chrono::system_clock; +using Nsecs = duration<uint64_t, std::nano>; +using Millis = duration<unsigned, std::milli>; + +namespace { + +template<typename T> struct array_size_; +template<typename T, size_t N> struct array_size_<T(&)[N]> : std::integral_constant<size_t, N> {}; +template<typename T, size_t N> struct array_size_<std::array<T, N>> : std::integral_constant<size_t, N> {}; +template<typename T> constexpr inline auto array_size = array_size_<T>::value; + +uint64_t get_time() noexcept { return duration_cast<Nsecs>(Clock::now().time_since_epoch()).count(); } + +const uint64_t Epoch = get_time(); + +} // namespace + +Time Time::now() noexcept +{ + auto val = get_time(); + auto ret = val - Epoch; + return {ret}; +} + +Ns operator-(const Time& a, const Time& b) noexcept +{ + fm_assert(a.stamp >= b.stamp); + auto ret = a.stamp - b.stamp; + fm_assert(ret < uint64_t{1} << 63); + return Ns{ int64_t(ret) }; +} + +Ns Time::update(const Time& ts) & noexcept +{ + auto ret = ts - *this; + stamp = ts.stamp; + return ret; +} + +uint64_t Time::init() noexcept { return get_time(); } +bool Time::operator==(const Time&) const noexcept = default; +std::strong_ordering Time::operator<=>(const Time&) const noexcept = default; + +float Time::to_seconds(const Ns& ts) noexcept { return float(Ns::Type{ts} * 1e-9L); } +float Time::to_milliseconds(const Ns& ts) noexcept { return float(Ns::Type{ts} * 1e-6L); } + +const char* format_datetime_to_string(char (&buf)[fm_DATETIME_BUF_SIZE]) +{ + constexpr const char* fmt = "%a, %d %b %Y %H:%M:%S."; + constexpr size_t fmtsize = std::size("Thu 01 Mon 197000 00:00:00."); + static_assert(array_size<decltype(buf)> - fmtsize == 4); + const auto t = SystemClock::now(); + const auto ms = duration_cast<Millis>(t.time_since_epoch()) % 1000; + const auto time = SystemClock::to_time_t(t); + const auto* tm = std::localtime(&time); + auto len = std::strftime(buf, std::size(buf), fmt, tm); + fm_assert(len > 0 && len <= fmtsize); + auto len2 = std::sprintf(buf + len, "%03u", unsigned{ms.count()}); + fm_assert(len2 > 0 && len + (size_t)len2 < std::size(buf)); + return buf; +} + +} // namespace floormat |