From a69b88e09a6a2ecdc739e09ed8ca2afb50dce99f Mon Sep 17 00:00:00 2001 From: MrSimbax Date: Sat, 11 Sep 2021 13:26:38 +0200 Subject: [PATCH] Move time related functions out of CSystemUtils GetCurrentTimeStamp() has not been moved because of CApplication unit tests. --- src/CMakeLists.txt | 2 + src/app/app.cpp | 26 ++++---- src/app/app.h | 12 ++-- src/common/profiler.cpp | 10 ++-- src/common/profiler.h | 2 +- src/common/system/system.cpp | 29 +-------- src/common/system/system.h | 28 +-------- src/common/system/system_linux.cpp | 11 ---- src/common/timeutils.cpp | 54 +++++++++++++++++ src/common/timeutils.h | 50 ++++++++++++++++ src/graphics/engine/engine.cpp | 4 +- src/graphics/engine/engine.h | 4 +- test/unit/CMakeLists.txt | 5 +- test/unit/app/app_test.cpp | 11 ++-- test/unit/common/system/system_test.cpp | 79 ------------------------- test/unit/common/timeutils_test.cpp | 78 ++++++++++++++++++++++++ 16 files changed, 227 insertions(+), 178 deletions(-) create mode 100644 src/common/timeutils.cpp create mode 100644 src/common/timeutils.h delete mode 100644 test/unit/common/system/system_test.cpp create mode 100644 test/unit/common/timeutils_test.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 69de9fe0..105bce70 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -83,6 +83,8 @@ add_library(colobotbase STATIC common/singleton.h common/stringutils.cpp common/stringutils.h + common/timeutils.cpp + common/timeutils.h common/thread/worker_thread.h graphics/core/color.cpp graphics/core/color.h diff --git a/src/app/app.cpp b/src/app/app.cpp index c2264cf8..a30e0ba7 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -61,6 +61,9 @@ #include #include +using TimeUtils::TimeStamp; +using TimeUtils::TimeUnit; + char CApplication::m_languageLocale[] = { 0 }; @@ -70,7 +73,6 @@ const int JOYSTICK_TIMER_INTERVAL = 1000/30; //! Function called by the timer Uint32 JoystickTimerCallback(Uint32 interval, void *); - /** * \struct ApplicationPrivate * \brief Private data of CApplication class @@ -1043,9 +1045,9 @@ int CApplication::Run() MoveMouse(Math::Point(0.5f, 0.5f)); // center mouse on start - SystemTimeStamp previousTimeStamp{}; - SystemTimeStamp currentTimeStamp{}; - SystemTimeStamp interpolatedTimeStamp{}; + TimeStamp previousTimeStamp{}; + TimeStamp currentTimeStamp{}; + TimeStamp interpolatedTimeStamp{}; while (true) { @@ -1153,7 +1155,7 @@ int CApplication::Run() currentTimeStamp = m_systemUtils->GetCurrentTimeStamp(); for(int tickSlice = 0; tickSlice < numTickSlices; tickSlice++) { - interpolatedTimeStamp = m_systemUtils->TimeStampLerp(previousTimeStamp, currentTimeStamp, (tickSlice+1)/static_cast(numTickSlices)); + interpolatedTimeStamp = TimeUtils::Lerp(previousTimeStamp, currentTimeStamp, (tickSlice+1)/static_cast(numTickSlices)); Event event = CreateUpdateEvent(interpolatedTimeStamp); if (event.type != EVENT_NULL && m_controller != nullptr) { @@ -1478,7 +1480,7 @@ void CApplication::Render() void CApplication::RenderIfNeeded(int updateRate) { m_manualFrameTime = m_systemUtils->GetCurrentTimeStamp(); - long long diff = m_systemUtils->TimeStampExactDiff(m_manualFrameLast, m_manualFrameTime); + long long diff = TimeUtils::ExactDiff(m_manualFrameLast, m_manualFrameTime); if (diff < 1e9f / updateRate) { return; @@ -1522,13 +1524,13 @@ void CApplication::StartLoadingMusic() std::thread{[this]() { GetLogger()->Debug("Cache sounds...\n"); - SystemTimeStamp musicLoadStart{m_systemUtils->GetCurrentTimeStamp()}; + TimeStamp musicLoadStart{m_systemUtils->GetCurrentTimeStamp()}; m_sound->Reset(); m_sound->CacheAll(); - SystemTimeStamp musicLoadEnd{m_systemUtils->GetCurrentTimeStamp()}; - float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, SystemTimeUnit::MILLISECONDS); + TimeStamp musicLoadEnd{m_systemUtils->GetCurrentTimeStamp()}; + float musicLoadTime = TimeUtils::Diff(musicLoadStart, musicLoadEnd, TimeUnit::MILLISECONDS); GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime); }}.detach(); } @@ -1549,7 +1551,7 @@ void CApplication::SetSimulationSpeed(float speed) GetLogger()->Info("Simulation speed = %.2f\n", speed); } -Event CApplication::CreateUpdateEvent(SystemTimeStamp newTimeStamp) +Event CApplication::CreateUpdateEvent(TimeStamp newTimeStamp) { if (m_simulationSuspended) return Event(EVENT_NULL); @@ -1557,9 +1559,9 @@ Event CApplication::CreateUpdateEvent(SystemTimeStamp newTimeStamp) m_lastTimeStamp = m_curTimeStamp; m_curTimeStamp = newTimeStamp; - long long absDiff = m_systemUtils->TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp); + long long absDiff = TimeUtils::ExactDiff(m_baseTimeStamp, m_curTimeStamp); long long newRealAbsTime = m_realAbsTimeBase + absDiff; - long long newRealRelTime = m_systemUtils->TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp); + long long newRealRelTime = TimeUtils::ExactDiff(m_lastTimeStamp, m_curTimeStamp); if (newRealAbsTime < m_realAbsTime || newRealRelTime < 0) { diff --git a/src/app/app.h b/src/app/app.h index 60d11c42..7160be54 100644 --- a/src/app/app.h +++ b/src/app/app.h @@ -297,7 +297,7 @@ protected: //! If applicable, creates a virtual event to match the changed state as of new event Event CreateVirtualEvent(const Event& sourceEvent); //! Prepares a simulation update event - TEST_VIRTUAL Event CreateUpdateEvent(SystemTimeStamp newTimeStamp); + TEST_VIRTUAL Event CreateUpdateEvent(TimeUtils::TimeStamp newTimeStamp); //! Logs debug data for event void LogEvent(const Event& event); @@ -354,9 +354,9 @@ protected: //! Animation time stamps, etc. //@{ - SystemTimeStamp m_baseTimeStamp; - SystemTimeStamp m_lastTimeStamp; - SystemTimeStamp m_curTimeStamp; + TimeUtils::TimeStamp m_baseTimeStamp; + TimeUtils::TimeStamp m_lastTimeStamp; + TimeUtils::TimeStamp m_curTimeStamp; long long m_realAbsTimeBase; long long m_realAbsTime; @@ -373,8 +373,8 @@ protected: bool m_simulationSuspended; //@} - SystemTimeStamp m_manualFrameLast; - SystemTimeStamp m_manualFrameTime; + TimeUtils::TimeStamp m_manualFrameLast; + TimeUtils::TimeStamp m_manualFrameTime; //! Graphics device to use bool m_graphicsOverride = false; diff --git a/src/common/profiler.cpp b/src/common/profiler.cpp index d97572d8..56a5996d 100644 --- a/src/common/profiler.cpp +++ b/src/common/profiler.cpp @@ -23,10 +23,12 @@ #include +using TimeUtils::TimeStamp; + CSystemUtils* CProfiler::m_systemUtils = nullptr; long long CProfiler::m_performanceCounters[PCNT_MAX] = {0}; long long CProfiler::m_prevPerformanceCounters[PCNT_MAX] = {0}; -std::stack CProfiler::m_runningPerformanceCounters; +std::stack CProfiler::m_runningPerformanceCounters; std::stack CProfiler::m_runningPerformanceCountersType; void CProfiler::SetSystemUtils(CSystemUtils* systemUtils) @@ -39,7 +41,7 @@ void CProfiler::StartPerformanceCounter(PerformanceCounter counter) if (counter == PCNT_ALL) ResetPerformanceCounters(); - SystemTimeStamp timeStamp = m_systemUtils->GetCurrentTimeStamp(); + TimeStamp timeStamp = m_systemUtils->GetCurrentTimeStamp(); m_runningPerformanceCounters.push(timeStamp); m_runningPerformanceCountersType.push(counter); } @@ -49,8 +51,8 @@ void CProfiler::StopPerformanceCounter(PerformanceCounter counter) assert(m_runningPerformanceCountersType.top() == counter); m_runningPerformanceCountersType.pop(); - SystemTimeStamp timeStamp = m_systemUtils->GetCurrentTimeStamp(); - m_performanceCounters[counter] += m_systemUtils->TimeStampExactDiff(m_runningPerformanceCounters.top(), timeStamp); + TimeStamp timeStamp = m_systemUtils->GetCurrentTimeStamp(); + m_performanceCounters[counter] += TimeUtils::ExactDiff(m_runningPerformanceCounters.top(), timeStamp); m_runningPerformanceCounters.pop(); if (counter == PCNT_ALL) diff --git a/src/common/profiler.h b/src/common/profiler.h index 38956e70..0c3da2b1 100644 --- a/src/common/profiler.h +++ b/src/common/profiler.h @@ -73,7 +73,7 @@ private: static long long m_performanceCounters[PCNT_MAX]; static long long m_prevPerformanceCounters[PCNT_MAX]; - static std::stack m_runningPerformanceCounters; + static std::stack m_runningPerformanceCounters; static std::stack m_runningPerformanceCountersType; }; diff --git a/src/common/system/system.cpp b/src/common/system/system.cpp index d007fcb1..b21015d3 100644 --- a/src/common/system/system.cpp +++ b/src/common/system/system.cpp @@ -143,38 +143,11 @@ SystemDialogResult CSystemUtils::ConsoleSystemDialog(SystemDialogType type, cons return result; } -SystemTimeStamp CSystemUtils::GetCurrentTimeStamp() +TimeUtils::TimeStamp CSystemUtils::GetCurrentTimeStamp() { return std::chrono::high_resolution_clock::now(); } -SystemTimeStamp CSystemUtils::TimeStampLerp(SystemTimeStamp a, SystemTimeStamp b, float t) -{ - return a + std::chrono::duration_cast((b - a) * t); -} - -long long CSystemUtils::TimeStampExactDiff(SystemTimeStamp before, SystemTimeStamp after) -{ - return std::chrono::duration_cast(after - before).count(); -} - -float CSystemUtils::TimeStampDiff(SystemTimeStamp before, SystemTimeStamp after, SystemTimeUnit unit) -{ - long long exact = TimeStampExactDiff(before, after); - - float result = 0.0f; - if (unit == SystemTimeUnit::SECONDS) - result = exact * 1e-9; - else if (unit == SystemTimeUnit::MILLISECONDS) - result = exact * 1e-6; - else if (unit == SystemTimeUnit::MICROSECONDS) - result = exact * 1e-3; - else - assert(false); - - return result; -} - std::string CSystemUtils::GetBasePath() { if (m_basePath.empty()) diff --git a/src/common/system/system.h b/src/common/system/system.h index 1d0b31eb..b2399cf5 100644 --- a/src/common/system/system.h +++ b/src/common/system/system.h @@ -25,6 +25,7 @@ #pragma once #include "common/config.h" +#include "common/timeutils.h" #include #include @@ -63,19 +64,6 @@ enum class SystemDialogResult NO }; -/** - * \enum SystemTimeUnit - * \brief Time unit - */ -enum class SystemTimeUnit -{ - SECONDS, - MILLISECONDS, - MICROSECONDS -}; - -using SystemTimeStamp = std::chrono::time_point; - /** * \class CSystemUtils * \brief Platform-specific utils @@ -101,18 +89,7 @@ public: TEST_VIRTUAL SystemDialogResult ConsoleSystemDialog(SystemDialogType type, const std::string& title, const std::string& message); //! Returns a time stamp associated with current time - TEST_VIRTUAL SystemTimeStamp GetCurrentTimeStamp(); - - //! Linearly interpolates between two timestamps. - SystemTimeStamp TimeStampLerp(SystemTimeStamp a, SystemTimeStamp b, float t); - - //! Returns a difference between two timestamps in given time unit - /** The difference is \a after - \a before. */ - float TimeStampDiff(SystemTimeStamp before, SystemTimeStamp after, SystemTimeUnit unit = SystemTimeUnit::SECONDS); - - //! Returns the exact (in nanosecond units) difference between two timestamps - /** The difference is \a after - \a before. */ - long long TimeStampExactDiff(SystemTimeStamp before, SystemTimeStamp after); + TEST_VIRTUAL TimeUtils::TimeStamp GetCurrentTimeStamp(); //! Returns the path where the executable binary is located (ends with the path separator) virtual std::string GetBasePath(); @@ -142,5 +119,4 @@ public: private: std::string m_basePath; - std::vector> m_timeStamps; }; diff --git a/src/common/system/system_linux.cpp b/src/common/system/system_linux.cpp index 056e34ad..a5ef14c0 100644 --- a/src/common/system/system_linux.cpp +++ b/src/common/system/system_linux.cpp @@ -83,17 +83,6 @@ SystemDialogResult CSystemUtilsLinux::SystemDialog(SystemDialogType type, const return result; } -void CSystemUtilsLinux::GetCurrentTimeStamp(SystemTimeStamp *stamp) -{ - clock_gettime(CLOCK_MONOTONIC_RAW, &stamp->clockTime); -} - -long long CSystemUtilsLinux::TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) -{ - return (after->clockTime.tv_nsec - before->clockTime.tv_nsec) + - (after->clockTime.tv_sec - before->clockTime.tv_sec) * 1000000000ll; -} - std::string CSystemUtilsLinux::GetSaveDir() { #if PORTABLE_SAVES || DEV_BUILD diff --git a/src/common/timeutils.cpp b/src/common/timeutils.cpp new file mode 100644 index 00000000..96bcaa9c --- /dev/null +++ b/src/common/timeutils.cpp @@ -0,0 +1,54 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#include "common/timeutils.h" + +#include + +namespace TimeUtils +{ + +TimeStamp Lerp(TimeStamp a, TimeStamp b, float t) +{ + return a + std::chrono::duration_cast((b - a) * t); +} + +float Diff(TimeStamp before, TimeStamp after, TimeUnit unit) +{ + long long exact = ExactDiff(before, after); + + float result = 0.0f; + if (unit == TimeUnit::SECONDS) + result = exact * 1e-9; + else if (unit == TimeUnit::MILLISECONDS) + result = exact * 1e-6; + else if (unit == TimeUnit::MICROSECONDS) + result = exact * 1e-3; + else + assert(false); + + return result; +} + +long long ExactDiff(TimeStamp before, TimeStamp after) +{ + return std::chrono::duration_cast(after - before).count(); +} + +} // namespace TimeUtils diff --git a/src/common/timeutils.h b/src/common/timeutils.h new file mode 100644 index 00000000..5d67f4d7 --- /dev/null +++ b/src/common/timeutils.h @@ -0,0 +1,50 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2001-2021, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +/** + * \file common/timeutils.h + * \brief Some useful cross-platform operations on timestamps + */ + +#include + +namespace TimeUtils +{ + +enum class TimeUnit +{ + SECONDS, + MILLISECONDS, + MICROSECONDS +}; + +using TimeStamp = std::chrono::time_point; + +//! Linearly interpolates between two timestamps. +TimeStamp Lerp(TimeStamp a, TimeStamp b, float t); + +//! Returns a difference between two timestamps in given time unit +/** The difference is \a after - \a before. */ +float Diff(TimeStamp before, TimeStamp after, TimeUnit unit = TimeUnit::SECONDS); + +//! Returns the exact (in nanosecond units) difference between two timestamps +/** The difference is \a after - \a before. */ +long long ExactDiff(TimeStamp before, TimeStamp after); + +} // namespace TimeUtils diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 72cc69b4..f241f85d 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -63,6 +63,8 @@ #include #include +using TimeUtils::TimeUnit; + // Graphics module namespace namespace Gfx { @@ -3168,7 +3170,7 @@ void CEngine::Render() m_fpsCounter++; m_currentFrameTime = m_systemUtils->GetCurrentTimeStamp(); - float diff = m_systemUtils->TimeStampDiff(m_lastFrameTime, m_currentFrameTime, SystemTimeUnit::SECONDS); + float diff = TimeUtils::Diff(m_lastFrameTime, m_currentFrameTime, TimeUnit::SECONDS); if (diff > 1.0f) { m_lastFrameTime = m_currentFrameTime; diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index b652b3c3..db6eb8e1 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -1310,8 +1310,8 @@ protected: //! Last encountered error std::string m_error; - SystemTimeStamp m_lastFrameTime; - SystemTimeStamp m_currentFrameTime; + TimeUtils::TimeStamp m_lastFrameTime; + TimeUtils::TimeStamp m_currentFrameTime; int m_fpsCounter; float m_fps; diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index bcf187d0..b549229e 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -14,13 +14,12 @@ add_executable(colobot_ut CBot/CBotToken_test.cpp CBot/CBot_test.cpp common/config_file_test.cpp - common/system/system_test.cpp + common/timeutils_test.cpp graphics/engine/lightman_test.cpp math/func_test.cpp math/geometry_test.cpp math/matrix_test.cpp - math/vector_test.cpp -) + math/vector_test.cpp) target_include_directories(colobot_ut PRIVATE common diff --git a/test/unit/app/app_test.cpp b/test/unit/app/app_test.cpp index 22fc3eb4..549941c6 100644 --- a/test/unit/app/app_test.cpp +++ b/test/unit/app/app_test.cpp @@ -31,6 +31,7 @@ using namespace HippoMocks; namespace ph = std::placeholders; +using TimeUtils::TimeStamp; class CApplicationWrapper : public CApplication { @@ -47,7 +48,7 @@ public: SDL_Quit(); } - Event CreateUpdateEvent(SystemTimeStamp timestamp) override + Event CreateUpdateEvent(TimeStamp timestamp) override { return CApplication::CreateUpdateEvent(timestamp); } @@ -69,7 +70,7 @@ protected: void NextInstant(long long diff); - SystemTimeStamp GetCurrentTimeStamp(); + TimeStamp GetCurrentTimeStamp(); void TestCreateUpdateEvent(long long relTimeExact, long long absTimeExact, float relTime, float absTime, @@ -103,9 +104,9 @@ void CApplicationUT::TearDown() } -SystemTimeStamp CApplicationUT::GetCurrentTimeStamp() +TimeStamp CApplicationUT::GetCurrentTimeStamp() { - return SystemTimeStamp{SystemTimeStamp::duration{m_currentTime}}; + return TimeStamp{ TimeStamp::duration{m_currentTime}}; } void CApplicationUT::NextInstant(long long diff) @@ -117,7 +118,7 @@ void CApplicationUT::TestCreateUpdateEvent(long long relTimeExact, long long abs float relTime, float absTime, long long relTimeReal, long long absTimeReal) { - SystemTimeStamp now = GetCurrentTimeStamp(); + TimeStamp now = GetCurrentTimeStamp(); Event event = m_app->CreateUpdateEvent(now); EXPECT_EQ(EVENT_FRAME, event.type); EXPECT_FLOAT_EQ(relTime, event.rTime); diff --git a/test/unit/common/system/system_test.cpp b/test/unit/common/system/system_test.cpp deleted file mode 100644 index f78a4f98..00000000 --- a/test/unit/common/system/system_test.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * This file is part of the Colobot: Gold Edition source code - * Copyright (C) 2018, Daniel Roux, EPSITEC SA & TerranovaTeam - * http://epsitec.ch; http://colobot.info; http://github.com/colobot - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://gnu.org/licenses - */ - -#include "common/system/system_other.h" - -#include - -struct SystemTest : ::testing::Test -{ - CSystemUtilsOther system; -}; - -TEST_F(SystemTest, TimeStampExactDiff) -{ - auto epoch = SystemTimeStamp{}; - EXPECT_EQ(system.TimeStampExactDiff(epoch, epoch), 0); - - auto duration = std::chrono::microseconds{123456789L}; - auto before = std::chrono::high_resolution_clock::now(); - auto after = before + duration; - EXPECT_EQ(system.TimeStampExactDiff(before, after), std::chrono::nanoseconds{duration}.count()); - EXPECT_EQ(system.TimeStampExactDiff(after, before), -std::chrono::nanoseconds{duration}.count()); -} - -constexpr auto TIMESTAMP_START = SystemTimeStamp{std::chrono::nanoseconds{300}}; -constexpr auto TIMESTAMP_MID = SystemTimeStamp{std::chrono::nanoseconds{600}}; -constexpr auto TIMESTAMP_END = SystemTimeStamp{std::chrono::nanoseconds{900}}; - -constexpr auto LERP_PARAM_ZERO = 0.0f; -constexpr auto LERP_PARAM_HALF = 0.5f; -constexpr auto LERP_PARAM_ONE = 1.0f; - -TEST_F(SystemTest, TimeStampLerpReturnsStartWhenLerpParameterIsZero) -{ - EXPECT_EQ(TIMESTAMP_START, system.TimeStampLerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_ZERO)); -} - -TEST_F(SystemTest, TimeStampLerpReturnsEndWhenLerpParameterIsOne) -{ - EXPECT_EQ(TIMESTAMP_END, system.TimeStampLerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_ONE)); -} - -TEST_F(SystemTest, TimeStampLerpReturnsValueBetweenStartAndEndWhenLerpParameterIsBetweenZeroAndOne) -{ - EXPECT_EQ(TIMESTAMP_MID, system.TimeStampLerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_HALF)); -} - -TEST_F(SystemTest, TimeStampLerpIsMonotonic) -{ - constexpr auto deltaLerpParam = 0.1f; - auto earlierTimeStamp = system.TimeStampLerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_HALF - deltaLerpParam); - auto laterTimeStamp = system.TimeStampLerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_HALF + deltaLerpParam); - EXPECT_TRUE(earlierTimeStamp < laterTimeStamp); -} - -TEST_F(SystemTest, TimeStampLerpIsConsistent) -{ - auto timeStamp = TIMESTAMP_START; - EXPECT_EQ(timeStamp, system.TimeStampLerp(timeStamp, timeStamp, LERP_PARAM_ZERO)); - EXPECT_EQ(timeStamp, system.TimeStampLerp(timeStamp, timeStamp, LERP_PARAM_HALF)); - EXPECT_EQ(timeStamp, system.TimeStampLerp(timeStamp, timeStamp, LERP_PARAM_ONE)); -} - diff --git a/test/unit/common/timeutils_test.cpp b/test/unit/common/timeutils_test.cpp new file mode 100644 index 00000000..0f312a53 --- /dev/null +++ b/test/unit/common/timeutils_test.cpp @@ -0,0 +1,78 @@ +/* + * This file is part of the Colobot: Gold Edition source code + * Copyright (C) 2018-2021, Daniel Roux, EPSITEC SA & TerranovaTeam + * http://epsitec.ch; http://colobot.info; http://github.com/colobot + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see http://gnu.org/licenses + */ + +#include "common/timeutils.h" + +#include + +namespace TimeUtils +{ + +TEST(TimeUtilsExactDiffTest, ExactDiff) +{ + auto epoch = TimeStamp{}; + EXPECT_EQ(ExactDiff(epoch, epoch), 0); + + auto duration = std::chrono::microseconds{123456789L}; + auto before = std::chrono::high_resolution_clock::now(); + auto after = before + duration; + EXPECT_EQ(ExactDiff(before, after), std::chrono::nanoseconds{duration}.count()); + EXPECT_EQ(ExactDiff(after, before), -std::chrono::nanoseconds{duration}.count()); +} + +constexpr auto TIMESTAMP_START = TimeStamp{std::chrono::nanoseconds{300}}; +constexpr auto TIMESTAMP_MID = TimeStamp{std::chrono::nanoseconds{600}}; +constexpr auto TIMESTAMP_END = TimeStamp{std::chrono::nanoseconds{900}}; + +constexpr auto LERP_PARAM_ZERO = 0.0f; +constexpr auto LERP_PARAM_HALF = 0.5f; +constexpr auto LERP_PARAM_ONE = 1.0f; + +TEST(TimeUtilsLerpTest, LerpReturnsStartWhenLerpParameterIsZero) +{ + EXPECT_EQ(TIMESTAMP_START, Lerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_ZERO)); +} + +TEST(TimeUtilsLerpTest, LerpReturnsEndWhenLerpParameterIsOne) +{ + EXPECT_EQ(TIMESTAMP_END, Lerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_ONE)); +} + +TEST(TimeUtilsLerpTest, LerpReturnsValueBetweenStartAndEndWhenLerpParameterIsBetweenZeroAndOne) +{ + EXPECT_EQ(TIMESTAMP_MID, Lerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_HALF)); +} + +TEST(TimeUtilsLerpTest, LerpIsMonotonic) +{ + constexpr auto deltaLerpParam = 0.1f; + auto earlierTimeStamp = Lerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_HALF - deltaLerpParam); + auto laterTimeStamp = Lerp(TIMESTAMP_START, TIMESTAMP_END, LERP_PARAM_HALF + deltaLerpParam); + EXPECT_TRUE(earlierTimeStamp < laterTimeStamp); +} + +TEST(TimeUtilsLerpTest, LerpIsConsistent) +{ + auto timeStamp = TIMESTAMP_START; + EXPECT_EQ(timeStamp, Lerp(timeStamp, timeStamp, LERP_PARAM_ZERO)); + EXPECT_EQ(timeStamp, Lerp(timeStamp, timeStamp, LERP_PARAM_HALF)); + EXPECT_EQ(timeStamp, Lerp(timeStamp, timeStamp, LERP_PARAM_ONE)); +} + +} // namespace TimeUtils