// This prevent inclusion of winsock.h in Windows.h, which prevents windows redifinition errors // Look at winsock2.h for details, winsock2.h is #included from boost.hpp & other places. #ifdef _WIN32 #define _WINSOCKAPI_ #endif #if defined(__linux) || defined(__APPLE__) #include #include #include #endif #include "time.hpp" #include "Debug.hpp" #include "atomic.hpp" #include #include "FastLog.hpp" #include #ifdef __APPLE__ #include #include #endif #ifdef __ANDROID__ #include #endif #if defined(_WIN32) && !defined(AYA_PLATFORM_DURANGO) #include #include #endif FASTINTVARIABLE(SpeedTestPeriodMillis, 1000) FASTINTVARIABLE(MaxSpeedDeltaMillis, 300) FASTINTVARIABLE(SpeedCountCap, 5) namespace Aya { long long Time::getTickCount() { #if defined(_WIN32) LARGE_INTEGER ticks; int rval = QueryPerformanceCounter(&ticks); return ticks.QuadPart; #elif defined(__APPLE__) uint64_t ticks = mach_absolute_time(); return ticks; #elif defined(__ANDROID__) || defined(__linux) timespec now; clock_gettime(CLOCK_MONOTONIC, &now); return now.tv_sec * 1e9 + now.tv_nsec; #endif } #if defined(_WIN32) static double getPerformanceFrequency() { static double frequency = 0.0; if (frequency == 0.0) { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); frequency = static_cast(freq.QuadPart); } return frequency; } #endif long long Time::getStart() { // not worried about potential multi-threaded double-init. // assumptions: underlying type is long long. static const long long start = getTickCount(); return start; } Time::SampleMethod Time::preciseOverride = Time::Precise; template<> Time Time::now() { Time result; #if defined(_WIN32) result.sec = static_cast(getTickCount() - getStart()) / getPerformanceFrequency(); #else result.sec = (getTickCount() - getStart()) * 1e-9; #endif return result; } template<> Time Time::now() { #if defined(_WIN32) && !defined(AYA_PLATFORM_DURANGO) return Time(timeGetTime() / 1000.0); #else // TODO: Is this fast enough on Mac? return now(); #endif } template<> Time Time::now() { return now(); } Time Time::nowFast() { return now(); } double Time::nowFastSec() { return Time::nowFast().timestampSeconds(); } template<> Time Time::now() { if (preciseOverride <= Benchmark) return now(); else return now(); } Time Time::now(SampleMethod sampleMethod) { switch (sampleMethod) { default: case Fast: return now(); case Precise: return now(); case Benchmark: return now(); case Multimedia: return now(); } } Time::Interval operator-(const Time& t1, const Time& t0) { const double seconds = t1.sec - t0.sec; return Time::Interval(seconds); } void Time::Interval::sleep() { #ifdef _WIN32 // Translate to milliseconds Sleep((int)(sec * 1e3)); #else // Translate to microseconds usleep((int)(sec * 1e6)); #endif } } // namespace Aya