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 #134dev-ui
parent
c211b001d2
commit
195d6cded0
|
@ -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
|
||||
##
|
||||
|
|
|
@ -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()
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
133
src/app/app.cpp
133
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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
template<>
|
||||
CSystemUtils* CSingleton<CSystemUtils>::m_instance = nullptr;
|
||||
|
||||
|
||||
CSystemUtils::CSystemUtils()
|
||||
{
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
return SystemDialog_Windows(type, title, message);
|
||||
#elif defined(PLATFORM_LINUX)
|
||||
return SystemDialog_Linux(type, title, message);
|
||||
#else
|
||||
return SystemDialog_Other(type, title, message);
|
||||
#endif
|
||||
}
|
||||
|
||||
SystemTimeStamp* CreateTimeStamp()
|
||||
CSystemUtils* CSystemUtils::Create()
|
||||
{
|
||||
assert(m_instance == nullptr);
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
m_instance = new CSystemUtilsWindows();
|
||||
#elif defined(PLATFORM_LINUX)
|
||||
m_instance = new CSystemUtilsLinux();
|
||||
#else
|
||||
m_instance = new CSystemUtilsOther();
|
||||
#endif
|
||||
return m_instance;
|
||||
}
|
||||
|
||||
SystemDialogResult CSystemUtils::ConsoleSystemDialog(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;
|
||||
}
|
||||
|
||||
SystemTimeStamp* CSystemUtils::CreateTimeStamp()
|
||||
{
|
||||
return new SystemTimeStamp();
|
||||
}
|
||||
|
||||
void DestroyTimeStamp(SystemTimeStamp *stamp)
|
||||
void CSystemUtils::DestroyTimeStamp(SystemTimeStamp *stamp)
|
||||
{
|
||||
delete stamp;
|
||||
}
|
||||
|
||||
void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src)
|
||||
void CSystemUtils::CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src)
|
||||
{
|
||||
*dst = *src;
|
||||
}
|
||||
|
||||
void GetCurrentTimeStamp(SystemTimeStamp *stamp)
|
||||
float CSystemUtils::GetTimeStampResolution(SystemTimeUnit unit)
|
||||
{
|
||||
#if defined(PLATFORM_WINDOWS)
|
||||
GetCurrentTimeStamp_Windows(stamp);
|
||||
#elif defined(PLATFORM_LINUX)
|
||||
GetCurrentTimeStamp_Linux(stamp);
|
||||
#else
|
||||
GetCurrentTimeStamp_Other(stamp);
|
||||
#endif
|
||||
}
|
||||
|
||||
float 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
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
//! Destroys a time stamp object
|
||||
void DestroyTimeStamp(SystemTimeStamp *stamp);
|
||||
public:
|
||||
//! Creates system utils for specific platform
|
||||
static CSystemUtils* Create();
|
||||
|
||||
//! Copies the time stamp from \a src to \a dst
|
||||
void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src);
|
||||
//! Performs platform-specific initialization
|
||||
virtual void Init() = 0;
|
||||
|
||||
//! Returns a time stamp associated with current time
|
||||
void GetCurrentTimeStamp(SystemTimeStamp *stamp);
|
||||
//! Displays a system dialog
|
||||
virtual SystemDialogResult SystemDialog(SystemDialogType, const std::string &title, const std::string &message) = 0;
|
||||
|
||||
//! Returns the platform's expected time stamp resolution
|
||||
float GetTimeStampResolution(SystemTimeUnit unit = STU_SEC);
|
||||
//! Displays a fallback system dialog using console
|
||||
TEST_VIRTUAL SystemDialogResult ConsoleSystemDialog(SystemDialogType type, const std::string& title, const std::string& message);
|
||||
|
||||
//! Returns the platform's exact (in nanosecond units) expected time stamp resolution
|
||||
long long GetTimeStampExactResolution();
|
||||
//! Creates a new time stamp object
|
||||
TEST_VIRTUAL SystemTimeStamp* CreateTimeStamp();
|
||||
|
||||
//! 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);
|
||||
//! Destroys a time stamp object
|
||||
TEST_VIRTUAL void DestroyTimeStamp(SystemTimeStamp *stamp);
|
||||
|
||||
//! Returns the exact (in nanosecond units) difference between two timestamps
|
||||
/** The difference is \a after - \a before. */
|
||||
long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after);
|
||||
//! Copies the time stamp from \a src to \a dst
|
||||
TEST_VIRTUAL void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src);
|
||||
|
||||
//! Returns a time stamp associated with current time
|
||||
virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) = 0;
|
||||
|
||||
//! Returns the platform's expected time stamp resolution
|
||||
TEST_VIRTUAL float GetTimeStampResolution(SystemTimeUnit unit = STU_SEC);
|
||||
|
||||
//! 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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -35,9 +35,17 @@ struct SystemTimeStamp
|
|||
}
|
||||
};
|
||||
|
||||
class CSystemUtilsLinux : public CSystemUtils
|
||||
{
|
||||
public:
|
||||
virtual void Init() override;
|
||||
|
||||
SystemDialogResult SystemDialog_Linux(SystemDialogType type, const std::string& title, const std::string& message);
|
||||
virtual SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
|
||||
|
||||
void GetCurrentTimeStamp_Linux(SystemTimeStamp *stamp);
|
||||
long long GetTimeStampExactResolution_Linux();
|
||||
long long TimeStampExactDiff_Linux(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:
|
||||
bool m_zenityAvailable;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -17,30 +17,25 @@
|
|||
|
||||
#include "app/system_windows.h"
|
||||
|
||||
#include "common/logger.h"
|
||||
|
||||
// Convert a wide Unicode string to an UTF8 string
|
||||
std::string UTF8_Encode_Windows(const std::wstring &wstr)
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
void CSystemUtilsWindows::Init()
|
||||
{
|
||||
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;
|
||||
LARGE_INTEGER freq;
|
||||
QueryPerformanceFrequency(&freq);
|
||||
m_counterFrequency = freq.QuadPart;
|
||||
|
||||
assert(m_counterFrequency != 0);
|
||||
}
|
||||
|
||||
// Convert an UTF8 string to a wide Unicode String
|
||||
std::wstring UTF8_Decode_Windows(const std::string &str)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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 GetCurrentTimeStamp_Windows(SystemTimeStamp *stamp)
|
||||
void CSystemUtilsWindows::GetCurrentTimeStamp(SystemTimeStamp* stamp)
|
||||
{
|
||||
GetSystemTimeAsFileTime(&stamp->fileTime);
|
||||
LARGE_INTEGER value;
|
||||
QueryPerformanceCounter(&value);
|
||||
stamp->counterValue = value.QuadPart;
|
||||
}
|
||||
|
||||
long long GetTimeStampExactResolution_Windows()
|
||||
long long int CSystemUtilsWindows::GetTimeStampExactResolution()
|
||||
{
|
||||
return 100ll;
|
||||
return 1000000000ll / m_counterFrequency;
|
||||
}
|
||||
|
||||
long long TimeStampExactDiff_Windows(SystemTimeStamp *before, SystemTimeStamp *after)
|
||||
long long int CSystemUtilsWindows::TimeStampExactDiff(SystemTimeStamp* before, SystemTimeStamp* after)
|
||||
{
|
||||
long long tH = (1ll << 32) * (after->fileTime.dwHighDateTime - before->fileTime.dwHighDateTime);
|
||||
long long tL = after->fileTime.dwLowDateTime - before->fileTime.dwLowDateTime;
|
||||
return (tH + tL) * 100ll;
|
||||
float floatValue = static_cast<double>(after->counterValue - before->counterValue) * (1e9 / static_cast<double>(m_counterFrequency));
|
||||
return static_cast<long long>(floatValue);
|
||||
}
|
||||
|
||||
//! Converts a wide Unicode string to an UTF8 string
|
||||
std::string CSystemUtilsWindows::UTF8_Encode(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;
|
||||
}
|
||||
|
||||
//! Converts an UTF8 string to a wide Unicode String
|
||||
std::wstring CSystemUtilsWindows::UTF8_Decode(const std::string& str)
|
||||
{
|
||||
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;
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
void GetCurrentTimeStamp_Windows(SystemTimeStamp *stamp);
|
||||
long long GetTimeStampExactResolution_Windows();
|
||||
long long TimeStampExactDiff_Windows(SystemTimeStamp *before, SystemTimeStamp *after);
|
||||
virtual SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
};
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -40,3 +40,8 @@ std::string CApplication::GetDataDirPath()
|
|||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
Event CApplication::CreateUpdateEvent()
|
||||
{
|
||||
return Event(EVENT_NULL);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue