1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2024-11-08 08:47:17 +01:00
SqMod/source/Library/Chrono.cpp
Sandu Liviu Catalin b818a162ee Initial implementation of the standard math library.
Implemented utilities to convert between fundamental types.
Implemented helper functions to retrieve numeric values from the stack at all costs.
Implemented various delegates on the long integer types to mimic the standard types.
Moved most of the stack utilities in a separate source.
Various other fixes and improvements.
2016-04-14 03:08:06 +03:00

198 lines
6.1 KiB
C++

// ------------------------------------------------------------------------------------------------
#include "Library/Chrono.hpp"
#include "Library/Chrono/Date.hpp"
#include "Library/Chrono/Datetime.hpp"
#include "Library/Chrono/Time.hpp"
#include "Library/Chrono/Timer.hpp"
#include "Library/Chrono/Timestamp.hpp"
#include "Library/Numeric.hpp"
#include "Base/Shared.hpp"
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
#include <windows.h>
#else
#include <time.h>
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
namespace SqMod {
// ------------------------------------------------------------------------------------------------
#ifdef SQMOD_OS_WINDOWS
/* ------------------------------------------------------------------------------------------------
* Used by GetCurrentSysTime to obtain the system frequency on initial call.
*/
LARGE_INTEGER GetFrequency()
{
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
return frequency;
}
// ------------------------------------------------------------------------------------------------
Int64 GetCurrentSysTime()
{
// Force the following code to run on first core
// (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx)
HANDLE current_thread = GetCurrentThread();
DWORD_PTR previous_mask = SetThreadAffinityMask(current_thread, 1);
// Get the frequency of the performance counter
// (it is constant across the program lifetime)
static const LARGE_INTEGER frequency = GetFrequency();
// Get the current time
LARGE_INTEGER time;
QueryPerformanceCounter(&time);
// Restore the thread affinity
SetThreadAffinityMask(current_thread, previous_mask);
// Return the current time as microseconds
return Int64(1000000LL * time.QuadPart / frequency.QuadPart);
}
// ------------------------------------------------------------------------------------------------
Int64 GetEpochTimeMicro()
{
FILETIME ft;
GetSystemTimeAsFileTime(&ft);
// Extract the nanoseconds from the resulted timestamp
Uint64 time = ft.dwHighDateTime;
time <<= 32;
time |= ft.dwLowDateTime;
time /= 10;
time -= 11644473600000000ULL;
// Return the resulted timestamp
return Int64(time);
}
// ------------------------------------------------------------------------------------------------
Uint32 GetTickCount()
{
return GetTickCount();
}
// ------------------------------------------------------------------------------------------------
Int64 GetTickCount64()
{
#ifdef _SQ64
return GetTickCount64();
#else
return 0; // Should we fallback to 32 bit?
#endif // _SQ64
}
#else
// ------------------------------------------------------------------------------------------------
Int64 GetCurrentSysTime()
{
// POSIX implementation
timespec time;
clock_gettime(CLOCK_MONOTONIC, &time);
return Int64(Uint64(time.tv_sec) * 1000000 + time.tv_nsec / 1000);
}
// ------------------------------------------------------------------------------------------------
Int64 GetEpochTimeMicro()
{
// POSIX implementation
timespec time;
clock_gettime(CLOCK_REALTIME, &time);
return Int64(Uint64(time.tv_sec) * 1000000 + time.tv_nsec / 1000);
}
// ------------------------------------------------------------------------------------------------
Uint32 GetTickCount()
{
// POSIX implementation
struct timespec time;
if (clock_gettime(CLOCK_MONOTONIC, &time))
{
return 0;
}
return time.tv_sec * 1000.0 + time.tv_nsec / 1000000.0;
}
// ------------------------------------------------------------------------------------------------
Int64 GetTickCount64()
{
struct timespec time;
if (clock_gettime(CLOCK_MONOTONIC, &time))
{
return 0;
}
return time.tv_sec * 1000.0 + time.tv_nsec / 1000000.0;
}
#endif // SQMOD_OS_WINDOWS
// ------------------------------------------------------------------------------------------------
Int64 GetEpochTimeMilli()
{
return (GetEpochTimeMicro() / 1000L);
}
// ------------------------------------------------------------------------------------------------
static SLongInt SqGetEpochTimeMicro()
{
return SLongInt(GetEpochTimeMicro());
}
// ------------------------------------------------------------------------------------------------
static SLongInt SqGetEpochTimeMilli()
{
return SLongInt(GetEpochTimeMilli());
}
// ------------------------------------------------------------------------------------------------
static SLongInt SqGetCurrentSysTime()
{
return SLongInt(GetCurrentSysTime());
}
// ------------------------------------------------------------------------------------------------
static SQInteger SqGetTickCount()
{
return GetTickCount();
}
// ------------------------------------------------------------------------------------------------
static SLongInt SqGetTickCount64()
{
return SLongInt(GetTickCount64());
}
// ------------------------------------------------------------------------------------------------
extern void Register_ChronoDate(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoDatetime(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoTime(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoTimer(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoTimestamp(HSQUIRRELVM vm, Table & cns);
// ================================================================================================
void Register_Chrono(HSQUIRRELVM vm)
{
Table cns(vm);
Register_ChronoDate(vm, cns);
Register_ChronoDatetime(vm, cns);
Register_ChronoTime(vm, cns);
Register_ChronoTimer(vm, cns);
Register_ChronoTimestamp(vm, cns);
cns
.Func(_SC("EpochMicro"), &SqGetEpochTimeMicro)
.Func(_SC("EpochMilli"), &SqGetEpochTimeMilli)
.Func(_SC("Current"), &SqGetCurrentSysTime)
.Func(_SC("TickCount"), &SqGetTickCount)
.Func(_SC("TickCount64"), &SqGetTickCount64);
RootTable(vm).Bind(_SC("SqChrono"), cns);
}
} // Namespace:: SqMod