summaryrefslogtreecommitdiffstats
path: root/src/app
diff options
context:
space:
mode:
Diffstat (limited to 'src/app')
-rw-r--r--src/app/app.cpp133
-rw-r--r--src/app/app.h2
-rw-r--r--src/app/main.cpp32
-rw-r--r--src/app/system.cpp185
-rw-r--r--src/app/system.h90
-rw-r--r--src/app/system_linux.cpp25
-rw-r--r--src/app/system_linux.h16
-rw-r--r--src/app/system_other.cpp93
-rw-r--r--src/app/system_other.h13
-rw-r--r--src/app/system_windows.cpp64
-rw-r--r--src/app/system_windows.h29
11 files changed, 370 insertions, 312 deletions
diff --git a/src/app/app.cpp b/src/app/app.cpp
index e84091b..9349cbf 100644
--- a/src/app/app.cpp
+++ b/src/app/app.cpp
@@ -125,14 +125,14 @@ CApplication::CApplication()
m_absTime = 0.0f;
m_relTime = 0.0f;
- m_baseTimeStamp = CreateTimeStamp();
- m_curTimeStamp = CreateTimeStamp();
- m_lastTimeStamp = CreateTimeStamp();
+ m_baseTimeStamp = GetSystemUtils()->CreateTimeStamp();
+ m_curTimeStamp = GetSystemUtils()->CreateTimeStamp();
+ m_lastTimeStamp = GetSystemUtils()->CreateTimeStamp();
for (int i = 0; i < PCNT_MAX; ++i)
{
- m_performanceCounters[i][0] = CreateTimeStamp();
- m_performanceCounters[i][1] = CreateTimeStamp();
+ m_performanceCounters[i][0] = GetSystemUtils()->CreateTimeStamp();
+ m_performanceCounters[i][1] = GetSystemUtils()->CreateTimeStamp();
}
m_joystickEnabled = false;
@@ -177,14 +177,14 @@ CApplication::~CApplication()
delete m_iMan;
m_iMan = nullptr;
- DestroyTimeStamp(m_baseTimeStamp);
- DestroyTimeStamp(m_curTimeStamp);
- DestroyTimeStamp(m_lastTimeStamp);
+ GetSystemUtils()->DestroyTimeStamp(m_baseTimeStamp);
+ GetSystemUtils()->DestroyTimeStamp(m_curTimeStamp);
+ GetSystemUtils()->DestroyTimeStamp(m_lastTimeStamp);
for (int i = 0; i < PCNT_MAX; ++i)
{
- DestroyTimeStamp(m_performanceCounters[i][0]);
- DestroyTimeStamp(m_performanceCounters[i][1]);
+ GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][0]);
+ GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][1]);
}
}
@@ -199,8 +199,8 @@ CSoundInterface* CApplication::GetSound()
for (int i = 0; i < PCNT_MAX; ++i)
{
- DestroyTimeStamp(m_performanceCounters[i][0]);
- DestroyTimeStamp(m_performanceCounters[i][1]);
+ GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][0]);
+ GetSystemUtils()->DestroyTimeStamp(m_performanceCounters[i][1]);
}
}
@@ -607,7 +607,7 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig)
std::string(SDL_GetError()) + std::string("\n") +
std::string("Previous mode will be restored");
GetLogger()->Error(error.c_str());
- SystemDialog( SDT_ERROR, "COLOBT - Error", error);
+ GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Error", error);
restore = true;
ChangeVideoConfig(m_lastDeviceConfig);
@@ -620,7 +620,7 @@ bool CApplication::ChangeVideoConfig(const Gfx::GLDeviceConfig &newConfig)
std::string error = std::string("SDL error while restoring previous video mode:\n") +
std::string(SDL_GetError());
GetLogger()->Error(error.c_str());
- SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error);
+ GetSystemUtils()->SystemDialog( SDT_ERROR, "COLOBT - Fatal Error", error);
// Fatal error, so post the quit event
@@ -755,9 +755,9 @@ int CApplication::Run()
{
m_active = true;
- GetCurrentTimeStamp(m_baseTimeStamp);
- GetCurrentTimeStamp(m_lastTimeStamp);
- GetCurrentTimeStamp(m_curTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_lastTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_curTimeStamp);
MoveMouse(Math::Point(0.5f, 0.5f)); // center mouse on start
@@ -1109,49 +1109,49 @@ bool CApplication::ProcessEvent(const Event &event)
{
case EVENT_KEY_DOWN:
case EVENT_KEY_UP:
- l->Info("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP");
- l->Info(" virt = %s\n", (event.key.virt) ? "true" : "false");
- l->Info(" key = %d\n", event.key.key);
- l->Info(" unicode = 0x%04x\n", event.key.unicode);
+ l->Trace("EVENT_KEY_%s:\n", (event.type == EVENT_KEY_DOWN) ? "DOWN" : "UP");
+ l->Trace(" virt = %s\n", (event.key.virt) ? "true" : "false");
+ l->Trace(" key = %d\n", event.key.key);
+ l->Trace(" unicode = 0x%04x\n", event.key.unicode);
break;
case EVENT_MOUSE_MOVE:
- l->Info("EVENT_MOUSE_MOVE:\n");
+ l->Trace("EVENT_MOUSE_MOVE:\n");
break;
case EVENT_MOUSE_BUTTON_DOWN:
case EVENT_MOUSE_BUTTON_UP:
- l->Info("EVENT_MOUSE_BUTTON_%s:\n", (event.type == EVENT_MOUSE_BUTTON_DOWN) ? "DOWN" : "UP");
- l->Info(" button = %d\n", event.mouseButton.button);
+ l->Trace("EVENT_MOUSE_BUTTON_%s:\n", (event.type == EVENT_MOUSE_BUTTON_DOWN) ? "DOWN" : "UP");
+ l->Trace(" button = %d\n", event.mouseButton.button);
break;
case EVENT_MOUSE_WHEEL:
- l->Info("EVENT_MOUSE_WHEEL:\n");
- l->Info(" dir = %s\n", (event.mouseWheel.dir == WHEEL_DOWN) ? "WHEEL_DOWN" : "WHEEL_UP");
+ l->Trace("EVENT_MOUSE_WHEEL:\n");
+ l->Trace(" dir = %s\n", (event.mouseWheel.dir == WHEEL_DOWN) ? "WHEEL_DOWN" : "WHEEL_UP");
break;
case EVENT_JOY_AXIS:
- l->Info("EVENT_JOY_AXIS:\n");
- l->Info(" axis = %d\n", event.joyAxis.axis);
- l->Info(" value = %d\n", event.joyAxis.value);
+ l->Trace("EVENT_JOY_AXIS:\n");
+ l->Trace(" axis = %d\n", event.joyAxis.axis);
+ l->Trace(" value = %d\n", event.joyAxis.value);
break;
case EVENT_JOY_BUTTON_DOWN:
case EVENT_JOY_BUTTON_UP:
- l->Info("EVENT_JOY_BUTTON_%s:\n", (event.type == EVENT_JOY_BUTTON_DOWN) ? "DOWN" : "UP");
- l->Info(" button = %d\n", event.joyButton.button);
+ l->Trace("EVENT_JOY_BUTTON_%s:\n", (event.type == EVENT_JOY_BUTTON_DOWN) ? "DOWN" : "UP");
+ l->Trace(" button = %d\n", event.joyButton.button);
break;
case EVENT_ACTIVE:
- l->Info("EVENT_ACTIVE:\n");
- l->Info(" flags = 0x%x\n", event.active.flags);
- l->Info(" gain = %s\n", event.active.gain ? "true" : "false");
+ l->Trace("EVENT_ACTIVE:\n");
+ l->Trace(" flags = 0x%x\n", event.active.flags);
+ l->Trace(" gain = %s\n", event.active.gain ? "true" : "false");
break;
default:
- l->Info("Event type = %d:\n", static_cast<int>(event.type));
+ l->Trace("Event type = %d:\n", static_cast<int>(event.type));
break;
}
- l->Info(" systemEvent = %s\n", event.systemEvent ? "true" : "false");
- l->Info(" rTime = %f\n", event.rTime);
- l->Info(" kmodState = %04x\n", event.kmodState);
- l->Info(" trackedKeysState = %04x\n", event.trackedKeysState);
- l->Info(" mousePos = %f, %f\n", event.mousePos.x, event.mousePos.y);
- l->Info(" mouseButtonsState = %02x\n", event.mouseButtonsState);
+ l->Trace(" systemEvent = %s\n", event.systemEvent ? "true" : "false");
+ l->Trace(" rTime = %f\n", event.rTime);
+ l->Trace(" kmodState = %04x\n", event.kmodState);
+ l->Trace(" trackedKeysState = %04x\n", event.trackedKeysState);
+ l->Trace(" mousePos = %f, %f\n", event.mousePos.x, event.mousePos.y);
+ l->Trace(" mouseButtonsState = %02x\n", event.mouseButtonsState);
}
// By default, pass on all events
@@ -1219,8 +1219,8 @@ void CApplication::ResumeSimulation()
{
m_simulationSuspended = false;
- GetCurrentTimeStamp(m_baseTimeStamp);
- CopyTimeStamp(m_curTimeStamp, m_baseTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp);
+ GetSystemUtils()->CopyTimeStamp(m_curTimeStamp, m_baseTimeStamp);
m_realAbsTimeBase = m_realAbsTime;
m_absTimeBase = m_exactAbsTime;
@@ -1236,7 +1236,7 @@ void CApplication::SetSimulationSpeed(float speed)
{
m_simulationSpeed = speed;
- GetCurrentTimeStamp(m_baseTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_baseTimeStamp);
m_realAbsTimeBase = m_realAbsTime;
m_absTimeBase = m_exactAbsTime;
@@ -1248,18 +1248,31 @@ Event CApplication::CreateUpdateEvent()
if (m_simulationSuspended)
return Event(EVENT_NULL);
- CopyTimeStamp(m_lastTimeStamp, m_curTimeStamp);
- GetCurrentTimeStamp(m_curTimeStamp);
+ GetSystemUtils()->CopyTimeStamp(m_lastTimeStamp, m_curTimeStamp);
+ GetSystemUtils()->GetCurrentTimeStamp(m_curTimeStamp);
- long long absDiff = TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp);
- m_realAbsTime = m_realAbsTimeBase + absDiff;
- // m_baseTimeStamp is updated on simulation speed change, so this is OK
- m_exactAbsTime = m_absTimeBase + m_simulationSpeed * absDiff;
- m_absTime = (m_absTimeBase + m_simulationSpeed * absDiff) / 1e9f;
+ long long absDiff = GetSystemUtils()->TimeStampExactDiff(m_baseTimeStamp, m_curTimeStamp);
+ long long newRealAbsTime = m_realAbsTimeBase + absDiff;
+ long long newRealRelTime = GetSystemUtils()->TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp);
- m_realRelTime = TimeStampExactDiff(m_lastTimeStamp, m_curTimeStamp);
- m_exactRelTime = m_simulationSpeed * m_realRelTime;
- m_relTime = (m_simulationSpeed * m_realRelTime) / 1e9f;
+ if (newRealAbsTime < m_realAbsTime || newRealRelTime < 0)
+ {
+ GetLogger()->Error("Fatal error: got negative system counter difference!\n");
+ GetLogger()->Error("This should never happen. Please report this error.\n");
+ m_eventQueue->AddEvent(Event(EVENT_QUIT));
+ return Event(EVENT_NULL);
+ }
+ else
+ {
+ m_realAbsTime = newRealAbsTime;
+ // m_baseTimeStamp is updated on simulation speed change, so this is OK
+ m_exactAbsTime = m_absTimeBase + m_simulationSpeed * absDiff;
+ m_absTime = (m_absTimeBase + m_simulationSpeed * absDiff) / 1e9f;
+
+ m_realRelTime = newRealRelTime;
+ m_exactRelTime = m_simulationSpeed * m_realRelTime;
+ m_relTime = (m_simulationSpeed * m_realRelTime) / 1e9f;
+ }
Event frameEvent(EVENT_FRAME);
frameEvent.systemEvent = true;
@@ -1651,12 +1664,12 @@ bool CApplication::GetLowCPU()
void CApplication::StartPerformanceCounter(PerformanceCounter counter)
{
- GetCurrentTimeStamp(m_performanceCounters[counter][0]);
+ GetSystemUtils()->GetCurrentTimeStamp(m_performanceCounters[counter][0]);
}
void CApplication::StopPerformanceCounter(PerformanceCounter counter)
{
- GetCurrentTimeStamp(m_performanceCounters[counter][1]);
+ GetSystemUtils()->GetCurrentTimeStamp(m_performanceCounters[counter][1]);
}
float CApplication::GetPerformanceCounterData(PerformanceCounter counter)
@@ -1675,13 +1688,13 @@ void CApplication::ResetPerformanceCounters()
void CApplication::UpdatePerformanceCountersData()
{
- long long sum = TimeStampExactDiff(m_performanceCounters[PCNT_ALL][0],
- m_performanceCounters[PCNT_ALL][1]);
+ long long sum = GetSystemUtils()->TimeStampExactDiff(m_performanceCounters[PCNT_ALL][0],
+ m_performanceCounters[PCNT_ALL][1]);
for (int i = 0; i < PCNT_MAX; ++i)
{
- long long diff = TimeStampExactDiff(m_performanceCounters[i][0],
- m_performanceCounters[i][1]);
+ long long diff = GetSystemUtils()->TimeStampExactDiff(m_performanceCounters[i][0],
+ m_performanceCounters[i][1]);
m_performanceCountersData[static_cast<PerformanceCounter>(i)] =
static_cast<float>(diff) / static_cast<float>(sum);
diff --git a/src/app/app.h b/src/app/app.h
index 71a3527..d2561e7 100644
--- a/src/app/app.h
+++ b/src/app/app.h
@@ -352,7 +352,7 @@ protected:
//! If applicable, creates a virtual event to match the changed state as of new event
Event CreateVirtualEvent(const Event& sourceEvent);
//! Prepares a simulation update event
- Event CreateUpdateEvent();
+ TEST_VIRTUAL Event CreateUpdateEvent();
//! Handles some incoming events
bool ProcessEvent(const Event& event);
//! Renders the image in window
diff --git a/src/app/main.cpp b/src/app/main.cpp
index 0622370..edb5828 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -76,40 +76,46 @@ extern "C"
int SDL_MAIN_FUNC(int argc, char *argv[])
{
- CLogger logger; // Create the logger
+ CLogger logger; // single istance of logger
- InitializeRestext(); // Initialize translation strings
+ InitializeRestext(); // init static translation strings
+
+ CSystemUtils* systemUtils = CSystemUtils::Create(); // platform-specific utils
+ systemUtils->Init();
logger.Info("Colobot starting\n");
- CApplication app; // single instance of the application
+ CApplication* app = new CApplication(); // single instance of the application
- ParseArgsStatus status = app.ParseArguments(argc, argv);
+ ParseArgsStatus status = app->ParseArguments(argc, argv);
if (status == PARSE_ARGS_FAIL)
{
- SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
- return app.GetExitCode();
+ systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", "Invalid commandline arguments!\n");
+ return app->GetExitCode();
}
else if (status == PARSE_ARGS_HELP)
{
- return app.GetExitCode();
+ return app->GetExitCode();
}
int code = 0;
- if (! app.Create())
+ if (! app->Create())
{
- app.Destroy(); // ensure a clean exit
- code = app.GetExitCode();
- if ( code != 0 && !app.GetErrorMessage().empty() )
+ app->Destroy(); // ensure a clean exit
+ code = app->GetExitCode();
+ if ( code != 0 && !app->GetErrorMessage().empty() )
{
- SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app.GetErrorMessage());
+ systemUtils->SystemDialog(SDT_ERROR, "COLOBOT - Fatal Error", app->GetErrorMessage());
}
logger.Info("Didn't run main loop. Exiting with code %d\n", code);
return code;
}
- code = app.Run();
+ code = app->Run();
+
+ delete app;
+ delete systemUtils;
logger.Info("Exiting with code %d\n", code);
return code;
diff --git a/src/app/system.cpp b/src/app/system.cpp
index 73614aa..6927af8 100644
--- a/src/app/system.cpp
+++ b/src/app/system.cpp
@@ -22,75 +22,142 @@
#if defined(PLATFORM_WINDOWS)
-#include "app/system_windows.h"
-
+ #include "app/system_windows.h"
#elif defined(PLATFORM_LINUX)
-#include "app/system_linux.h"
-
+ #include "app/system_linux.h"
#else
-#include "app/system_other.h"
-
+ #include "app/system_other.h"
#endif
-
#include <cassert>
+#include <iostream>
+
+
+template<>
+CSystemUtils* CSingleton<CSystemUtils>::m_instance = nullptr;
-/**
- * Displays a system dialog with info, error, question etc. message.
- *
- * \param type type of dialog
- * \param message text of message (in UTF-8)
- * \param title dialog title (in UTF-8)
- * \returns result (which button was clicked)
- */
-SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
+CSystemUtils::CSystemUtils()
{
+}
+
+CSystemUtils* CSystemUtils::Create()
+{
+ assert(m_instance == nullptr);
#if defined(PLATFORM_WINDOWS)
- return SystemDialog_Windows(type, title, message);
+ m_instance = new CSystemUtilsWindows();
#elif defined(PLATFORM_LINUX)
- return SystemDialog_Linux(type, title, message);
+ m_instance = new CSystemUtilsLinux();
#else
- return SystemDialog_Other(type, title, message);
+ m_instance = new CSystemUtilsOther();
#endif
+ return m_instance;
}
-SystemTimeStamp* CreateTimeStamp()
+SystemDialogResult CSystemUtils::ConsoleSystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
{
- return new SystemTimeStamp();
+ switch (type)
+ {
+ case SDT_INFO:
+ std::cout << "INFO: ";
+ break;
+ case SDT_WARNING:
+ std::cout << "WARNING:";
+ break;
+ case SDT_ERROR:
+ std::cout << "ERROR: ";
+ break;
+ case SDT_YES_NO:
+ case SDT_OK_CANCEL:
+ std::cout << "QUESTION: ";
+ break;
+ }
+
+ std::cout << message << std::endl;
+
+ std::string line;
+
+ SystemDialogResult result = SDR_OK;
+
+ bool done = false;
+ while (!done)
+ {
+ switch (type)
+ {
+ case SDT_INFO:
+ case SDT_WARNING:
+ case SDT_ERROR:
+ std::cout << "Press ENTER to continue";
+ break;
+
+ case SDT_YES_NO:
+ std::cout << "Type 'Y' for Yes or 'N' for No";
+ break;
+
+ case SDT_OK_CANCEL:
+ std::cout << "Type 'O' for OK or 'C' for Cancel";
+ break;
+ }
+
+ std::getline(std::cin, line);
+
+ switch (type)
+ {
+ case SDT_INFO:
+ case SDT_WARNING:
+ case SDT_ERROR:
+ done = true;
+ break;
+
+ case SDT_YES_NO:
+ if (line == "Y" || line == "y")
+ {
+ result = SDR_YES;
+ done = true;
+ }
+ else if (line == "N" || line == "n")
+ {
+ result = SDR_NO;
+ done = true;
+ }
+ break;
+
+ case SDT_OK_CANCEL:
+ if (line == "O" || line == "o")
+ {
+ done = true;
+ result = SDR_OK;
+ }
+ else if (line == "C" || line == "c")
+ {
+ done = true;
+ result = SDR_CANCEL;
+ }
+ break;
+ }
+ }
+
+ return result;
}
-void DestroyTimeStamp(SystemTimeStamp *stamp)
+SystemTimeStamp* CSystemUtils::CreateTimeStamp()
{
- delete stamp;
+ return new SystemTimeStamp();
}
-void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src)
+void CSystemUtils::DestroyTimeStamp(SystemTimeStamp *stamp)
{
- *dst = *src;
+ delete stamp;
}
-void GetCurrentTimeStamp(SystemTimeStamp *stamp)
+void CSystemUtils::CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src)
{
-#if defined(PLATFORM_WINDOWS)
- GetCurrentTimeStamp_Windows(stamp);
-#elif defined(PLATFORM_LINUX)
- GetCurrentTimeStamp_Linux(stamp);
-#else
- GetCurrentTimeStamp_Other(stamp);
-#endif
+ *dst = *src;
}
-float GetTimeStampResolution(SystemTimeUnit unit)
+float CSystemUtils::GetTimeStampResolution(SystemTimeUnit unit)
{
- unsigned long long exact = 0;
-#if defined(PLATFORM_WINDOWS)
- exact = GetTimeStampExactResolution_Windows();
-#elif defined(PLATFORM_LINUX)
- exact = GetTimeStampExactResolution_Linux();
-#else
- exact = GetTimeStampExactResolution_Other();
-#endif
+ unsigned long long exact = GetTimeStampExactResolution();
float result = 0.0f;
if (unit == STU_SEC)
result = exact * 1e-9;
@@ -100,30 +167,14 @@ float GetTimeStampResolution(SystemTimeUnit unit)
result = exact * 1e-3;
else
assert(false);
+
return result;
}
-long long GetTimeStampExactResolution()
+float CSystemUtils::TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeUnit unit)
{
-#if defined(PLATFORM_WINDOWS)
- return GetTimeStampExactResolution_Windows();
-#elif defined(PLATFORM_LINUX)
- return GetTimeStampExactResolution_Linux();
-#else
- return GetTimeStampExactResolution_Other();
-#endif
-}
+ long long exact = TimeStampExactDiff(before, after);
-float TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeUnit unit)
-{
- long long exact = 0;
-#if defined(PLATFORM_WINDOWS)
- exact = TimeStampExactDiff_Windows(before, after);
-#elif defined(PLATFORM_LINUX)
- exact = TimeStampExactDiff_Linux(before, after);
-#else
- exact = TimeStampExactDiff_Other(before, after);
-#endif
float result = 0.0f;
if (unit == STU_SEC)
result = exact * 1e-9;
@@ -133,16 +184,6 @@ float TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeU
result = exact * 1e-3;
else
assert(false);
- return result;
-}
-long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after)
-{
-#if defined(PLATFORM_WINDOWS)
- return TimeStampExactDiff_Windows(before, after);
-#elif defined(PLATFORM_LINUX)
- return TimeStampExactDiff_Linux(before, after);
-#else
- return TimeStampExactDiff_Other(before, after);
-#endif
+ return result;
}
diff --git a/src/app/system.h b/src/app/system.h
index e216842..278a4bf 100644
--- a/src/app/system.h
+++ b/src/app/system.h
@@ -22,12 +22,10 @@
#pragma once
+#include "common/singleton.h"
#include <string>
-
-/* Dialog utils */
-
/**
* \enum SystemDialogType
* \brief Type of system dialog
@@ -60,12 +58,10 @@ enum SystemDialogResult
SDR_NO
};
-//! Displays a system dialog
-SystemDialogResult SystemDialog(SystemDialogType, const std::string &title, const std::string &message);
-
-
-/* Time utils */
-
+/**
+ * \enum SystemTimeUnit
+ * \brief Time unit
+ */
enum SystemTimeUnit
{
//! seconds
@@ -76,33 +72,67 @@ enum SystemTimeUnit
STU_USEC
};
-/* Forward declaration of time stamp struct
- * SystemTimeStamp should be used in a pointer context.
- * The implementation details are hidden because of platform dependence. */
+/*
+ * Forward declaration of time stamp struct
+ * SystemTimeStamp should only be used in a pointer context.
+ * The implementation details are hidden because of platform dependence.
+ */
struct SystemTimeStamp;
-//! Creates a new time stamp object
-SystemTimeStamp* CreateTimeStamp();
+/**
+ * \class CSystemUtils
+ * \brief Platform-specific utils
+ *
+ * This class provides system-specific utilities like displaying user dialogs and
+ * querying system timers for exact timestamps.
+ */
+class CSystemUtils : public CSingleton<CSystemUtils>
+{
+protected:
+ CSystemUtils();
+
+public:
+ //! Creates system utils for specific platform
+ static CSystemUtils* Create();
+
+ //! Performs platform-specific initialization
+ virtual void Init() = 0;
+
+ //! Displays a system dialog
+ virtual SystemDialogResult SystemDialog(SystemDialogType, const std::string &title, const std::string &message) = 0;
-//! Destroys a time stamp object
-void DestroyTimeStamp(SystemTimeStamp *stamp);
+ //! Displays a fallback system dialog using console
+ TEST_VIRTUAL SystemDialogResult ConsoleSystemDialog(SystemDialogType type, const std::string& title, const std::string& message);
-//! Copies the time stamp from \a src to \a dst
-void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src);
+ //! Creates a new time stamp object
+ TEST_VIRTUAL SystemTimeStamp* CreateTimeStamp();
-//! Returns a time stamp associated with current time
-void GetCurrentTimeStamp(SystemTimeStamp *stamp);
+ //! Destroys a time stamp object
+ TEST_VIRTUAL void DestroyTimeStamp(SystemTimeStamp *stamp);
-//! Returns the platform's expected time stamp resolution
-float GetTimeStampResolution(SystemTimeUnit unit = STU_SEC);
+ //! Copies the time stamp from \a src to \a dst
+ TEST_VIRTUAL void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src);
-//! Returns the platform's exact (in nanosecond units) expected time stamp resolution
-long long GetTimeStampExactResolution();
+ //! Returns a time stamp associated with current time
+ virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) = 0;
-//! Returns a difference between two timestamps in given time unit
-/** The difference is \a after - \a before. */
-float TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeUnit unit = STU_SEC);
+ //! Returns the platform's expected time stamp resolution
+ TEST_VIRTUAL float GetTimeStampResolution(SystemTimeUnit unit = STU_SEC);
-//! Returns the exact (in nanosecond units) difference between two timestamps
-/** The difference is \a after - \a before. */
-long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after);
+ //! Returns the platform's exact (in nanosecond units) expected time stamp resolution
+ virtual long long GetTimeStampExactResolution() = 0;
+
+ //! Returns a difference between two timestamps in given time unit
+ /** The difference is \a after - \a before. */
+ TEST_VIRTUAL float TimeStampDiff(SystemTimeStamp *before, SystemTimeStamp *after, SystemTimeUnit unit = STU_SEC);
+
+ //! Returns the exact (in nanosecond units) difference between two timestamps
+ /** The difference is \a after - \a before. */
+ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) = 0;
+};
+
+//! Global function to get CSystemUtils instance
+inline CSystemUtils* GetSystemUtils()
+{
+ return CSystemUtils::GetInstancePointer();
+}
diff --git a/src/app/system_linux.cpp b/src/app/system_linux.cpp
index cd785f8..619909d 100644
--- a/src/app/system_linux.cpp
+++ b/src/app/system_linux.cpp
@@ -17,11 +17,28 @@
#include "app/system_linux.h"
+#include "common/logger.h"
+
#include <stdlib.h>
-SystemDialogResult SystemDialog_Linux(SystemDialogType type, const std::string& title, const std::string& message)
+void CSystemUtilsLinux::Init()
{
+ m_zenityAvailable = true;
+ if (system("zenity --version") != 0)
+ {
+ m_zenityAvailable = false;
+ GetLogger()->Warn("Zenity not available, will fallback to console users dialogs.\n");
+ }
+}
+
+SystemDialogResult CSystemUtilsLinux::SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
+{
+ if (!m_zenityAvailable)
+ {
+ return ConsoleSystemDialog(type, title, message);
+ }
+
std::string options = "";
switch (type)
{
@@ -62,17 +79,17 @@ SystemDialogResult SystemDialog_Linux(SystemDialogType type, const std::string&
return result;
}
-void GetCurrentTimeStamp_Linux(SystemTimeStamp *stamp)
+void CSystemUtilsLinux::GetCurrentTimeStamp(SystemTimeStamp *stamp)
{
clock_gettime(CLOCK_MONOTONIC_RAW, &stamp->clockTime);
}
-long long GetTimeStampExactResolution_Linux()
+long long CSystemUtilsLinux::GetTimeStampExactResolution()
{
return 1ll;
}
-long long TimeStampExactDiff_Linux(SystemTimeStamp *before, SystemTimeStamp *after)
+long long CSystemUtilsLinux::TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after)
{
return (after->clockTime.tv_nsec - before->clockTime.tv_nsec) +
(after->clockTime.tv_sec - before->clockTime.tv_sec) * 1000000000ll;
diff --git a/src/app/system_linux.h b/src/app/system_linux.h
index bc07c31..ba0d8cd 100644
--- a/src/app/system_linux.h
+++ b/src/app/system_linux.h
@@ -35,9 +35,17 @@ struct SystemTimeStamp
}
};
+class CSystemUtilsLinux : public CSystemUtils
+{
+public:
+ virtual void Init() override;
+
+ virtual SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
-SystemDialogResult SystemDialog_Linux(SystemDialogType type, const std::string& title, const std::string& message);
+ virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
+ virtual long long GetTimeStampExactResolution() override;
+ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
-void GetCurrentTimeStamp_Linux(SystemTimeStamp *stamp);
-long long GetTimeStampExactResolution_Linux();
-long long TimeStampExactDiff_Linux(SystemTimeStamp *before, SystemTimeStamp *after);
+private:
+ bool m_zenityAvailable;
+};
diff --git a/src/app/system_other.cpp b/src/app/system_other.cpp
index 006bf6d..9fc1f95 100644
--- a/src/app/system_other.cpp
+++ b/src/app/system_other.cpp
@@ -18,105 +18,22 @@
#include "app/system_other.h"
-SystemDialogResult SystemDialog_Other(SystemDialogType type, const std::string& title, const std::string& message)
+SystemDialogResult CSystemUtilsOther::SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
{
- switch (type)
- {
- case SDT_INFO:
- std::cout << "INFO: ";
- break;
- case SDT_WARNING:
- std::cout << "WARNING:";
- break;
- case SDT_ERROR:
- std::cout << "ERROR: ";
- break;
- case SDT_YES_NO:
- case SDT_OK_CANCEL:
- std::cout << "QUESTION: ";
- break;
- }
-
- std::cout << message << std::endl;
-
- std::string line;
-
- SystemDialogResult result = SDR_OK;
-
- bool done = false;
- while (!done)
- {
- switch (type)
- {
- case SDT_INFO:
- case SDT_WARNING:
- case SDT_ERROR:
- std::cout << "Press ENTER to continue";
- break;
-
- case SDT_YES_NO:
- std::cout << "Type 'Y' for Yes or 'N' for No";
- break;
-
- case SDT_OK_CANCEL:
- std::cout << "Type 'O' for OK or 'C' for Cancel";
- break;
- }
-
- std::getline(std::cin, line);
-
- switch (type)
- {
- case SDT_INFO:
- case SDT_WARNING:
- case SDT_ERROR:
- done = true;
- break;
-
- case SDT_YES_NO:
- if (line == "Y" || line == "y")
- {
- result = SDR_YES;
- done = true;
- }
- else if (line == "N" || line == "n")
- {
- result = SDR_NO;
- done = true;
- }
- break;
-
- case SDT_OK_CANCEL:
- if (line == "O" || line == "o")
- {
- done = true;
- result = SDR_OK;
- }
- else if (line == "C" || line == "c")
- {
- done = true;
- result = SDR_CANCEL;
- }
- break;
- }
- }
-
- return result;
+ return ConsoleSystemDialog(type, title, message);
}
-
-
-void GetCurrentTimeStamp_Other(SystemTimeStamp *stamp)
+void CSystemUtilsOther::GetCurrentTimeStamp(SystemTimeStamp* stamp)
{
stamp->sdlTicks = SDL_GetTicks();
}
-long long GetTimeStampExactResolution_Other()
+long long int CSystemUtilsOther::GetTimeStampExactResolution()
{
return 1000000ll;
}
-long long TimeStampExactDiff_Other(SystemTimeStamp *before, SystemTimeStamp *after)
+long long int CSystemUtilsOther::TimeStampExactDiff(SystemTimeStamp* before, SystemTimeStamp* after) const
{
return (after->sdlTicks - before->sdlTicks) * 1000000ll;
}
diff --git a/src/app/system_other.h b/src/app/system_other.h
index aee3536..bf16c80 100644
--- a/src/app/system_other.h
+++ b/src/app/system_other.h
@@ -37,9 +37,12 @@ struct SystemTimeStamp
}
};
+class CSystemUtilsOther : public CSystemUtils
+{
+public:
+ virtual SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
-SystemDialogResult SystemDialog_Other(SystemDialogType type, const std::string& title, const std::string& message);
-
-void GetCurrentTimeStamp_Other(SystemTimeStamp *stamp);
-long long GetTimeStampExactResolution_Other();
-long long TimeStampExactDiff_Other(SystemTimeStamp *before, SystemTimeStamp *after);
+ virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
+ virtual long long GetTimeStampExactResolution() override;
+ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
+};
diff --git a/src/app/system_windows.cpp b/src/app/system_windows.cpp
index 34fa57e..780afef 100644
--- a/src/app/system_windows.cpp
+++ b/src/app/system_windows.cpp
@@ -17,30 +17,25 @@
#include "app/system_windows.h"
+#include "common/logger.h"
+
+#include <windows.h>
-// Convert a wide Unicode string to an UTF8 string
-std::string UTF8_Encode_Windows(const std::wstring &wstr)
-{
- int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), NULL, 0, NULL, NULL);
- std::string strTo(size_needed, 0);
- WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), &strTo[0], size_needed, NULL, NULL);
- return strTo;
-}
-// Convert an UTF8 string to a wide Unicode String
-std::wstring UTF8_Decode_Windows(const std::string &str)
+void CSystemUtilsWindows::Init()
{
- int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), NULL, 0);
- std::wstring wstrTo(size_needed, 0);
- MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), &wstrTo[0], size_needed);
- return wstrTo;
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ m_counterFrequency = freq.QuadPart;
+
+ assert(m_counterFrequency != 0);
}
-SystemDialogResult SystemDialog_Windows(SystemDialogType type, const std::string& title, const std::string& message)
+SystemDialogResult CSystemUtilsWindows::SystemDialog(SystemDialogType type, const std::string& title, const std::string& message)
{
unsigned int windowsType = 0;
- std::wstring windowsMessage = UTF8_Decode_Windows(message);
- std::wstring windowsTitle = UTF8_Decode_Windows(title);
+ std::wstring windowsMessage = UTF8_Decode(message);
+ std::wstring windowsTitle = UTF8_Decode(title);
switch (type)
{
@@ -79,20 +74,39 @@ SystemDialogResult SystemDialog_Windows(SystemDialogType type, const std::string
return SDR_OK;
}
+void CSystemUtilsWindows::GetCurrentTimeStamp(SystemTimeStamp* stamp)
+{
+ LARGE_INTEGER value;
+ QueryPerformanceCounter(&value);
+ stamp->counterValue = value.QuadPart;
+}
+
+long long int CSystemUtilsWindows::GetTimeStampExactResolution()
+{
+ return 1000000000ll / m_counterFrequency;
+}
-void GetCurrentTimeStamp_Windows(SystemTimeStamp *stamp)
+long long int CSystemUtilsWindows::TimeStampExactDiff(SystemTimeStamp* before, SystemTimeStamp* after)
{
- GetSystemTimeAsFileTime(&stamp->fileTime);
+ float floatValue = static_cast<double>(after->counterValue - before->counterValue) * (1e9 / static_cast<double>(m_counterFrequency));
+ return static_cast<long long>(floatValue);
}
-long long GetTimeStampExactResolution_Windows()
+//! Converts a wide Unicode string to an UTF8 string
+std::string CSystemUtilsWindows::UTF8_Encode(const std::wstring& wstr)
{
- return 100ll;
+ int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), NULL, 0, NULL, NULL);
+ std::string strTo(size_needed, 0);
+ WideCharToMultiByte(CP_UTF8, 0, &wstr[0], static_cast<int>(wstr.size()), &strTo[0], size_needed, NULL, NULL);
+ return strTo;
}
-long long TimeStampExactDiff_Windows(SystemTimeStamp *before, SystemTimeStamp *after)
+//! Converts an UTF8 string to a wide Unicode String
+std::wstring CSystemUtilsWindows::UTF8_Decode(const std::string& str)
{
- long long tH = (1ll << 32) * (after->fileTime.dwHighDateTime - before->fileTime.dwHighDateTime);
- long long tL = after->fileTime.dwLowDateTime - before->fileTime.dwLowDateTime;
- return (tH + tL) * 100ll;
+ int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), NULL, 0);
+ std::wstring wstrTo(size_needed, 0);
+ MultiByteToWideChar(CP_UTF8, 0, &str[0], static_cast<int>(str.size()), &wstrTo[0], size_needed);
+ return wstrTo;
+
}
diff --git a/src/app/system_windows.h b/src/app/system_windows.h
index 804d064..e367b92 100644
--- a/src/app/system_windows.h
+++ b/src/app/system_windows.h
@@ -22,23 +22,32 @@
#include "app/system.h"
-#include <windows.h>
-
struct SystemTimeStamp
{
- FILETIME fileTime;
+ long long counterValue;
SystemTimeStamp()
{
- fileTime.dwHighDateTime = fileTime.dwLowDateTime = 0;
+ counterValue = 0;
}
};
-std::string UTF8_Encode_Windows(const std::wstring &wstr);
-std::wstring UTF8_Decode_Windows(const std::string &str);
-SystemDialogResult SystemDialog_Windows(SystemDialogType type, const std::string& title, const std::string& message);
+class CSystemUtilsWindows : public CSystemUtils
+{
+public:
+ virtual void Init() override;
+
+ virtual SystemDialogResult SystemDialog(SystemDialogType type, const std::string& title, const std::string& message) override;
-void GetCurrentTimeStamp_Windows(SystemTimeStamp *stamp);
-long long GetTimeStampExactResolution_Windows();
-long long TimeStampExactDiff_Windows(SystemTimeStamp *before, SystemTimeStamp *after);
+ virtual void GetCurrentTimeStamp(SystemTimeStamp *stamp) override;
+ virtual long long GetTimeStampExactResolution() override;
+ virtual long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after) override;
+
+private:
+ std::string UTF8_Encode(const std::wstring &wstr);
+ std::wstring UTF8_Decode(const std::string &str);
+
+protected:
+ long long m_counterFrequency;
+};