3

自 Mac 启动以来,我找到了一个获取毫秒数的函数:

U32 Platform::getRealMilliseconds()
{
   // Duration is a S32 value.
   // if negative, it is in microseconds.
   // if positive, it is in milliseconds.
   Duration durTime = AbsoluteToDuration(UpTime());
   U32 ret;
   if( durTime < 0 )
      ret = durTime / -1000;
   else 
      ret = durTime;

   return ret;
}

问题是,大约 20 天后,AbsoluteToDuration 一直返回 INT_MAX,直到 Mac 重新启动。

我尝试使用下面的方法,它有效,但看起来 gettimeofday 需要更多时间并且会减慢游戏速度:

timeval tim;
gettimeofday(&tim, NULL);
U32 ret = ((tim.tv_sec) * 1000 + tim.tv_usec/1000.0) + 0.5;

有没有更好的方法来获取自某个时期以来经过的毫秒数(最好是自应用程序启动以来)?

谢谢!

4

2 回答 2

4

我的首选方法是mach_absolute_time- 请参阅此技术说明- 我使用第二种方法,即mach_absolute_time获取时间戳并mach_timebase_info获取将时间戳之间的差异转换为实际时间值(具有纳秒分辨率)所需的常量。

于 2012-06-01T17:06:19.973 回答
4

您真正的问题是您正在尝试将正常运行时间(以毫秒为单位)值放入 32 位整数中。如果您这样做,无论您如何获得价值,您的价值将始终在 49 天或更短的时间内归零(或饱和)。

一种可能的解决方案是使用 64 位整数来跟踪时间值;这样算账的日子就会推迟几百年,所以你不必担心这个问题。这是它的 MacOS/X 实现:

uint64_t GetTimeInMillisecondsSinceBoot()
{
   return UnsignedWideToUInt64(AbsoluteToNanoseconds(UpTime()))/1000000;
}

...或者如果您不想返回 64 位时间值,则最好在程序启动时记录当前的毫秒时间值,然后始终从值中减去该值你回来。这样,在您自己的程序运行至少 49 天之前,事情不会中断,我认为这对于游戏来说不太可能。

uint32_t GetTimeInMillisecondsSinceProgramStart()
{
   static uint64_t _firstTimeMillis = GetTimeInMillisecondsSinceBoot();
   uint64_t nowMillis = GetTimeInMillisecondsSinceBoot();
   return (uint32_t) (nowMillis-_firstTimeMillis);
}
于 2012-06-01T16:51:59.047 回答