Fixes after merge

Fix mistakes after previous merge and make it compile.

Rewrite the function interpolating between time stamps as it was
written after the original pull request was created. Add unit tests
for it.

I couldn't help myself and also changed some enums to enum classes and
did some renames.
fix-squashed-planets
MrSimbax 2021-09-11 12:44:26 +02:00
parent 2b107736e2
commit 5daaba6e64
15 changed files with 146 additions and 295 deletions

View File

@ -137,13 +137,6 @@ CApplication::CApplication(CSystemUtils* systemUtils)
m_absTime = 0.0f;
m_relTime = 0.0f;
m_baseTimeStamp = m_systemUtils->CreateTimeStamp();
m_curTimeStamp = m_systemUtils->CreateTimeStamp();
m_lastTimeStamp = m_systemUtils->CreateTimeStamp();
m_manualFrameLast = m_systemUtils->CreateTimeStamp();
m_manualFrameTime = m_systemUtils->CreateTimeStamp();
m_joystickEnabled = false;
@ -161,13 +154,6 @@ CApplication::CApplication(CSystemUtils* systemUtils)
CApplication::~CApplication()
{
m_systemUtils->DestroyTimeStamp(m_baseTimeStamp);
m_systemUtils->DestroyTimeStamp(m_curTimeStamp);
m_systemUtils->DestroyTimeStamp(m_lastTimeStamp);
m_systemUtils->DestroyTimeStamp(m_manualFrameLast);
m_systemUtils->DestroyTimeStamp(m_manualFrameTime);
m_joystickEnabled = false;
m_controller.reset();
@ -674,7 +660,7 @@ bool CApplication::Create()
{
GetLogger()->Error("Unknown graphics device: %s\n", graphics.c_str());
GetLogger()->Info("Changing to default device\n");
m_systemUtils->SystemDialog(SDT_ERROR, "Graphics initialization error", "You have selected invalid graphics device with -graphics switch. Game will use default OpenGL device instead.");
m_systemUtils->SystemDialog(SystemDialogType::ERROR, "Graphics initialization error", "You have selected invalid graphics device with -graphics switch. Game will use default OpenGL device instead.");
m_device = Gfx::CreateDevice(m_deviceConfig, "opengl");
}
}
@ -1057,9 +1043,9 @@ int CApplication::Run()
MoveMouse(Math::Point(0.5f, 0.5f)); // center mouse on start
SystemTimeStamp *previousTimeStamp = m_systemUtils->CreateTimeStamp();
SystemTimeStamp *currentTimeStamp = m_systemUtils->CreateTimeStamp();
SystemTimeStamp *interpolatedTimeStamp = m_systemUtils->CreateTimeStamp();
SystemTimeStamp previousTimeStamp{};
SystemTimeStamp currentTimeStamp{};
SystemTimeStamp interpolatedTimeStamp{};
while (true)
{
@ -1163,11 +1149,11 @@ int CApplication::Run()
// If game speed is increased then we do extra ticks per loop iteration to improve physics accuracy.
int numTickSlices = static_cast<int>(GetSimulationSpeed());
if(numTickSlices < 1) numTickSlices = 1;
m_systemUtils->CopyTimeStamp(previousTimeStamp, m_curTimeStamp);
m_systemUtils->GetCurrentTimeStamp(currentTimeStamp);
previousTimeStamp = m_curTimeStamp;
currentTimeStamp = m_systemUtils->GetCurrentTimeStamp();
for(int tickSlice = 0; tickSlice < numTickSlices; tickSlice++)
{
m_systemUtils->InterpolateTimeStamp(interpolatedTimeStamp, previousTimeStamp, currentTimeStamp, (tickSlice+1)/static_cast<float>(numTickSlices));
interpolatedTimeStamp = m_systemUtils->TimeStampLerp(previousTimeStamp, currentTimeStamp, (tickSlice+1)/static_cast<float>(numTickSlices));
Event event = CreateUpdateEvent(interpolatedTimeStamp);
if (event.type != EVENT_NULL && m_controller != nullptr)
{
@ -1198,9 +1184,6 @@ int CApplication::Run()
}
end:
m_systemUtils->DestroyTimeStamp(previousTimeStamp);
m_systemUtils->DestroyTimeStamp(currentTimeStamp);
m_systemUtils->DestroyTimeStamp(interpolatedTimeStamp);
return m_exitCode;
}
@ -1539,17 +1522,15 @@ void CApplication::StartLoadingMusic()
std::thread{[this]()
{
GetLogger()->Debug("Cache sounds...\n");
SystemTimeStamp* musicLoadStart = m_systemUtils->CreateTimeStamp();
m_systemUtils->GetCurrentTimeStamp(musicLoadStart);
SystemTimeStamp musicLoadStart{m_systemUtils->GetCurrentTimeStamp()};
m_sound->Reset();
m_sound->CacheAll();
SystemTimeStamp* musicLoadEnd = m_systemUtils->CreateTimeStamp();
m_systemUtils->GetCurrentTimeStamp(musicLoadEnd);
float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, STU_MSEC);
SystemTimeStamp musicLoadEnd{m_systemUtils->GetCurrentTimeStamp()};
float musicLoadTime = m_systemUtils->TimeStampDiff(musicLoadStart, musicLoadEnd, SystemTimeUnit::MILLISECONDS);
GetLogger()->Debug("Sound loading took %.2f ms\n", musicLoadTime);
}).detach();
}}.detach();
}
bool CApplication::GetSimulationSuspended() const
@ -1561,20 +1542,20 @@ void CApplication::SetSimulationSpeed(float speed)
{
m_simulationSpeed = speed;
m_systemUtils->CopyTimeStamp(m_baseTimeStamp, m_curTimeStamp);
m_baseTimeStamp = m_curTimeStamp;
m_realAbsTimeBase = m_realAbsTime;
m_absTimeBase = m_exactAbsTime;
GetLogger()->Info("Simulation speed = %.2f\n", speed);
}
Event CApplication::CreateUpdateEvent(SystemTimeStamp *newTimeStamp)
Event CApplication::CreateUpdateEvent(SystemTimeStamp newTimeStamp)
{
if (m_simulationSuspended)
return Event(EVENT_NULL);
m_systemUtils->CopyTimeStamp(m_lastTimeStamp, m_curTimeStamp);
m_systemUtils->CopyTimeStamp(m_curTimeStamp, newTimeStamp);
m_lastTimeStamp = m_curTimeStamp;
m_curTimeStamp = newTimeStamp;
long long absDiff = m_systemUtils->TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp);
long long newRealAbsTime = m_realAbsTimeBase + absDiff;

View File

@ -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(SystemTimeStamp newTimeStamp);
//! Logs debug data for event
void LogEvent(const Event& event);

View File

@ -177,7 +177,7 @@ int main(int argc, char *argv[])
ParseArgsStatus status = app.ParseArguments(argc, argv);
if (status == PARSE_ARGS_FAIL)
{
systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
systemUtils->SystemDialog(SystemDialogType::ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
return app.GetExitCode();
}
else if (status == PARSE_ARGS_HELP)
@ -190,7 +190,7 @@ int main(int argc, char *argv[])
code = app.GetExitCode();
if (code != 0 && !app.GetErrorMessage().empty())
{
systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app.GetErrorMessage());
systemUtils->SystemDialog(SystemDialogType::ERROR, "COLOBOT - Fatal Error", app.GetErrorMessage());
}
logger.Info("Didn't run main loop. Exiting with code %d\n", code);
return code;

View File

@ -162,7 +162,7 @@ void CSignalHandlers::ReportError(const std::string& errorMessage)
std::cerr << std::endl << msg.str() << std::endl;
m_systemUtils->SystemDialog(SDT_ERROR, "Unhandled exception occurred!", msg.str());
m_systemUtils->SystemDialog(SystemDialogType::ERROR, "Unhandled exception occurred!", msg.str());
if (canSave && !triedSaving)
{
@ -172,13 +172,13 @@ void CSignalHandlers::ReportError(const std::string& errorMessage)
msg << std::endl;
msg << "Do you want to try saving now?";
SystemDialogResult result = m_systemUtils->SystemDialog(SDT_YES_NO, "Try to save?", msg.str());
if (result == SDR_YES)
SystemDialogResult result = m_systemUtils->SystemDialog(SystemDialogType::YES_NO, "Try to save?", msg.str());
if (result == SystemDialogResult::YES)
{
triedSaving = true;
CResourceManager::CreateNewDirectory("crashsave");
robotMain->IOWriteScene("crashsave/data.sav", "crashsave/cbot.run", "crashsave/screen.png", "Backup at the moment of a crash", true);
m_systemUtils->SystemDialog(SDT_INFO, "Try to save?", "Saving finished.\nPlease restart the game now");
m_systemUtils->SystemDialog(SystemDialogType::INFO, "Try to save?", "Saving finished.\nPlease restart the game now");
}
}

View File

@ -61,17 +61,17 @@ SystemDialogResult CSystemUtils::ConsoleSystemDialog(SystemDialogType type, cons
{
switch (type)
{
case SDT_INFO:
case SystemDialogType::INFO:
std::cout << "INFO: ";
break;
case SDT_WARNING:
case SystemDialogType::WARNING:
std::cout << "WARNING:";
break;
case SDT_ERROR:
case SystemDialogType::ERROR:
std::cout << "ERROR: ";
break;
case SDT_YES_NO:
case SDT_OK_CANCEL:
case SystemDialogType::YES_NO:
case SystemDialogType::OK_CANCEL:
std::cout << "QUESTION: ";
break;
}
@ -80,24 +80,24 @@ SystemDialogResult CSystemUtils::ConsoleSystemDialog(SystemDialogType type, cons
std::string line;
SystemDialogResult result = SDR_OK;
auto result = SystemDialogResult::OK;
bool done = false;
while (!done)
{
switch (type)
{
case SDT_INFO:
case SDT_WARNING:
case SDT_ERROR:
case SystemDialogType::INFO:
case SystemDialogType::WARNING:
case SystemDialogType::ERROR:
std::cout << "Press ENTER to continue";
break;
case SDT_YES_NO:
case SystemDialogType::YES_NO:
std::cout << "Type 'Y' for Yes or 'N' for No";
break;
case SDT_OK_CANCEL:
case SystemDialogType::OK_CANCEL:
std::cout << "Type 'O' for OK or 'C' for Cancel";
break;
}
@ -106,35 +106,35 @@ SystemDialogResult CSystemUtils::ConsoleSystemDialog(SystemDialogType type, cons
switch (type)
{
case SDT_INFO:
case SDT_WARNING:
case SDT_ERROR:
case SystemDialogType::INFO:
case SystemDialogType::WARNING:
case SystemDialogType::ERROR:
done = true;
break;
case SDT_YES_NO:
case SystemDialogType::YES_NO:
if (line == "Y" || line == "y")
{
result = SDR_YES;
result = SystemDialogResult::YES;
done = true;
}
else if (line == "N" || line == "n")
{
result = SDR_NO;
result = SystemDialogResult::NO;
done = true;
}
break;
case SDT_OK_CANCEL:
case SystemDialogType::OK_CANCEL:
if (line == "O" || line == "o")
{
done = true;
result = SDR_OK;
result = SystemDialogResult::OK;
}
else if (line == "C" || line == "c")
{
done = true;
result = SDR_CANCEL;
result = SystemDialogResult::CANCEL;
}
break;
}
@ -148,6 +148,11 @@ SystemTimeStamp CSystemUtils::GetCurrentTimeStamp()
return std::chrono::high_resolution_clock::now();
}
SystemTimeStamp CSystemUtils::TimeStampLerp(SystemTimeStamp a, SystemTimeStamp b, float t)
{
return a + std::chrono::duration_cast<SystemTimeStamp::duration>((b - a) * t);
}
long long CSystemUtils::TimeStampExactDiff(SystemTimeStamp before, SystemTimeStamp after)
{
return std::chrono::duration_cast<std::chrono::nanoseconds>(after - before).count();
@ -158,11 +163,11 @@ float CSystemUtils::TimeStampDiff(SystemTimeStamp before, SystemTimeStamp after,
long long exact = TimeStampExactDiff(before, after);
float result = 0.0f;
if (unit == STU_SEC)
if (unit == SystemTimeUnit::SECONDS)
result = exact * 1e-9;
else if (unit == STU_MSEC)
else if (unit == SystemTimeUnit::MILLISECONDS)
result = exact * 1e-6;
else if (unit == STU_USEC)
else if (unit == SystemTimeUnit::MICROSECONDS)
result = exact * 1e-3;
else
assert(false);

View File

@ -35,18 +35,18 @@
* \enum SystemDialogType
* \brief Type of system dialog
*/
enum SystemDialogType
enum class SystemDialogType
{
//! Information message
SDT_INFO,
INFO,
//! Warning message
SDT_WARNING,
WARNING,
//! Error message
SDT_ERROR,
ERROR,
//! Yes/No question
SDT_YES_NO,
YES_NO,
//! Ok/Cancel question
SDT_OK_CANCEL
OK_CANCEL
};
/**
@ -55,26 +55,23 @@ enum SystemDialogType
*
* Means which button was pressed.
*/
enum SystemDialogResult
enum class SystemDialogResult
{
SDR_OK,
SDR_CANCEL,
SDR_YES,
SDR_NO
OK,
CANCEL,
YES,
NO
};
/**
* \enum SystemTimeUnit
* \brief Time unit
*/
enum SystemTimeUnit
enum class SystemTimeUnit
{
//! seconds
STU_SEC,
//! milliseconds
STU_MSEC,
//! microseconds
STU_USEC
SECONDS,
MILLISECONDS,
MICROSECONDS
};
using SystemTimeStamp = std::chrono::time_point<std::chrono::high_resolution_clock>;
@ -103,20 +100,23 @@ public:
//! Displays a fallback system dialog using console
TEST_VIRTUAL SystemDialogResult ConsoleSystemDialog(SystemDialogType type, const std::string& title, const std::string& message);
//! Interpolates between two timestamps. If i=0 then dst=a. If i=1 then dst=b. If i=0.5 then dst is halfway between.
virtual void InterpolateTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *a, SystemTimeStamp *b, float i) = 0;
//! 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 = STU_SEC);
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);
//! Returns the path where the executable binary is located (ends with the path separator)
virtual std::string GetBasePath();
//! Returns the data path (containing textures, levels, helpfiles, etc)
virtual std::string GetDataPath();

View File

@ -46,20 +46,20 @@ SystemDialogResult CSystemUtilsLinux::SystemDialog(SystemDialogType type, const
std::string options = "";
switch (type)
{
case SDT_INFO:
case SystemDialogType::INFO:
default:
options = "--info";
break;
case SDT_WARNING:
case SystemDialogType::WARNING:
options = "--warning";
break;
case SDT_ERROR:
case SystemDialogType::ERROR:
options = "--error";
break;
case SDT_YES_NO:
case SystemDialogType::YES_NO:
options = "--question --ok-label=\"Yes\" --cancel-label=\"No\"";
break;
case SDT_OK_CANCEL:
case SystemDialogType::OK_CANCEL:
options = "--question --ok-label=\"OK\" --cancel-label=\"Cancel\"";
break;
}
@ -67,14 +67,14 @@ SystemDialogResult CSystemUtilsLinux::SystemDialog(SystemDialogType type, const
std::string command = "zenity " + options + " --text=\"" + message + "\" --title=\"" + title + "\"";
int code = system(command.c_str());
SystemDialogResult result = SDR_OK;
SystemDialogResult result = SystemDialogResult::OK;
switch (type)
{
case SDT_YES_NO:
result = code ? SDR_NO : SDR_YES;
case SystemDialogType::YES_NO:
result = code ? SystemDialogResult::NO : SystemDialogResult::YES;
break;
case SDT_OK_CANCEL:
result = code ? SDR_CANCEL : SDR_OK;
case SystemDialogType::OK_CANCEL:
result = code ? SystemDialogResult::CANCEL : SystemDialogResult::OK;
break;
default:
break;
@ -83,19 +83,6 @@ SystemDialogResult CSystemUtilsLinux::SystemDialog(SystemDialogType type, const
return result;
}
void CSystemUtilsLinux::InterpolateTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *a, SystemTimeStamp *b, float i)
{
long long delta = TimeStampExactDiff(a, b);
delta *= i; // truncates
dst->clockTime.tv_sec = a->clockTime.tv_sec + delta / 1000000000;
dst->clockTime.tv_nsec = a->clockTime.tv_nsec + delta % 1000000000;
if(dst->clockTime.tv_nsec >= 1000000000)
{
dst->clockTime.tv_nsec -= 1000000000;
dst->clockTime.tv_sec++;
}
}
void CSystemUtilsLinux::GetCurrentTimeStamp(SystemTimeStamp *stamp)
{
clock_gettime(CLOCK_MONOTONIC_RAW, &stamp->clockTime);

View File

@ -24,8 +24,6 @@
#include "common/system/system.h"
#include <sys/time.h>
//@colobot-lint-exclude UndefinedFunctionRule
class CSystemUtilsLinux : public CSystemUtils
@ -35,8 +33,6 @@ public:
SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
void InterpolateTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *a, SystemTimeStamp *b, float i) override;
std::string GetSaveDir() override;
std::string GetEnvVar(const std::string& name) override;

View File

@ -37,20 +37,24 @@ SystemDialogResult CSystemUtilsWindows::SystemDialog(SystemDialogType type, cons
switch (type)
{
case SDT_INFO:
case SystemDialogType::INFO:
default:
windowsType = MB_ICONINFORMATION|MB_OK;
break;
case SDT_WARNING:
case SystemDialogType::WARNING:
windowsType = MB_ICONWARNING|MB_OK;
break;
case SDT_ERROR:
// windows.h defines ERROR which collides with the enum name
#pragma push_macro("ERROR")
#undef ERROR
case SystemDialogType::ERROR:
#pragma pop_macro("ERROR")
windowsType = MB_ICONERROR|MB_OK;
break;
case SDT_YES_NO:
case SystemDialogType::YES_NO:
windowsType = MB_ICONQUESTION|MB_YESNO;
break;
case SDT_OK_CANCEL:
case SystemDialogType::OK_CANCEL:
windowsType = MB_ICONWARNING|MB_OKCANCEL;
break;
}
@ -58,18 +62,18 @@ SystemDialogResult CSystemUtilsWindows::SystemDialog(SystemDialogType type, cons
switch (MessageBoxW(nullptr, windowsMessage.c_str(), windowsTitle.c_str(), windowsType))
{
case IDOK:
return SDR_OK;
return SystemDialogResult::OK;
case IDCANCEL:
return SDR_CANCEL;
return SystemDialogResult::CANCEL;
case IDYES:
return SDR_YES;
return SystemDialogResult::YES;
case IDNO:
return SDR_NO;
return SystemDialogResult::NO;
default:
break;
}
return SDR_OK;
return SystemDialogResult::OK;
}
//! Converts a wide Unicode string to an UTF8 string

View File

@ -3168,7 +3168,7 @@ void CEngine::Render()
m_fpsCounter++;
m_currentFrameTime = m_systemUtils->GetCurrentTimeStamp();
float diff = m_systemUtils->TimeStampDiff(m_lastFrameTime, m_currentFrameTime, STU_SEC);
float diff = m_systemUtils->TimeStampDiff(m_lastFrameTime, m_currentFrameTime, SystemTimeUnit::SECONDS);
if (diff > 1.0f)
{
m_lastFrameTime = m_currentFrameTime;

View File

@ -1,10 +1,3 @@
# Platform-dependent tests
if(PLATFORM_WINDOWS)
set(PLATFORM_TESTS common/system/system_windows_test.cpp)
elseif(PLATFORM_LINUX)
set(PLATFORM_TESTS common/system/system_linux_test.cpp)
endif()
set(TEST_FILES
common/colobot.ini
)
@ -21,6 +14,7 @@ add_executable(colobot_ut
CBot/CBotToken_test.cpp
CBot/CBot_test.cpp
common/config_file_test.cpp
common/system/system_test.cpp
graphics/engine/lightman_test.cpp
math/func_test.cpp
math/geometry_test.cpp
@ -28,13 +22,6 @@ add_executable(colobot_ut
math/vector_test.cpp
)
# Platform-dependent tests
if(PLATFORM_WINDOWS)
target_sources(colobot_ut PRIVATE common/system/system_windows_test.cpp)
elseif(PLATFORM_LINUX)
target_sources(colobot_ut PRIVATE common/system/system_linux_test.cpp)
endif()
target_include_directories(colobot_ut PRIVATE
common
math

View File

@ -47,7 +47,7 @@ public:
SDL_Quit();
}
Event CreateUpdateEvent(SystemTimeStamp *timestamp) override
Event CreateUpdateEvent(SystemTimeStamp timestamp) override
{
return CApplication::CreateUpdateEvent(timestamp);
}
@ -117,8 +117,7 @@ void CApplicationUT::TestCreateUpdateEvent(long long relTimeExact, long long abs
float relTime, float absTime,
long long relTimeReal, long long absTimeReal)
{
SystemTimeStamp *now = CreateTimeStamp();
GetCurrentTimeStamp(now);
SystemTimeStamp now = GetCurrentTimeStamp();
Event event = m_app->CreateUpdateEvent(now);
EXPECT_EQ(EVENT_FRAME, event.type);
EXPECT_FLOAT_EQ(relTime, event.rTime);
@ -135,9 +134,7 @@ TEST_F(CApplicationUT, UpdateEventTimeCalculation_SimulationSuspended)
{
m_app->SuspendSimulation();
SystemTimeStamp *now = CreateTimeStamp();
GetCurrentTimeStamp(now);
Event event = m_app->CreateUpdateEvent(now);
Event event = m_app->CreateUpdateEvent(GetCurrentTimeStamp());
EXPECT_EQ(EVENT_NULL, event.type);
}
@ -190,9 +187,7 @@ TEST_F(CApplicationUT, UpdateEventTimeCalculation_NegativeTimeOperation)
NextInstant(-1111);
SystemTimeStamp *now = CreateTimeStamp();
GetCurrentTimeStamp(now);
Event event = m_app->CreateUpdateEvent(now);
Event event = m_app->CreateUpdateEvent(GetCurrentTimeStamp());
EXPECT_EQ(EVENT_NULL, event.type);
}

View File

@ -1,77 +0,0 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2020, 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.h"
#include "common/system/system_linux.h"
#include <gtest/gtest.h>
class CSystemUtilsLinuxUT : public testing::Test
{
protected:
static const long long SEC = 1000000000;
CSystemUtilsLinux m_systemUtils;
};
TEST_F(CSystemUtilsLinuxUT, TimeStampDiff)
{
SystemTimeStamp before, after;
before.clockTime.tv_sec = 1;
before.clockTime.tv_nsec = 100;
after.clockTime.tv_sec = 1;
after.clockTime.tv_nsec = 900;
long long tDiff = m_systemUtils.TimeStampExactDiff(&before, &after);
EXPECT_EQ( 800, tDiff);
tDiff = m_systemUtils.TimeStampExactDiff(&after, &before);
EXPECT_EQ(-800, tDiff);
// -------
before.clockTime.tv_sec = 2;
before.clockTime.tv_nsec = 200;
after.clockTime.tv_sec = 3;
after.clockTime.tv_nsec = 500;
tDiff = m_systemUtils.TimeStampExactDiff(&before, &after);
EXPECT_EQ( SEC + 300, tDiff);
tDiff = m_systemUtils.TimeStampExactDiff(&after, &before);
EXPECT_EQ(-SEC - 300, tDiff);
// -------
before.clockTime.tv_sec = 3;
before.clockTime.tv_nsec = 200;
after.clockTime.tv_sec = 4;
after.clockTime.tv_nsec = 100;
tDiff = m_systemUtils.TimeStampExactDiff(&before, &after);
EXPECT_EQ( SEC - 100, tDiff);
tDiff = m_systemUtils.TimeStampExactDiff(&after, &before);
EXPECT_EQ(-SEC + 100, tDiff);
}

View File

@ -21,11 +21,13 @@
#include <gtest/gtest.h>
struct SystemTest : ::testing::Test {
struct SystemTest : ::testing::Test
{
CSystemUtilsOther system;
};
TEST_F(SystemTest, TimeStampExactDiff) {
TEST_F(SystemTest, TimeStampExactDiff)
{
auto epoch = SystemTimeStamp{};
EXPECT_EQ(system.TimeStampExactDiff(epoch, epoch), 0);
@ -35,3 +37,43 @@ TEST_F(SystemTest, TimeStampExactDiff) {
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));
}

View File

@ -1,69 +0,0 @@
/*
* This file is part of the Colobot: Gold Edition source code
* Copyright (C) 2001-2020, 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.h"
#include "common/system/system_windows.h"
#include <gtest/gtest.h>
class CSystemUtilsWindowsWrapper : public CSystemUtilsWindows
{
public:
void SetFrequency(long long frequency)
{
m_counterFrequency = frequency;
}
};
class CSystemUtilsWindowsUT : public testing::Test
{
protected:
static const long long SEC = 1000000000;
CSystemUtilsWindowsWrapper m_systemUtils;
};
TEST_F(CSystemUtilsWindowsUT, TimeStampDiff)
{
m_systemUtils.SetFrequency(SEC);
SystemTimeStamp before, after;
before.counterValue = 100;
after.counterValue = 200;
long long tDiff = m_systemUtils.TimeStampExactDiff(&before, &after);
EXPECT_EQ( 100, tDiff);
tDiff = m_systemUtils.TimeStampExactDiff(&after, &before);
EXPECT_EQ(-100, tDiff);
// -------
m_systemUtils.SetFrequency(SEC/3);
before.counterValue = 200;
after.counterValue = 400;
tDiff = m_systemUtils.TimeStampExactDiff(&before, &after);
EXPECT_EQ( 200*3, tDiff);
tDiff = m_systemUtils.TimeStampExactDiff(&after, &before);
EXPECT_EQ(-200*3, tDiff);
}