From 195d6cded05f7ef5bde695ee047b341a0265eab3 Mon Sep 17 00:00:00 2001 From: Piotr Dziwinski Date: Sun, 24 Mar 2013 00:03:37 +0100 Subject: Fixed timer functions on win32 * changed win32 implementation to QueryPerformaceTimer system function * refactored system utils code * proper tests for time utils and update event creation in application * should fix issue #134 --- CMakeLists.txt | 43 ++-- cmake/msys.cmake | 12 ++ cmake/mxe.cmake | 3 + src/CMakeLists.txt | 4 +- src/app/app.cpp | 133 ++++++------ src/app/app.h | 2 +- src/app/main.cpp | 32 +-- src/app/system.cpp | 185 +++++++++------- src/app/system.h | 90 +++++--- src/app/system_linux.cpp | 25 ++- src/app/system_linux.h | 16 +- src/app/system_other.cpp | 93 +------- src/app/system_other.h | 13 +- src/app/system_windows.cpp | 64 +++--- src/app/system_windows.h | 29 ++- src/graphics/engine/engine.cpp | 18 +- test/envs/opengl/CMakeLists.txt | 4 +- test/envs/opengl/light_test.cpp | 18 +- test/envs/opengl/model_test.cpp | 18 +- test/envs/opengl/transform_test.cpp | 18 +- test/unit/CMakeLists.txt | 13 +- test/unit/app/app_test.cpp | 320 ++++++++++++++++++++++++++++ test/unit/app/system_linux_test.cpp | 29 ++- test/unit/app/system_mock.h | 48 +++++ test/unit/app/system_windows_test.cpp | 62 ++++++ test/unit/graphics/engine/lightman_test.cpp | 6 +- test/unit/ui/stubs/app_stub.cpp | 5 + 27 files changed, 916 insertions(+), 387 deletions(-) create mode 100644 cmake/msys.cmake create mode 100644 test/unit/app/app_test.cpp create mode 100644 test/unit/app/system_mock.h create mode 100644 test/unit/app/system_windows_test.cpp 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 ## @@ -131,35 +123,24 @@ if (${OPENAL_SOUND}) 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() @@ -171,6 +152,30 @@ else() 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(event.type)); + l->Trace("Event type = %d:\n", static_cast(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(i)] = static_cast(diff) / static_cast(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 +#include + + +template<> +CSystemUtils* CSingleton::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 - -/* 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 +{ +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 -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 -// 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(wstr.size()), NULL, 0, NULL, NULL); - std::string strTo(size_needed, 0); - WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast(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(str.size()), NULL, 0); - std::wstring wstrTo(size_needed, 0); - MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast(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(after->counterValue - before->counterValue) * (1e9 / static_cast(m_counterFrequency)); + return static_cast(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(wstr.size()), NULL, 0, NULL, NULL); + std::string strTo(size_needed, 0); + WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast(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(str.size()), NULL, 0); + std::wstring wstrTo(size_needed, 0); + MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast(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 - 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 + +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(stamp); +} + +void ApplicationUT::CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src) +{ + *static_cast(dst) = *static_cast(src); +} + +void ApplicationUT::GetCurrentTimeStamp(SystemTimeStamp *stamp) +{ + static_cast(stamp)->time = m_currentTime; +} + +long long ApplicationUT::TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) +{ + return static_cast(after)->time - static_cast(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 -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 + +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 + +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); +} -- cgit v1.2.3-1-g7c22