summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt43
-rw-r--r--cmake/msys.cmake12
-rw-r--r--cmake/mxe.cmake3
-rw-r--r--src/CMakeLists.txt4
-rw-r--r--src/app/app.cpp133
-rw-r--r--src/app/app.h2
-rw-r--r--src/app/main.cpp32
-rw-r--r--src/app/system.cpp185
-rw-r--r--src/app/system.h90
-rw-r--r--src/app/system_linux.cpp25
-rw-r--r--src/app/system_linux.h16
-rw-r--r--src/app/system_other.cpp93
-rw-r--r--src/app/system_other.h13
-rw-r--r--src/app/system_windows.cpp64
-rw-r--r--src/app/system_windows.h29
-rw-r--r--src/graphics/engine/engine.cpp18
-rw-r--r--test/envs/opengl/CMakeLists.txt4
-rw-r--r--test/envs/opengl/light_test.cpp18
-rw-r--r--test/envs/opengl/model_test.cpp18
-rw-r--r--test/envs/opengl/transform_test.cpp18
-rw-r--r--test/unit/CMakeLists.txt13
-rw-r--r--test/unit/app/app_test.cpp320
-rw-r--r--test/unit/app/system_linux_test.cpp29
-rw-r--r--test/unit/app/system_mock.h48
-rw-r--r--test/unit/app/system_windows_test.cpp62
-rw-r--r--test/unit/graphics/engine/lightman_test.cpp6
-rw-r--r--test/unit/ui/stubs/app_stub.cpp5
27 files changed, 916 insertions, 387 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 607df20..48a47bb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,14 +94,6 @@ option(INSTALL_DOCS "Install Doxygen-generated documentation" OFF)
option(OPENAL_SOUND "Build openal sound support" OFF)
-# Hacks for MSYS
-if (MSYS)
- set(COLOBOT_CXX_FLAGS "${COLOBOT_CXX_FLAGS} -U__STRICT_ANSI__") # fixes putenv()
- set(USE_SDL_MAIN 1) # fixes SDL_main
- set(DESKTOP OFF) # MSYS doesn't have the necessary tools
-endif()
-
-
##
# Searching for packages
##
@@ -132,34 +124,23 @@ endif()
##
-# Additional settings to use when cross-compiling with MXE (http://mxe.cc/)
-##
-
-include("${colobot_SOURCE_DIR}/cmake/mxe.cmake")
-
-
-##
# Platform detection and some related checks
##
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
- message(STATUS "Windows system detected")
set(PLATFORM_WINDOWS 1)
set(PLATFORM_LINUX 0)
set(PLATFORM_OTHER 0)
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
- message(STATUS "Linux system detected")
set(PLATFORM_WINDOWS 0)
set(PLATFORM_LINUX 1)
set(PLATFORM_OTHER 0)
else()
- message(STATUS "Other system detected")
set(PLATFORM_WINDOWS 0)
set(PLATFORM_LINUX 0)
set(PLATFORM_OTHER 1)
endif()
-
if(NOT ${ASSERTS})
add_definitions(-DNDEBUG)
endif()
@@ -172,6 +153,30 @@ endif()
##
+# Additional settings to use when cross-compiling with MXE (http://mxe.cc/)
+##
+
+include("${colobot_SOURCE_DIR}/cmake/mxe.cmake")
+
+##
+# Additional settings for MSYS
+##
+include("${colobot_SOURCE_DIR}/cmake/msys.cmake")
+
+
+##
+# Summary of detected things
+##
+if (${PLATFORM_WINDOWS})
+ message(STATUS "Build for Windows system")
+elseif(${PLATFORM_LINUX})
+ message(STATUS "Build for Linux system")
+else()
+ message(STATUS "Build for other system")
+endif()
+
+
+##
# Doxygen docs
##
diff --git a/cmake/msys.cmake b/cmake/msys.cmake
new file mode 100644
index 0000000..26b25b2
--- /dev/null
+++ b/cmake/msys.cmake
@@ -0,0 +1,12 @@
+# Hacks for MSYS
+if (MSYS AND (NOT MXE))
+ message(STATUS "Detected MSYS build")
+
+ set(PLATFORM_WINDOWS 1)
+ set(PLATFORM_LINUX 0)
+ set(PLATFORM_OTHER 0)
+
+ set(COLOBOT_CXX_FLAGS "${COLOBOT_CXX_FLAGS} -U__STRICT_ANSI__") # fixes putenv()
+ set(USE_SDL_MAIN 1) # fixes SDL_main
+ set(DESKTOP OFF) # MSYS doesn't have the necessary tools
+endif()
diff --git a/cmake/mxe.cmake b/cmake/mxe.cmake
index 5502c1b..9bb38d0 100644
--- a/cmake/mxe.cmake
+++ b/cmake/mxe.cmake
@@ -4,6 +4,9 @@
if((${CMAKE_CROSSCOMPILING}) AND (DEFINED MSYS))
message(STATUS "Detected MXE build")
set(MXE 1)
+ set(PLATFORM_WINDOWS 1)
+ set(PLATFORM_LINUX 0)
+ set(PLATFORM_OTHER 0)
# Because some tests will not compile
set(TESTS OFF)
# All must be static, CBOT and GLEW too
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3d6908d..de60ef3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -52,9 +52,9 @@ if (${OPENAL_SOUND})
endif()
# Platform-dependent implementation of system.h
-if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+if (${PLATFORM_WINDOWS})
set(SYSTEM_CPP_MODULE "system_windows.cpp")
-elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+elseif(${PLATFORM_LINUX})
set(SYSTEM_CPP_MODULE "system_linux.cpp")
else()
set(SYSTEM_CPP_MODULE "system_other.cpp")
diff --git a/src/app/app.cpp b/src/app/app.cpp
index e84091b..9349cbf 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -125,14 +125,14 @@ CApplication::CApplication()
m_absTime = 0.0f;
m_relTime = 0.0f;
- m_baseTimeStamp = CreateTimeStamp();
- m_curTimeStamp = CreateTimeStamp();
- m_lastTimeStamp = CreateTimeStamp();
+ m_baseTimeStamp = GetSystemUtils()->CreateTimeStamp();
+ m_curTimeStamp = GetSystemUtils()->CreateTimeStamp();
+ m_lastTimeStamp = GetSystemUtils()->CreateTimeStamp();
for (int i = 0; i < PCNT_MAX; ++i)
{
- m_performanceCounters[i][0] = CreateTimeStamp();
- m_performanceCounters[i][1] = CreateTimeStamp();
+ m_performanceCounters[i][0] = GetSystemUtils()->CreateTimeStamp();
+ m_performanceCounters[i][1] = GetSystemUtils()->CreateTimeStamp();
}
m_joystickEnabled = false;
@@ -177,14 +177,14 @@ CApplication::~CApplication()
delete m_iMan;
m_iMan = nullptr;
- DestroyTimeStamp(m_baseTimeStamp);
- DestroyTimeStamp(m_curTimeStamp);
- DestroyTimeStamp(m_lastTimeStamp);
+ GetSystemUtils()->DestroyTimeStamp(m_baseTimeStamp);
+ GetSystemUtils()->DestroyTimeStamp(m_curTimeStamp);
+ GetSystemUtils()->DestroyTimeStamp(m_lastTimeStamp);
for (int i = 0; i < PCNT_MAX; ++i)
{
- DestroyTimeStamp(m_performanceCounters[i][0]);
- DestroyTimeStamp(m_performanceCounters[i][1]);
+ GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][0]);
+ GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][1]);
}
}
@@ -199,8 +199,8 @@ CSoundInterface* CApplication::GetSound()
for (int i = 0; i < PCNT_MAX; ++i)
{
- DestroyTimeStamp(m_performanceCounters[i][0]);
- DestroyTimeStamp(m_performanceCounters[i][1]);
+ GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][0]);
+ GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][1]);
}
}
@@ -607,7 +607,7 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig)
std::string(SDL_GetError()) + std::string("\n") +
std::string("Previous mode will be restored");
GetLogger()->Error(error.c_str());
- SystemDialog( SDT_ERROR, "COLOBT - Error", error);
+ GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Error", error);
restore = true;
ChangeVideoConfig(m_lastDeviceConfig);
@@ -620,7 +620,7 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig)
std::string error = std::string("SDL error while restoring previous video mode:\n") +
std::string(SDL_GetError());
GetLogger()->Error(error.c_str());
- SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error);
+ GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error);
// Fatal error, so post the quit event
@@ -755,9 +755,9 @@ int CApplication::Run()
{
m_active = true;
- GetCurrentTimeStamp(m_baseTimeStamp);
- GetCurrentTimeStamp(m_lastTimeStamp);
- GetCurrentTimeStamp(m_curTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_lastTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_curTimeStamp);
MoveMouse(Math::Point(0.5f, 0.5f)); // center mouse on start
@@ -1109,49 +1109,49 @@ bool CApplication::ProcessEvent(const Event &event)
{
case EVENT_KEY_DOWN:
case EVENT_KEY_UP:
- l->Info("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP");
- l->Info(" virt = %s\n", (event.key.virt) ? "true" : "false");
- l->Info(" key = %d\n", event.key.key);
- l->Info(" unicode = 0x%04x\n", event.key.unicode);
+ l->Trace("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP");
+ l->Trace(" virt = %s\n", (event.key.virt) ? "true" : "false");
+ l->Trace(" key = %d\n", event.key.key);
+ l->Trace(" unicode = 0x%04x\n", event.key.unicode);
break;
case EVENT_MOUSE_MOVE:
- l->Info("EVENT_MOUSE_MOVE:\n");
+ l->Trace("EVENT_MOUSE_MOVE:\n");
break;
case EVENT_MOUSE_BUTTON_DOWN:
case EVENT_MOUSE_BUTTON_UP:
- l->Info("EVENT_MOUSE_BUTTON_%s:\n", (event.type == EVENT_MOUSE_BUTTON_DOWN) ? "DOWN" : "UP");
- l->Info(" button = %d\n", event.mouseButton.button);
+ l->Trace("EVENT_MOUSE_BUTTON_%s:\n", (event.type == EVENT_MOUSE_BUTTON_DOWN) ? "DOWN" : "UP");
+ l->Trace(" button = %d\n", event.mouseButton.button);
break;
case EVENT_MOUSE_WHEEL:
- l->Info("EVENT_MOUSE_WHEEL:\n");
- l->Info(" dir = %s\n", (event.mouseWheel.dir == WHEEL_DOWN) ? "WHEEL_DOWN" : "WHEEL_UP");
+ l->Trace("EVENT_MOUSE_WHEEL:\n");
+ l->Trace(" dir = %s\n", (event.mouseWheel.dir == WHEEL_DOWN) ? "WHEEL_DOWN" : "WHEEL_UP");
break;
case EVENT_JOY_AXIS:
- l->Info("EVENT_JOY_AXIS:\n");
- l->Info(" axis = %d\n", event.joyAxis.axis);
- l->Info(" value = %d\n", event.joyAxis.value);
+ l->Trace("EVENT_JOY_AXIS:\n");
+ l->Trace(" axis = %d\n", event.joyAxis.axis);
+ l->Trace(" value = %d\n", event.joyAxis.value);
break;
case EVENT_JOY_BUTTON_DOWN:
case EVENT_JOY_BUTTON_UP:
- l->Info("EVENT_JOY_BUTTON_%s:\n", (event.type == EVENT_JOY_BUTTON_DOWN) ? "DOWN" : "UP");
- l->Info(" button = %d\n", event.joyButton.button);
+ l->Trace("EVENT_JOY_BUTTON_%s:\n", (event.type == EVENT_JOY_BUTTON_DOWN) ? "DOWN" : "UP");
+ l->Trace(" button = %d\n", event.joyButton.button);
break;
case EVENT_ACTIVE:
- l->Info("EVENT_ACTIVE:\n");
- l->Info(" flags = 0x%x\n", event.active.flags);
- l->Info(" gain = %s\n", event.active.gain ? "true" : "false");
+ l->Trace("EVENT_ACTIVE:\n");
+ l->Trace(" flags = 0x%x\n", event.active.flags);
+ l->Trace(" gain = %s\n", event.active.gain ? "true" : "false");
break;
default:
- l->Info("Event type = %d:\n", static_cast<int>(event.type));
+ l->Trace("Event type = %d:\n", static_cast<int>(event.type));
break;
}
- l->Info(" systemEvent = %s\n", event.systemEvent ? "true" : "false");
- l->Info(" rTime = %f\n", event.rTime);
- l->Info(" kmodState = %04x\n", event.kmodState);
- l->Info(" trackedKeysState = %04x\n", event.trackedKeysState);
- l->Info(" mousePos = %f, %f\n", event.mousePos.x, event.mousePos.y);
- l->Info(" mouseButtonsState = %02x\n", event.mouseButtonsState);
+ l->Trace(" systemEvent = %s\n", event.systemEvent ? "true" : "false");
+ l->Trace(" rTime = %f\n", event.rTime);
+ l->Trace(" kmodState = %04x\n", event.kmodState);
+ l->Trace(" trackedKeysState = %04x\n", event.trackedKeysState);
+ l->Trace(" mousePos = %f, %f\n", event.mousePos.x, event.mousePos.y);
+ l->Trace(" mouseButtonsState = %02x\n", event.mouseButtonsState);
}
// By default, pass on all events
@@ -1219,8 +1219,8 @@ void CApplication::ResumeSimulation()
{
m_simulationSuspended = false;
- GetCurrentTimeStamp(m_baseTimeStamp);
- CopyTimeStamp(m_curTimeStamp, m_baseTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp);
+ GetSystemUtils()->CopyTimeStamp(m_curTimeStamp, m_baseTimeStamp);
m_realAbsTimeBase = m_realAbsTime;
m_absTimeBase = m_exactAbsTime;
@@ -1236,7 +1236,7 @@ void CApplication::SetSimulationSpeed(float speed)
{
m_simulationSpeed = speed;
- GetCurrentTimeStamp(m_baseTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp);
m_realAbsTimeBase = m_realAbsTime;
m_absTimeBase = m_exactAbsTime;
@@ -1248,18 +1248,31 @@ Event CApplication::CreateUpdateEvent()
if (m_simulationSuspended)
return Event(EVENT_NULL);
- CopyTimeStamp(m_lastTimeStamp, m_curTimeStamp);
- GetCurrentTimeStamp(m_curTimeStamp);
+ GetSystemUtils()->CopyTimeStamp(m_lastTimeStamp, m_curTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_curTimeStamp);
- long long absDiff = TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp);
- m_realAbsTime = m_realAbsTimeBase + absDiff;
- // m_baseTimeStamp is updated on simulation speed change, so this is OK
- m_exactAbsTime = m_absTimeBase + m_simulationSpeed * absDiff;
- m_absTime = (m_absTimeBase + m_simulationSpeed * absDiff) / 1e9f;
+ long long absDiff = GetSystemUtils()->TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp);
+ long long newRealAbsTime = m_realAbsTimeBase + absDiff;
+ long long newRealRelTime = GetSystemUtils()->TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp);
- m_realRelTime = TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp);
- m_exactRelTime = m_simulationSpeed * m_realRelTime;
- m_relTime = (m_simulationSpeed * m_realRelTime) / 1e9f;
+ if (newRealAbsTime < m_realAbsTime || newRealRelTime < 0)
+ {
+ GetLogger()->Error("Fatal error: got negative system counter difference!\n");
+ GetLogger()->Error("This should never happen. Please report this error.\n");
+ m_eventQueue->AddEvent(Event(EVENT_QUIT));
+ return Event(EVENT_NULL);
+ }
+ else
+ {
+ m_realAbsTime = newRealAbsTime;
+ // m_baseTimeStamp is updated on simulation speed change, so this is OK
+ m_exactAbsTime = m_absTimeBase + m_simulationSpeed * absDiff;
+ m_absTime = (m_absTimeBase + m_simulationSpeed * absDiff) / 1e9f;
+
+ m_realRelTime = newRealRelTime;
+ m_exactRelTime = m_simulationSpeed * m_realRelTime;
+ m_relTime = (m_simulationSpeed * m_realRelTime) / 1e9f;
+ }
Event frameEvent(EVENT_FRAME);
frameEvent.systemEvent = true;
@@ -1651,12 +1664,12 @@ bool CApplication::GetLowCPU()
void CApplication::StartPerformanceCounter(PerformanceCounter counter)
{
- GetCurrentTimeStamp(m_performanceCounters[counter][0]);
+ GetSystemUtils()->GetCurrentTimeStamp(m_performanceCounters[counter][0]);
}
void CApplication::StopPerformanceCounter(PerformanceCounter counter)
{
- GetCurrentTimeStamp(m_performanceCounters[counter][1]);
+ GetSystemUtils()->GetCurrentTimeStamp(m_performanceCounters[counter][1]);
}
float CApplication::GetPerformanceCounterData(PerformanceCounter counter)
@@ -1675,13 +1688,13 @@ void CApplication::ResetPerformanceCounters()
void CApplication::UpdatePerformanceCountersData()
{
- long long sum = TimeStampExactDiff(m_performanceCounters[PCNT_ALL][0],
- m_performanceCounters[PCNT_ALL][1]);
+ long long sum = GetSystemUtils()->TimeStampExactDiff(m_performanceCounters[PCNT_ALL][0],
+ m_performanceCounters[PCNT_ALL][1]);
for (int i = 0; i < PCNT_MAX; ++i)
{
- long long diff = TimeStampExactDiff(m_performanceCounters[i][0],
- m_performanceCounters[i][1]);
+ long long diff = GetSystemUtils()->TimeStampExactDiff(m_performanceCounters[i][0],
+ m_performanceCounters[i][1]);
m_performanceCountersData[static_cast<PerformanceCounter>(i)] =
static_cast<float>(diff) / static_cast<float>(sum);
diff --git a/src/app/app.h b/src/app/app.h
index 71a3527..d2561e7 100644
--- a/src/app/app.h
+++ b/src/app/app.h
@@ -352,7 +352,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
- Event CreateUpdateEvent();
+ TEST_VIRTUAL Event CreateUpdateEvent();
//! Handles some incoming events
bool ProcessEvent(const Event& event);
//! Renders the image in window
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 0622370..edb5828 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -76,40 +76,46 @@ extern "C"
int SDL_MAIN_FUNC(int argc, char *argv[])
{
- CLogger logger; // Create the logger
+ CLogger logger; // single istance of logger
- InitializeRestext(); // Initialize translation strings
+ InitializeRestext(); // init static translation strings
+
+ CSystemUtils* systemUtils = CSystemUtils::Create(); // platform-specific utils
+ systemUtils->Init();
logger.Info("Colobot starting\n");
- CApplication app; // single instance of the application
+ CApplication* app = new CApplication(); // single instance of the application
- ParseArgsStatus status = app.ParseArguments(argc, argv);
+ ParseArgsStatus status = app->ParseArguments(argc, argv);
if (status == PARSE_ARGS_FAIL)
{
- SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
- return app.GetExitCode();
+ systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
+ return app->GetExitCode();
}
else if (status == PARSE_ARGS_HELP)
{
- return app.GetExitCode();
+ return app->GetExitCode();
}
int code = 0;
- if (! app.Create())
+ if (! app->Create())
{
- app.Destroy(); // ensure a clean exit
- code = app.GetExitCode();
- if ( code != 0 && !app.GetErrorMessage().empty() )
+ app->Destroy(); // ensure a clean exit
+ code = app->GetExitCode();
+ if ( code != 0 && !app->GetErrorMessage().empty() )
{
- SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app.GetErrorMessage());
+ systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app->GetErrorMessage());
}
logger.Info("Didn't run main loop. Exiting with code %d\n", code);
return code;
}
- code = app.Run();
+ code = app->Run();
+
+ delete app;
+ delete systemUtils;
logger.Info("Exiting with code %d\n", code);
return code;
diff --git a/src/app/system.cpp b/src/app/system.cpp
index 73614aa..6927af8 100644
--- a/src/app/system.cpp
+++ b/src/app/system.cpp
@@ -22,75 +22,142 @@
#if defined(PLATFORM_WINDOWS)
-#include "app/system_windows.h"
-
+ #include "app/system_windows.h"
#elif defined(PLATFORM_LINUX)
-#include "app/system_linux.h"
-
+ #include "app/system_linux.h"
#else
-#include "app/system_other.h"
-
+ #include "app/system_other.h"
#endif
-
#include <cassert>
+#include <iostream>
+
+
+template<>
+CSystemUtils* CSingleton<CSystemUtils>::m_instance = nullptr;
-/**
- * Displays a system dialog with info, error, question etc. message.
- *
- * \param type type of dialog
- * \param message text of message (in UTF-8)
- * \param title dialog title (in UTF-8)
- * \returns result (which button was clicked)
- */
-SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
+CSystemUtils::CSystemUtils()
{
+}
+
+CSystemUtils* CSystemUtils::Create()
+{
+ assert(m_instance == nullptr);
#if defined(PLATFORM_WINDOWS)
- return SystemDialog_Windows(type, title, message);
+ m_instance = new CSystemUtilsWindows();
#elif defined(PLATFORM_LINUX)
- return SystemDialog_Linux(type, title, message);
+ m_instance = new CSystemUtilsLinux();
#else
- return SystemDialog_Other(type, title, message);
+ m_instance = new CSystemUtilsOther();
#endif
+ return m_instance;
}
-SystemTimeStamp* CreateTimeStamp()
+SystemDialogResult CSystemUtils::ConsoleSystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
{
- return new SystemTimeStamp();
+ switch (type)
+ {
+ case SDT_INFO:
+ std::cout << "INFO: ";
+ break;
+ case SDT_WARNING:
+ std::cout << "WARNING:";
+ break;
+ case SDT_ERROR:
+ std::cout << "ERROR: ";
+ break;
+ case SDT_YES_NO:
+ case SDT_OK_CANCEL:
+ std::cout << "QUESTION: ";
+ break;
+ }
+
+ std::cout << message << std::endl;
+
+ std::string line;
+
+ SystemDialogResult result = SDR_OK;
+
+ bool done = false;
+ while (!done)
+ {
+ switch (type)
+ {
+ case SDT_INFO:
+ case SDT_WARNING:
+ case SDT_ERROR:
+ std::cout << "Press ENTER to continue";
+ break;
+
+ case SDT_YES_NO:
+ std::cout << "Type 'Y' for Yes or 'N' for No";
+ break;
+
+ case SDT_OK_CANCEL:
+ std::cout << "Type 'O' for OK or 'C' for Cancel";
+ break;
+ }
+
+ std::getline(std::cin, line);
+
+ switch (type)
+ {
+ case SDT_INFO:
+ case SDT_WARNING:
+ case SDT_ERROR:
+ done = true;
+ break;
+
+ case SDT_YES_NO:
+ if (line == "Y" || line == "y")
+ {
+ result = SDR_YES;
+ done = true;
+ }
+ else if (line == "N" || line == "n")
+ {
+ result = SDR_NO;
+ done = true;
+ }
+ break;
+
+ case SDT_OK_CANCEL:
+ if (line == "O" || line == "o")
+ {
+ done = true;
+ result = SDR_OK;
+ }
+ else if (line == "C" || line == "c")
+ {
+ done = true;
+ result = SDR_CANCEL;
+ }
+ break;
+ }
+ }
+
+ return result;
}
-void DestroyTimeStamp(SystemTimeStamp *stamp)
+SystemTimeStamp* CSystemUtils::CreateTimeStamp()
{
- delete stamp;
+ return new SystemTimeStamp();
}
-void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src)
+void CSystemUtils::DestroyTimeStamp(SystemTimeStamp *stamp)
{
- *dst = *src;
+ delete stamp;
}
-void GetCurrentTimeStamp(SystemTimeStamp *stamp)
+void CSystemUtils::CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src)
{
-#if defined(PLATFORM_WINDOWS)
- GetCurrentTimeStamp_Windows(stamp);
-#elif defined(PLATFORM_LINUX)
- GetCurrentTimeStamp_Linux(stamp);
-#else
- GetCurrentTimeStamp_Other(stamp);
-#endif
+ *dst = *src;
}
-float GetTimeStampResolution(SystemTimeUnit unit)
+float CSystemUtils::GetTimeStampResolution(SystemTimeUnit unit)
{
- unsigned long long exact = 0;
-#if defined(PLATFORM_WINDOWS)
- exact = GetTimeStampExactResolution_Windows();
-#elif defined(PLATFORM_LINUX)
- exact = GetTimeStampExactResolution_Linux();
-#else
- exact = GetTimeStampExactResolution_Other();
-#endif
+ unsigned long long exact = GetTimeStampExactResolution();
float result = 0.0f;
if (unit == STU_SEC)
result = exact * 1e-9;
@@ -100,30 +167,14 @@ float GetTimeStampResolution(SystemTimeUnit unit)
result = exact * 1e-3;
else
assert(false);
+
return result;
}
-long long GetTimeStampExactResolution()
+float CSystemUtils::TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeUnit unit)
{
-#if defined(PLATFORM_WINDOWS)
- return GetTimeStampExactResolution_Windows();
-#elif defined(PLATFORM_LINUX)
- return GetTimeStampExactResolution_Linux();
-#else
- return GetTimeStampExactResolution_Other();
-#endif
-}
+ long long exact = TimeStampExactDiff(before, after);
-float TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeUnit unit)
-{
- long long exact = 0;
-#if defined(PLATFORM_WINDOWS)
- exact = TimeStampExactDiff_Windows(before, after);
-#elif defined(PLATFORM_LINUX)
- exact = TimeStampExactDiff_Linux(before, after);
-#else
- exact = TimeStampExactDiff_Other(before, after);
-#endif
float result = 0.0f;
if (unit == STU_SEC)
result = exact * 1e-9;
@@ -133,16 +184,6 @@ float TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeU
result = exact * 1e-3;
else
assert(false);
- return result;
-}
-long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after)
-{
-#if defined(PLATFORM_WINDOWS)
- return TimeStampExactDiff_Windows(before, after);
-#elif defined(PLATFORM_LINUX)
- return TimeStampExactDiff_Linux(before, after);
-#else
- return TimeStampExactDiff_Other(before, after);
-#endif
+ return result;
}
diff --git a/src/app/system.h b/src/app/system.h
index e216842..278a4bf 100644
--- a/src/app/system.h
+++ b/src/app/system.h
@@ -22,12 +22,10 @@
#pragma once
+#include "common/singleton.h"
#include <string>
-
-/* Dialog utils */
-
/**
* \enum SystemDialogType
* \brief Type of system dialog
@@ -60,12 +58,10 @@ enum SystemDialogResult
SDR_NO
};
-//! Displays a system dialog
-SystemDialogResult SystemDialog(SystemDialogType, const std::string &title, const std::string &message);
-
-
-/* Time utils */
-
+/**
+ * \enum SystemTimeUnit
+ * \brief Time unit
+ */
enum SystemTimeUnit
{
//! seconds
@@ -76,33 +72,67 @@ enum SystemTimeUnit
STU_USEC
};
-/* Forward declaration of time stamp struct
- * SystemTimeStamp should be used in a pointer context.
- * The implementation details are hidden because of platform dependence. */
+/*
+ * Forward declaration of time stamp struct
+ * SystemTimeStamp should only be used in a pointer context.
+ * The implementation details are hidden because of platform dependence.
+ */
struct SystemTimeStamp;
-//! Creates a new time stamp object
-SystemTimeStamp* CreateTimeStamp();
+/**
+ * \class CSystemUtils
+ * \brief Platform-specific utils
+ *
+ * This class provides system-specific utilities like displaying user dialogs and
+ * querying system timers for exact timestamps.
+ */
+class CSystemUtils : public CSingleton<CSystemUtils>
+{
+protected:
+ CSystemUtils();
+
+public:
+ //! Creates system utils for specific platform
+ static CSystemUtils* Create();
+
+ //! Performs platform-specific initialization
+ virtual void Init() = 0;
+
+ //! Displays a system dialog
+ virtual SystemDialogResult SystemDialog(SystemDialogType, const std::string &title, const std::string &message) = 0;
-//! Destroys a time stamp object
-void DestroyTimeStamp(SystemTimeStamp *stamp);
+ //! Displays a fallback system dialog using console
+ TEST_VIRTUAL SystemDialogResult ConsoleSystemDialog(SystemDialogType type, const std::string& title, const std::string& message);
-//! Copies the time stamp from \a src to \a dst
-void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src);
+ //! Creates a new time stamp object
+ TEST_VIRTUAL SystemTimeStamp* CreateTimeStamp();
-//! Returns a time stamp associated with current time
-void GetCurrentTimeStamp(SystemTimeStamp *stamp);
+ //! Destroys a time stamp object
+ TEST_VIRTUAL void DestroyTimeStamp(SystemTimeStamp *stamp);
-//! Returns the platform's expected time stamp resolution
-float GetTimeStampResolution(SystemTimeUnit unit = STU_SEC);
+ //! Copies the time stamp from \a src to \a dst
+ TEST_VIRTUAL void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src);
-//! Returns the platform's exact (in nanosecond units) expected time stamp resolution
-long long GetTimeStampExactResolution();
+ //! Returns a time stamp associated with current time
+ virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) = 0;
-//! 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);
+ //! Returns the platform's expected time stamp resolution
+ TEST_VIRTUAL float GetTimeStampResolution(SystemTimeUnit unit = STU_SEC);
-//! 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 platform's exact (in nanosecond units) expected time stamp resolution
+ virtual long long GetTimeStampExactResolution() = 0;
+
+ //! Returns a difference between two timestamps in given time unit
+ /** The difference is \a after - \a before. */
+ TEST_VIRTUAL float TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeUnit unit = STU_SEC);
+
+ //! Returns the exact (in nanosecond units) difference between two timestamps
+ /** The difference is \a after - \a before. */
+ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) = 0;
+};
+
+//! Global function to get CSystemUtils instance
+inline CSystemUtils* GetSystemUtils()
+{
+ return CSystemUtils::GetInstancePointer();
+}
diff --git a/src/app/system_linux.cpp b/src/app/system_linux.cpp
index cd785f8..619909d 100644
--- a/src/app/system_linux.cpp
+++ b/src/app/system_linux.cpp
@@ -17,11 +17,28 @@
#include "app/system_linux.h"
+#include "common/logger.h"
+
#include <stdlib.h>
-SystemDialogResult SystemDialog_Linux(SystemDialogType type, const std::string& title, const std::string& message)
+void CSystemUtilsLinux::Init()
{
+ m_zenityAvailable = true;
+ if (system("zenity --version") != 0)
+ {
+ m_zenityAvailable = false;
+ GetLogger()->Warn("Zenity not available, will fallback to console users dialogs.\n");
+ }
+}
+
+SystemDialogResult CSystemUtilsLinux::SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
+{
+ if (!m_zenityAvailable)
+ {
+ return ConsoleSystemDialog(type, title, message);
+ }
+
std::string options = "";
switch (type)
{
@@ -62,17 +79,17 @@ SystemDialogResult SystemDialog_Linux(SystemDialogType type, const std::string&
return result;
}
-void GetCurrentTimeStamp_Linux(SystemTimeStamp *stamp)
+void CSystemUtilsLinux::GetCurrentTimeStamp(SystemTimeStamp *stamp)
{
clock_gettime(CLOCK_MONOTONIC_RAW, &stamp->clockTime);
}
-long long GetTimeStampExactResolution_Linux()
+long long CSystemUtilsLinux::GetTimeStampExactResolution()
{
return 1ll;
}
-long long TimeStampExactDiff_Linux(SystemTimeStamp *before, SystemTimeStamp *after)
+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;
diff --git a/src/app/system_linux.h b/src/app/system_linux.h
index bc07c31..ba0d8cd 100644
--- a/src/app/system_linux.h
+++ b/src/app/system_linux.h
@@ -35,9 +35,17 @@ struct SystemTimeStamp
}
};
+class CSystemUtilsLinux : public CSystemUtils
+{
+public:
+ virtual void Init() override;
+
+ virtual SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
-SystemDialogResult SystemDialog_Linux(SystemDialogType type, const std::string& title, const std::string& message);
+ virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
+ virtual long long GetTimeStampExactResolution() override;
+ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
-void GetCurrentTimeStamp_Linux(SystemTimeStamp *stamp);
-long long GetTimeStampExactResolution_Linux();
-long long TimeStampExactDiff_Linux(SystemTimeStamp *before, SystemTimeStamp *after);
+private:
+ bool m_zenityAvailable;
+};
diff --git a/src/app/system_other.cpp b/src/app/system_other.cpp
index 006bf6d..9fc1f95 100644
--- a/src/app/system_other.cpp
+++ b/src/app/system_other.cpp
@@ -18,105 +18,22 @@
#include "app/system_other.h"
-SystemDialogResult SystemDialog_Other(SystemDialogType type, const std::string& title, const std::string& message)
+SystemDialogResult CSystemUtilsOther::SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
{
- switch (type)
- {
- case SDT_INFO:
- std::cout << "INFO: ";
- break;
- case SDT_WARNING:
- std::cout << "WARNING:";
- break;
- case SDT_ERROR:
- std::cout << "ERROR: ";
- break;
- case SDT_YES_NO:
- case SDT_OK_CANCEL:
- std::cout << "QUESTION: ";
- break;
- }
-
- std::cout << message << std::endl;
-
- std::string line;
-
- SystemDialogResult result = SDR_OK;
-
- bool done = false;
- while (!done)
- {
- switch (type)
- {
- case SDT_INFO:
- case SDT_WARNING:
- case SDT_ERROR:
- std::cout << "Press ENTER to continue";
- break;
-
- case SDT_YES_NO:
- std::cout << "Type 'Y' for Yes or 'N' for No";
- break;
-
- case SDT_OK_CANCEL:
- std::cout << "Type 'O' for OK or 'C' for Cancel";
- break;
- }
-
- std::getline(std::cin, line);
-
- switch (type)
- {
- case SDT_INFO:
- case SDT_WARNING:
- case SDT_ERROR:
- done = true;
- break;
-
- case SDT_YES_NO:
- if (line == "Y" || line == "y")
- {
- result = SDR_YES;
- done = true;
- }
- else if (line == "N" || line == "n")
- {
- result = SDR_NO;
- done = true;
- }
- break;
-
- case SDT_OK_CANCEL:
- if (line == "O" || line == "o")
- {
- done = true;
- result = SDR_OK;
- }
- else if (line == "C" || line == "c")
- {
- done = true;
- result = SDR_CANCEL;
- }
- break;
- }
- }
-
- return result;
+ return ConsoleSystemDialog(type, title, message);
}
-
-
-void GetCurrentTimeStamp_Other(SystemTimeStamp *stamp)
+void CSystemUtilsOther::GetCurrentTimeStamp(SystemTimeStamp* stamp)
{
stamp->sdlTicks = SDL_GetTicks();
}
-long long GetTimeStampExactResolution_Other()
+long long int CSystemUtilsOther::GetTimeStampExactResolution()
{
return 1000000ll;
}
-long long TimeStampExactDiff_Other(SystemTimeStamp *before, SystemTimeStamp *after)
+long long int CSystemUtilsOther::TimeStampExactDiff(SystemTimeStamp* before, SystemTimeStamp* after) const
{
return (after->sdlTicks - before->sdlTicks) * 1000000ll;
}
diff --git a/src/app/system_other.h b/src/app/system_other.h
index aee3536..bf16c80 100644
--- a/src/app/system_other.h
+++ b/src/app/system_other.h
@@ -37,9 +37,12 @@ struct SystemTimeStamp
}
};
+class CSystemUtilsOther : public CSystemUtils
+{
+public:
+ virtual SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
-SystemDialogResult SystemDialog_Other(SystemDialogType type, const std::string& title, const std::string& message);
-
-void GetCurrentTimeStamp_Other(SystemTimeStamp *stamp);
-long long GetTimeStampExactResolution_Other();
-long long TimeStampExactDiff_Other(SystemTimeStamp *before, SystemTimeStamp *after);
+ virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
+ virtual long long GetTimeStampExactResolution() override;
+ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
+};
diff --git a/src/app/system_windows.cpp b/src/app/system_windows.cpp
index 34fa57e..780afef 100644
--- a/src/app/system_windows.cpp
+++ b/src/app/system_windows.cpp
@@ -17,30 +17,25 @@
#include "app/system_windows.h"
+#include "common/logger.h"
+
+#include <windows.h>
-// Convert a wide Unicode string to an UTF8 string
-std::string UTF8_Encode_Windows(const std::wstring &wstr)
-{
- int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), NULL, 0, NULL, NULL);
- std::string strTo(size_needed, 0);
- WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), &strTo[0], size_needed, NULL, NULL);
- return strTo;
-}
-// Convert an UTF8 string to a wide Unicode String
-std::wstring UTF8_Decode_Windows(const std::string &str)
+void CSystemUtilsWindows::Init()
{
- int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), NULL, 0);
- std::wstring wstrTo(size_needed, 0);
- MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), &wstrTo[0], size_needed);
- return wstrTo;
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ m_counterFrequency = freq.QuadPart;
+
+ assert(m_counterFrequency != 0);
}
-SystemDialogResult SystemDialog_Windows(SystemDialogType type, const std::string& title, const std::string& message)
+SystemDialogResult CSystemUtilsWindows::SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
{
unsigned int windowsType = 0;
- std::wstring windowsMessage = UTF8_Decode_Windows(message);
- std::wstring windowsTitle = UTF8_Decode_Windows(title);
+ std::wstring windowsMessage = UTF8_Decode(message);
+ std::wstring windowsTitle = UTF8_Decode(title);
switch (type)
{
@@ -79,20 +74,39 @@ SystemDialogResult SystemDialog_Windows(SystemDialogType type, const std::string
return SDR_OK;
}
+void CSystemUtilsWindows::GetCurrentTimeStamp(SystemTimeStamp* stamp)
+{
+ LARGE_INTEGER value;
+ QueryPerformanceCounter(&value);
+ stamp->counterValue = value.QuadPart;
+}
+
+long long int CSystemUtilsWindows::GetTimeStampExactResolution()
+{
+ return 1000000000ll / m_counterFrequency;
+}
-void GetCurrentTimeStamp_Windows(SystemTimeStamp *stamp)
+long long int CSystemUtilsWindows::TimeStampExactDiff(SystemTimeStamp* before, SystemTimeStamp* after)
{
- GetSystemTimeAsFileTime(&stamp->fileTime);
+ float floatValue = static_cast<double>(after->counterValue - before->counterValue) * (1e9 / static_cast<double>(m_counterFrequency));
+ return static_cast<long long>(floatValue);
}
-long long GetTimeStampExactResolution_Windows()
+//! Converts a wide Unicode string to an UTF8 string
+std::string CSystemUtilsWindows::UTF8_Encode(const std::wstring& wstr)
{
- return 100ll;
+ int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), NULL, 0, NULL, NULL);
+ std::string strTo(size_needed, 0);
+ WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), &strTo[0], size_needed, NULL, NULL);
+ return strTo;
}
-long long TimeStampExactDiff_Windows(SystemTimeStamp *before, SystemTimeStamp *after)
+//! Converts an UTF8 string to a wide Unicode String
+std::wstring CSystemUtilsWindows::UTF8_Decode(const std::string& str)
{
- long long tH = (1ll << 32) * (after->fileTime.dwHighDateTime - before->fileTime.dwHighDateTime);
- long long tL = after->fileTime.dwLowDateTime - before->fileTime.dwLowDateTime;
- return (tH + tL) * 100ll;
+ int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), NULL, 0);
+ std::wstring wstrTo(size_needed, 0);
+ MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), &wstrTo[0], size_needed);
+ return wstrTo;
+
}
diff --git a/src/app/system_windows.h b/src/app/system_windows.h
index 804d064..e367b92 100644
--- a/src/app/system_windows.h
+++ b/src/app/system_windows.h
@@ -22,23 +22,32 @@
#include "app/system.h"
-#include <windows.h>
-
struct SystemTimeStamp
{
- FILETIME fileTime;
+ long long counterValue;
SystemTimeStamp()
{
- fileTime.dwHighDateTime = fileTime.dwLowDateTime = 0;
+ counterValue = 0;
}
};
-std::string UTF8_Encode_Windows(const std::wstring &wstr);
-std::wstring UTF8_Decode_Windows(const std::string &str);
-SystemDialogResult SystemDialog_Windows(SystemDialogType type, const std::string& title, const std::string& message);
+class CSystemUtilsWindows : public CSystemUtils
+{
+public:
+ virtual void Init() override;
+
+ virtual SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
-void GetCurrentTimeStamp_Windows(SystemTimeStamp *stamp);
-long long GetTimeStampExactResolution_Windows();
-long long TimeStampExactDiff_Windows(SystemTimeStamp *before, SystemTimeStamp *after);
+ virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
+ virtual long long GetTimeStampExactResolution() override;
+ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
+
+private:
+ std::string UTF8_Encode(const std::wstring &wstr);
+ std::wstring UTF8_Decode(const std::string &str);
+
+protected:
+ long long m_counterFrequency;
+};
diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp
index d24a3bd..e2ef569 100644
--- a/src/graphics/engine/engine.cpp
+++ b/src/graphics/engine/engine.cpp
@@ -148,8 +148,8 @@ CEngine::CEngine(CApplication *app)
m_mouseType = ENG_MOUSE_NORM;
m_fpsCounter = 0;
- m_lastFrameTime = CreateTimeStamp();
- m_currentFrameTime = CreateTimeStamp();
+ m_lastFrameTime = GetSystemUtils()->CreateTimeStamp();
+ m_currentFrameTime = GetSystemUtils()->CreateTimeStamp();
m_defaultTexParams.format = TEX_IMG_AUTO;
m_defaultTexParams.mipmap = true;
@@ -176,9 +176,9 @@ CEngine::~CEngine()
m_planet = nullptr;
m_terrain = nullptr;
- DestroyTimeStamp(m_lastFrameTime);
+ GetSystemUtils()->DestroyTimeStamp(m_lastFrameTime);
m_lastFrameTime = nullptr;
- DestroyTimeStamp(m_currentFrameTime);
+ GetSystemUtils()->DestroyTimeStamp(m_currentFrameTime);
m_currentFrameTime = nullptr;
}
@@ -279,8 +279,8 @@ bool CEngine::Create()
params.mipmap = false;
m_miceTexture = LoadTexture("mouse.png", params);
- GetCurrentTimeStamp(m_currentFrameTime);
- GetCurrentTimeStamp(m_lastFrameTime);
+ GetSystemUtils()->GetCurrentTimeStamp(m_currentFrameTime);
+ GetSystemUtils()->GetCurrentTimeStamp(m_lastFrameTime);
return true;
}
@@ -336,11 +336,11 @@ void CEngine::FrameUpdate()
{
m_fpsCounter++;
- GetCurrentTimeStamp(m_currentFrameTime);
- float diff = TimeStampDiff(m_lastFrameTime, m_currentFrameTime, STU_SEC);
+ GetSystemUtils()->GetCurrentTimeStamp(m_currentFrameTime);
+ float diff = GetSystemUtils()->TimeStampDiff(m_lastFrameTime, m_currentFrameTime, STU_SEC);
if (diff > 1.0f)
{
- CopyTimeStamp(m_lastFrameTime, m_currentFrameTime);
+ GetSystemUtils()->CopyTimeStamp(m_lastFrameTime, m_currentFrameTime);
m_fps = m_fpsCounter / diff;
m_fpsCounter = 0;
diff --git a/test/envs/opengl/CMakeLists.txt b/test/envs/opengl/CMakeLists.txt
index d6c3a37..0bcb43d 100644
--- a/test/envs/opengl/CMakeLists.txt
+++ b/test/envs/opengl/CMakeLists.txt
@@ -3,9 +3,9 @@ set(SRC_DIR ${colobot_SOURCE_DIR}/src)
configure_file(${SRC_DIR}/common/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/common/config.h)
# Platform-dependent implementation of system.h
-if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+if (${PLATFORM_WINDOWS})
set(SYSTEM_CPP_MODULE "system_windows.cpp")
-elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+elseif(${PLATFORM_LINUX})
set(SYSTEM_CPP_MODULE "system_linux.cpp")
else()
set(SYSTEM_CPP_MODULE "system_other.cpp")
diff --git a/test/envs/opengl/light_test.cpp b/test/envs/opengl/light_test.cpp
index d4635cc..0baf6d3 100644
--- a/test/envs/opengl/light_test.cpp
+++ b/test/envs/opengl/light_test.cpp
@@ -258,9 +258,9 @@ void Update()
{
const float TRANS_SPEED = 6.0f; // units / sec
- GetCurrentTimeStamp(CURR_TIME);
- float timeDiff = TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC);
- CopyTimeStamp(PREV_TIME, CURR_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME);
+ float timeDiff = GetSystemUtils()->TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC);
+ GetSystemUtils()->CopyTimeStamp(PREV_TIME, CURR_TIME);
CUBE_ORBIT += timeDiff * (Math::PI / 4.0f);
@@ -365,11 +365,11 @@ int SDL_MAIN_FUNC(int argc, char *argv[])
{
CLogger logger;
- PREV_TIME = CreateTimeStamp();
- CURR_TIME = CreateTimeStamp();
+ PREV_TIME = GetSystemUtils()->CreateTimeStamp();
+ CURR_TIME = GetSystemUtils()->CreateTimeStamp();
- GetCurrentTimeStamp(PREV_TIME);
- GetCurrentTimeStamp(CURR_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(PREV_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME);
// Without any error checking, for simplicity
@@ -459,8 +459,8 @@ int SDL_MAIN_FUNC(int argc, char *argv[])
SDL_Quit();
- DestroyTimeStamp(PREV_TIME);
- DestroyTimeStamp(CURR_TIME);
+ GetSystemUtils()->DestroyTimeStamp(PREV_TIME);
+ GetSystemUtils()->DestroyTimeStamp(CURR_TIME);
return 0;
}
diff --git a/test/envs/opengl/model_test.cpp b/test/envs/opengl/model_test.cpp
index 168eb32..1dda69c 100644
--- a/test/envs/opengl/model_test.cpp
+++ b/test/envs/opengl/model_test.cpp
@@ -153,9 +153,9 @@ void Update()
const float ROT_SPEED = 80.0f * Math::DEG_TO_RAD; // rad / sec
const float TRANS_SPEED = 3.0f; // units / sec
- GetCurrentTimeStamp(CURR_TIME);
- float timeDiff = TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC);
- CopyTimeStamp(PREV_TIME, CURR_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME);
+ float timeDiff = GetSystemUtils()->TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC);
+ GetSystemUtils()->CopyTimeStamp(PREV_TIME, CURR_TIME);
if (KEYMAP[K_RotYLeft])
ROTATION.y -= ROT_SPEED * timeDiff;
@@ -265,11 +265,11 @@ int SDL_MAIN_FUNC(int argc, char *argv[])
{
CLogger logger;
- PREV_TIME = CreateTimeStamp();
- CURR_TIME = CreateTimeStamp();
+ PREV_TIME = GetSystemUtils()->CreateTimeStamp();
+ CURR_TIME = GetSystemUtils()->CreateTimeStamp();
- GetCurrentTimeStamp(PREV_TIME);
- GetCurrentTimeStamp(CURR_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(PREV_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME);
if (argc != 3)
{
@@ -377,8 +377,8 @@ int SDL_MAIN_FUNC(int argc, char *argv[])
SDL_Quit();
- DestroyTimeStamp(PREV_TIME);
- DestroyTimeStamp(CURR_TIME);
+ GetSystemUtils()->DestroyTimeStamp(PREV_TIME);
+ GetSystemUtils()->DestroyTimeStamp(CURR_TIME);
return 0;
}
diff --git a/test/envs/opengl/transform_test.cpp b/test/envs/opengl/transform_test.cpp
index 02f9d83..1d5ccf1 100644
--- a/test/envs/opengl/transform_test.cpp
+++ b/test/envs/opengl/transform_test.cpp
@@ -138,9 +138,9 @@ void Update()
{
const float TRANS_SPEED = 6.0f; // units / sec
- GetCurrentTimeStamp(CURR_TIME);
- float timeDiff = TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC);
- CopyTimeStamp(PREV_TIME, CURR_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME);
+ float timeDiff = GetSystemUtils()->TimeStampDiff(PREV_TIME, CURR_TIME, STU_SEC);
+ GetSystemUtils()->CopyTimeStamp(PREV_TIME, CURR_TIME);
Math::Vector incTrans;
@@ -243,11 +243,11 @@ int SDL_MAIN_FUNC(int argc, char *argv[])
{
CLogger logger;
- PREV_TIME = CreateTimeStamp();
- CURR_TIME = CreateTimeStamp();
+ PREV_TIME = GetSystemUtils()->CreateTimeStamp();
+ CURR_TIME = GetSystemUtils()->CreateTimeStamp();
- GetCurrentTimeStamp(PREV_TIME);
- GetCurrentTimeStamp(CURR_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(PREV_TIME);
+ GetSystemUtils()->GetCurrentTimeStamp(CURR_TIME);
// Without any error checking, for simplicity
@@ -337,8 +337,8 @@ int SDL_MAIN_FUNC(int argc, char *argv[])
SDL_Quit();
- DestroyTimeStamp(PREV_TIME);
- DestroyTimeStamp(CURR_TIME);
+ GetSystemUtils()->DestroyTimeStamp(PREV_TIME);
+ GetSystemUtils()->DestroyTimeStamp(CURR_TIME);
return 0;
}
diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt
index f3be01d..3d8a38c 100644
--- a/test/unit/CMakeLists.txt
+++ b/test/unit/CMakeLists.txt
@@ -16,9 +16,9 @@ endif()
configure_file(${SRC_DIR}/common/config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/common/config.h)
# Platform-dependent implementation of system.h
-if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+if (${PLATFORM_WINDOWS})
set(SYSTEM_CPP_MODULE "system_windows.cpp")
-elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+elseif(${PLATFORM_LINUX})
set(SYSTEM_CPP_MODULE "system_linux.cpp")
else()
set(SYSTEM_CPP_MODULE "system_other.cpp")
@@ -164,17 +164,16 @@ endif()
# Platform-dependent tests
-if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
- #TODO: set(PLATFORM_TESTS app/system_windows_test.cpp)
-elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+if (${PLATFORM_WINDOWS})
+ set(PLATFORM_TESTS app/system_windows_test.cpp)
+elseif(${PLATFORM_LINUX})
set(PLATFORM_TESTS app/system_linux_test.cpp)
-else()
- #TODO: set(PLATFORM_TESTS app/system_other_test.cpp)
endif()
# Tests
set(UT_SOURCES
main.cpp
+app/app_test.cpp
graphics/engine/lightman_test.cpp
math/geometry_test.cpp
math/matrix_test.cpp
diff --git a/test/unit/app/app_test.cpp b/test/unit/app/app_test.cpp
new file mode 100644
index 0000000..8c1e899
--- /dev/null
+++ b/test/unit/app/app_test.cpp
@@ -0,0 +1,320 @@
+#include "app/app.h"
+
+#if defined(PLATFORM_WINDOWS)
+ #include "app/system_windows.h"
+#elif defined(PLATFORM_LINUX)
+ #include "app/system_linux.h"
+#else
+ #include "app/system_other.h"
+#endif
+
+#include "app/system_mock.h"
+
+#include "common/logger.h"
+
+#include <gtest/gtest.h>
+
+using testing::_;
+using testing::InSequence;
+using testing::Return;
+
+struct FakeSystemTimeStamp : public SystemTimeStamp
+{
+ FakeSystemTimeStamp(int uid) : uid(uid), time(0) {}
+
+ int uid;
+ long long time;
+};
+
+
+class CApplicationWrapper : public CApplication
+{
+public:
+ virtual Event CreateUpdateEvent() override
+ {
+ return CApplication::CreateUpdateEvent();
+ }
+};
+
+class ApplicationUT : public testing::Test
+{
+protected:
+ ApplicationUT();
+
+ virtual void SetUp() override;
+ virtual void TearDown() override;
+
+ void NextInstant(long long diff);
+
+ SystemTimeStamp* CreateTimeStamp();
+ void DestroyTimeStamp(SystemTimeStamp *stamp);
+ void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src);
+ void GetCurrentTimeStamp(SystemTimeStamp *stamp);
+ long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after);
+
+ void TestCreateUpdateEvent(long long relTimeExact, long long absTimeExact,
+ float relTime, float absTime,
+ long long relTimeReal, long long absTimeReal);
+
+protected:
+ CLogger logger;
+ CApplicationWrapper* app;
+ CSystemUtilsMock* systemUtils;
+
+private:
+ int m_stampUid;
+ long long m_currentTime;
+};
+
+ApplicationUT::ApplicationUT()
+ : m_stampUid(0)
+ , m_currentTime(0)
+{}
+
+void ApplicationUT::SetUp()
+{
+ systemUtils = new CSystemUtilsMock();
+
+ ON_CALL(*systemUtils, CreateTimeStamp()).WillByDefault(Invoke(this, &ApplicationUT::CreateTimeStamp));
+ ON_CALL(*systemUtils, DestroyTimeStamp(_)).WillByDefault(Invoke(this, &ApplicationUT::DestroyTimeStamp));
+ ON_CALL(*systemUtils, CopyTimeStamp(_, _)).WillByDefault(Invoke(this, &ApplicationUT::CopyTimeStamp));
+ ON_CALL(*systemUtils, GetCurrentTimeStamp(_)).WillByDefault(Invoke(this, &ApplicationUT::GetCurrentTimeStamp));
+ ON_CALL(*systemUtils, TimeStampExactDiff(_, _)).WillByDefault(Invoke(this, &ApplicationUT::TimeStampExactDiff));
+
+ EXPECT_CALL(*systemUtils, CreateTimeStamp()).Times(3 + PCNT_MAX*2);
+ app = new CApplicationWrapper();
+}
+
+void ApplicationUT::TearDown()
+{
+ EXPECT_CALL(*systemUtils, DestroyTimeStamp(_)).Times(3 + PCNT_MAX*2);
+ delete app;
+ app = nullptr;
+
+ delete systemUtils;
+ systemUtils = nullptr;
+}
+
+SystemTimeStamp* ApplicationUT::CreateTimeStamp()
+{
+ return new FakeSystemTimeStamp(++m_stampUid);
+}
+
+void ApplicationUT::DestroyTimeStamp(SystemTimeStamp *stamp)
+{
+ delete static_cast<FakeSystemTimeStamp*>(stamp);
+}
+
+void ApplicationUT::CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src)
+{
+ *static_cast<FakeSystemTimeStamp*>(dst) = *static_cast<FakeSystemTimeStamp*>(src);
+}
+
+void ApplicationUT::GetCurrentTimeStamp(SystemTimeStamp *stamp)
+{
+ static_cast<FakeSystemTimeStamp*>(stamp)->time = m_currentTime;
+}
+
+long long ApplicationUT::TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after)
+{
+ return static_cast<FakeSystemTimeStamp*>(after)->time - static_cast<FakeSystemTimeStamp*>(before)->time;
+}
+
+void ApplicationUT::NextInstant(long long diff)
+{
+ m_currentTime += diff;
+}
+
+void ApplicationUT::TestCreateUpdateEvent(long long relTimeExact, long long absTimeExact,
+ float relTime, float absTime,
+ long long relTimeReal, long long absTimeReal)
+{
+ {
+ InSequence seq;
+ EXPECT_CALL(*systemUtils, CopyTimeStamp(_, _));
+ EXPECT_CALL(*systemUtils, GetCurrentTimeStamp(_));
+ EXPECT_CALL(*systemUtils, TimeStampExactDiff(_, _)).Times(2);
+ }
+
+ Event event = app->CreateUpdateEvent();
+ EXPECT_EQ(EVENT_FRAME, event.type);
+ EXPECT_FLOAT_EQ(relTime, event.rTime);
+ EXPECT_FLOAT_EQ(relTime, app->GetRelTime());
+ EXPECT_FLOAT_EQ(absTime, app->GetAbsTime());
+ EXPECT_EQ(relTimeExact, app->GetExactRelTime());
+ EXPECT_EQ(absTimeExact, app->GetExactAbsTime());
+ EXPECT_EQ(relTimeReal, app->GetRealRelTime());
+ EXPECT_EQ(absTimeReal, app->GetRealAbsTime());
+}
+
+
+TEST_F(ApplicationUT, UpdateEventTimeCalculation_SimulationSuspended)
+{
+ app->SuspendSimulation();
+ Event event = app->CreateUpdateEvent();
+ EXPECT_EQ(EVENT_NULL, event.type);
+}
+
+TEST_F(ApplicationUT, UpdateEventTimeCalculation_NormalOperation)
+{
+ // 1st update
+
+ long long relTimeExact = 1111;
+ long long absTimeExact = relTimeExact;
+ float relTime = relTimeExact / 1e9f;
+ float absTime = absTimeExact / 1e9f;
+ long long relTimeReal = relTimeExact;
+ long long absTimeReal = absTimeExact;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+
+ // 2nd update
+
+ relTimeExact = 2222;
+ absTimeExact += relTimeExact;
+ relTime = relTimeExact / 1e9f;
+ absTime = absTimeExact / 1e9f;
+ relTimeReal = relTimeExact;
+ absTimeReal = absTimeExact;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+}
+
+TEST_F(ApplicationUT, UpdateEventTimeCalculation_NegativeTimeOperation)
+{
+ // 1st update
+
+ long long relTimeExact = 2222;
+ long long absTimeExact = relTimeExact;
+ float relTime = relTimeExact / 1e9f;
+ float absTime = absTimeExact / 1e9f;
+ long long relTimeReal = relTimeExact;
+ long long absTimeReal = absTimeExact;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+
+ // 2nd update
+
+ NextInstant(-1111);
+
+ {
+ InSequence seq;
+ EXPECT_CALL(*systemUtils, CopyTimeStamp(_, _));
+ EXPECT_CALL(*systemUtils, GetCurrentTimeStamp(_));
+ EXPECT_CALL(*systemUtils, TimeStampExactDiff(_, _)).Times(2);
+ }
+ Event event = app->CreateUpdateEvent();
+ EXPECT_EQ(EVENT_NULL, event.type);
+}
+
+TEST_F(ApplicationUT, UpdateEventTimeCalculation_ChangingSimulationSpeed)
+{
+ EXPECT_CALL(*systemUtils, GetCurrentTimeStamp(_));
+ app->SetSimulationSpeed(2.0f);
+
+ // 1st update -- speed 2x
+
+ long long relTimeReal = 100;
+ long long absTimeReal = relTimeReal;
+ long long relTimeExact = relTimeReal*2;
+ long long absTimeExact = absTimeReal*2;
+ float relTime = relTimeExact / 1e9f;
+ float absTime = absTimeExact / 1e9f;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+
+ // 2nd update -- speed 2x
+
+ relTimeReal = 200;
+ absTimeReal += relTimeReal;
+ relTimeExact = relTimeReal*2;
+ absTimeExact += relTimeReal*2;
+ relTime = relTimeExact / 1e9f;
+ absTime = absTimeExact / 1e9f;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+
+ // 3rd update -- speed 4x
+ EXPECT_CALL(*systemUtils, GetCurrentTimeStamp(_));
+ app->SetSimulationSpeed(4.0f);
+
+ relTimeReal = 300;
+ absTimeReal += relTimeReal;
+ relTimeExact = relTimeReal*4;
+ absTimeExact += relTimeReal*4;
+ relTime = relTimeExact / 1e9f;
+ absTime = absTimeExact / 1e9f;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+
+ // 4th update -- speed 1x
+ EXPECT_CALL(*systemUtils, GetCurrentTimeStamp(_));
+ app->SetSimulationSpeed(1.0f);
+
+ relTimeReal = 400;
+ absTimeReal += relTimeReal;
+ relTimeExact = relTimeReal;
+ absTimeExact += relTimeReal;
+ relTime = relTimeExact / 1e9f;
+ absTime = absTimeExact / 1e9f;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+}
+
+TEST_F(ApplicationUT, UpdateEventTimeCalculation_SuspendingAndResumingSimulation)
+{
+ // 1st update -- simulation enabled
+
+ long long relTimeReal = 1000;
+ long long absTimeReal = relTimeReal;
+ long long relTimeExact = relTimeReal;
+ long long absTimeExact = absTimeReal;
+ float relTime = relTimeExact / 1e9f;
+ float absTime = absTimeExact / 1e9f;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+
+ // 2nd update -- simulation suspended
+
+ app->SuspendSimulation();
+
+ long long suspensionTime = 5000;
+
+ NextInstant(suspensionTime);
+
+ // 3rd update -- simulation resumed
+
+ {
+ InSequence seq;
+ EXPECT_CALL(*systemUtils, GetCurrentTimeStamp(_));
+ EXPECT_CALL(*systemUtils, CopyTimeStamp(_, _));
+ }
+ app->ResumeSimulation();
+
+ relTimeReal = 200;
+ absTimeReal += relTimeReal;
+ relTimeExact = relTimeReal;
+ absTimeExact += relTimeReal;
+ relTime = relTimeExact / 1e9f;
+ absTime = absTimeExact / 1e9f;
+
+ NextInstant(relTimeReal);
+
+ TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
+}
diff --git a/test/unit/app/system_linux_test.cpp b/test/unit/app/system_linux_test.cpp
index fe89399..b0a05ca 100644
--- a/test/unit/app/system_linux_test.cpp
+++ b/test/unit/app/system_linux_test.cpp
@@ -3,10 +3,23 @@
#include <gtest/gtest.h>
-TEST(SystemLinuxTest, TimeStampDiff)
+class CSystemUtilsLinuxWrapper : public CSystemUtilsLinux
{
- const long long SEC = 1000000000;
+public:
+ CSystemUtilsLinuxWrapper() {}
+};
+class SystemUtilsLinuxUT : public testing::Test
+{
+protected:
+ static const long long SEC = 1000000000;
+
+ CSystemUtilsLinuxWrapper systemUtils;
+};
+
+
+TEST_F(SystemUtilsLinuxUT, TimeStampDiff)
+{
SystemTimeStamp before, after;
before.clockTime.tv_sec = 1;
@@ -15,10 +28,10 @@ TEST(SystemLinuxTest, TimeStampDiff)
after.clockTime.tv_sec = 1;
after.clockTime.tv_nsec = 900;
- long long tDiff = TimeStampExactDiff_Linux(&before, &after);
+ long long tDiff = systemUtils.TimeStampExactDiff(&before, &after);
EXPECT_EQ( 800, tDiff);
- tDiff = TimeStampExactDiff_Linux(&after, &before);
+ tDiff = systemUtils.TimeStampExactDiff(&after, &before);
EXPECT_EQ(-800, tDiff);
// -------
@@ -29,10 +42,10 @@ TEST(SystemLinuxTest, TimeStampDiff)
after.clockTime.tv_sec = 3;
after.clockTime.tv_nsec = 500;
- tDiff = TimeStampExactDiff_Linux(&before, &after);
+ tDiff = systemUtils.TimeStampExactDiff(&before, &after);
EXPECT_EQ( SEC + 300, tDiff);
- tDiff = TimeStampExactDiff_Linux(&after, &before);
+ tDiff = systemUtils.TimeStampExactDiff(&after, &before);
EXPECT_EQ(-SEC - 300, tDiff);
// -------
@@ -43,9 +56,9 @@ TEST(SystemLinuxTest, TimeStampDiff)
after.clockTime.tv_sec = 4;
after.clockTime.tv_nsec = 100;
- tDiff = TimeStampExactDiff_Linux(&before, &after);
+ tDiff = systemUtils.TimeStampExactDiff(&before, &after);
EXPECT_EQ( SEC - 100, tDiff);
- tDiff = TimeStampExactDiff_Linux(&after, &before);
+ tDiff = systemUtils.TimeStampExactDiff(&after, &before);
EXPECT_EQ(-SEC + 100, tDiff);
}
diff --git a/test/unit/app/system_mock.h b/test/unit/app/system_mock.h
new file mode 100644
index 0000000..470a4e1
--- /dev/null
+++ b/test/unit/app/system_mock.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "app/system.h"
+
+#include <gmock/gmock.h>
+
+class CSystemUtilsMock : public CSystemUtils
+{
+public:
+ CSystemUtilsMock(bool defaultExpects = false)
+ {
+ if (defaultExpects)
+ SetDefaultExpects();
+ }
+
+ virtual ~CSystemUtilsMock() {}
+
+ void SetDefaultExpects()
+ {
+ using testing::_;
+ using testing::Return;
+ using testing::AnyNumber;
+
+ EXPECT_CALL(*this, CreateTimeStamp()).Times(AnyNumber()).WillRepeatedly(Return(nullptr));
+ EXPECT_CALL(*this, DestroyTimeStamp(_)).Times(AnyNumber());
+ EXPECT_CALL(*this, CopyTimeStamp(_, _)).Times(AnyNumber());
+ EXPECT_CALL(*this, GetCurrentTimeStamp(_)).Times(AnyNumber());
+
+ EXPECT_CALL(*this, GetTimeStampResolution(_)).Times(AnyNumber()).WillRepeatedly(Return(0.0f));
+ EXPECT_CALL(*this, GetTimeStampExactResolution()).Times(AnyNumber()).WillRepeatedly(Return(0ll));
+ EXPECT_CALL(*this, TimeStampDiff(_, _, _)).Times(AnyNumber()).WillRepeatedly(Return(0.0f));
+ EXPECT_CALL(*this, TimeStampExactDiff(_, _)).Times(AnyNumber()).WillRepeatedly(Return(0ll));
+ }
+
+ MOCK_METHOD0(Init, void());
+
+ MOCK_METHOD3(SystemDialog, SystemDialogResult(SystemDialogType, const std::string &title, const std::string &message));
+ MOCK_METHOD3(ConsoleSystemDialog, SystemDialogResult(SystemDialogType type, const std::string& title, const std::string& message));
+
+ MOCK_METHOD0(CreateTimeStamp, SystemTimeStamp*());
+ MOCK_METHOD1(DestroyTimeStamp, void (SystemTimeStamp *stamp));
+ MOCK_METHOD2(CopyTimeStamp, void (SystemTimeStamp *dst, SystemTimeStamp *src));
+ MOCK_METHOD1(GetCurrentTimeStamp, void (SystemTimeStamp *stamp));
+ MOCK_METHOD1(GetTimeStampResolution, float (SystemTimeUnit unit));
+ MOCK_METHOD0(GetTimeStampExactResolution, long long());
+ MOCK_METHOD3(TimeStampDiff, float(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeUnit unit));
+ MOCK_METHOD2(TimeStampExactDiff, long long(SystemTimeStamp *before, SystemTimeStamp *after));
+};
diff --git a/test/unit/app/system_windows_test.cpp b/test/unit/app/system_windows_test.cpp
new file mode 100644
index 0000000..79f8c7f
--- /dev/null
+++ b/test/unit/app/system_windows_test.cpp
@@ -0,0 +1,62 @@
+#include "app/system.h"
+#include "app/system_windows.h"
+
+#include <gtest/gtest.h>
+
+class CSystemUtilsWindowsWrapper : public CSystemUtilsWindows
+{
+public:
+ CSystemUtilsWindowsWrapper() {}
+
+ void SetFrequency(long long counterFrequency)
+ {
+ m_counterFrequency = counterFrequency;
+ }
+};
+
+class SystemUtilsWindowsUT : public testing::Test
+{
+protected:
+ static const long long SEC = 1000000000;
+
+ CSystemUtilsWindowsWrapper systemUtils;
+};
+
+
+TEST_F(SystemUtilsWindowsUT, TimerResolution)
+{
+ systemUtils.SetFrequency(SEC);
+ EXPECT_EQ(1u, systemUtils.GetTimeStampExactResolution());
+
+ systemUtils.SetFrequency(SEC/3);
+ EXPECT_EQ(3u, systemUtils.GetTimeStampExactResolution());
+}
+
+TEST_F(SystemUtilsWindowsUT, TimeStampDiff)
+{
+ systemUtils.SetFrequency(SEC);
+
+ SystemTimeStamp before, after;
+
+ before.counterValue = 100;
+ after.counterValue = 200;
+
+ long long tDiff = systemUtils.TimeStampExactDiff(&before, &after);
+ EXPECT_EQ( 100, tDiff);
+
+ tDiff = systemUtils.TimeStampExactDiff(&after, &before);
+ EXPECT_EQ(-100, tDiff);
+
+ // -------
+
+ systemUtils.SetFrequency(SEC/3);
+
+ before.counterValue = 200;
+ after.counterValue = 400;
+
+ tDiff = systemUtils.TimeStampExactDiff(&before, &after);
+ EXPECT_EQ( 200*3, tDiff);
+
+ tDiff = systemUtils.TimeStampExactDiff(&after, &before);
+ EXPECT_EQ(-200*3, tDiff);
+}
diff --git a/test/unit/graphics/engine/lightman_test.cpp b/test/unit/graphics/engine/lightman_test.cpp
index c955f0a..e2dc785 100644
--- a/test/unit/graphics/engine/lightman_test.cpp
+++ b/test/unit/graphics/engine/lightman_test.cpp
@@ -1,5 +1,7 @@
#include "graphics/engine/lightman.h"
+#include "app/system_mock.h"
+
#include "graphics/core/device_mock.h"
#include "graphics/engine/engine_mock.h"
@@ -15,7 +17,8 @@ class LightManagerUT : public testing::Test
{
protected:
LightManagerUT()
- : lightManager(&engine)
+ : systemUtils(true)
+ , lightManager(&engine)
{}
void PrepareLightTesting(int maxLights, Math::Vector eyePos);
@@ -25,6 +28,7 @@ protected:
Math::Vector pos, EngineObjectType includeType, EngineObjectType excludeType);
+ CSystemUtilsMock systemUtils;
CLightManager lightManager;
CEngineMock engine;
CDeviceMock device;
diff --git a/test/unit/ui/stubs/app_stub.cpp b/test/unit/ui/stubs/app_stub.cpp
index 3df7d42..c8e7bc6 100644
--- a/test/unit/ui/stubs/app_stub.cpp
+++ b/test/unit/ui/stubs/app_stub.cpp
@@ -40,3 +40,8 @@ std::string CApplication::GetDataDirPath()
{
return "";
}
+
+Event CApplication::CreateUpdateEvent()
+{
+ return Event(EVENT_NULL);
+}