stopwatch.h
来自「2002年」· C头文件 代码 · 共 217 行
H
217 行
#ifndef _STOPWATCH_H
#define _STOPWATCH_H
#ifdef WIN32
#include <winsock2.h>
#define INTEGER64 _int64
#else
#include <sys/time.h>
#define TIME_DIF_TO_MS(s,f) \
((f.tv_sec-s.tv_sec)*1000.0 + (f.tv_usec-s.tv_usec)*0.001)
#define INTEGER64 long long
#endif
#include "smp_datastruct.h"
const int Num_Time_Channels = 10; //the maximum num of channels
const int Num_Time_Events = 1; //the maximum num of events
const int Num_Cycles = 4; //the buffer size for a channel
//StopWatch Channels
/*
enum SW_Channel{
SW_CycleStart, //0
SW_Ctrl_UpdateStart, //1
SW_Info_Send_Notify, //2
SW_Ctrl_Recv_Notify, //3
SW_Recv_Visualinfo, //4
SW_Ctrl_Wake, //5
SW_Recv_Fullstateinfo, //6
SW_Ctrl_AIStart, //7
SW_Ctrl_AIExit, //8
SW_Recv_Soundinfo //9
};
*/
const int SW_CycleStart = 0;
const int SW_Ctrl_UpdateStart = 1;
const int SW_Info_Send_Notify = 2;
const int SW_Ctrl_Recv_Notify = 3;
const int SW_Recv_Visualinfo = 4;
const int SW_Ctrl_Wake = 5;
const int SW_Recv_Fullstateinfo = 6;
const int SW_Ctrl_AIStart = 7;
const int SW_Ctrl_AIExit = 8;
const int SW_Recv_Soundinfo = 9;
/*
enum SW_Event{
SW_Event_ChangeView
};
*/
const int SW_Event_ChangeView = 0;
#ifdef WIN32
typedef LARGE_INTEGER TIME_T;
#else // _LINUX
typedef struct timeval TIME_T;
#endif
union UniformTime{
struct timeval tv;
INTEGER64 QuadPart;
};
class Stopwatch{
protected:
INTEGER64 frequency; //system info for translating system counts into milisecond.
int current_cycle; //current cycle
TIME_T inittime; //time of starting program.
/* sometimes you can't identify the channel of a time,
so cache it before identification */
TIME_T cachetime;
/* Channels and Events' time buffer.
the only difference of event from channel is event is not cycle-based */
typedef TimedDataArray<TIME_T, Num_Cycles> _TDA;
_TDA Channels[Num_Time_Channels];
TIME_T Events[Num_Time_Events];
/*Millisecond between two times*/
inline float MsBetween(TIME_T& t1, TIME_T& t2){
#ifdef WIN32
return float(t2.QuadPart - t1.QuadPart)/frequency * 1000.0f;
#else
return float(TIME_DIF_TO_MS(t1,t2)) / correction_factor;
#endif
}
/*
* correction factor
* Depending on system, there might be systematic multiplicative error in measurement of time.
* We estimate that factor and use it to correct our measurement.
*/
float correction_factor;
public:
Stopwatch();
//set current cycle
inline void UpdateCycle(int cycle){
current_cycle = cycle;
}
//remember current time, you can identify it in the future
inline void Setcachetime(){
#ifdef WIN32
QueryPerformanceCounter(&cachetime);
#else // _LINUX
gettimeofday(&cachetime, NULL);
#endif
}
//Identify Cache Time as some channel in some cycle
inline void IdentifyCachetime(int no, int cycle){
Channels[no].Setdata(cachetime, cycle);
}
//Identify Cache Time as some channel in current cycle
inline void IdentifyCachetime(int no){
IdentifyCachetime(no, current_cycle);
}
//Time some channel of some cycle now
void TimeNow(int channel, int cycle);
//Time some channel of current cycle now
inline void TimeNow(int channel){
TimeNow(channel, current_cycle);
}
//Time an event now
void TimeEvent(int event);
/*The following set of functions are to compute the time gap between two times.
Most of functions are only for convenient call.
*/
//from channel1 of cycle1 to channel2 of cycle2
inline float MsBetween(int channel1, int cycle1, int channel2, int cycle2){
return MsBetween(Channels[channel1].Data(cycle1), Channels[channel2].Data(cycle2));
}
//from channel1 of current cycle to channel2 of current cycle
inline float MsBetween(int channel1, int channel2){
return MsBetween(channel1, current_cycle, channel2, current_cycle);
}
//from channel1 of cycle1 to channel1 of cycle2
inline float MsSpanCycle(int channel, int cycle1, int cycle2){
return MsBetween(channel, cycle1, channel, cycle2);
}
//from channel of cycle-1 to channel of cycle
inline float MsSpanCycle(int channel, int cycle){
return MsBetween(channel, cycle-1, channel, cycle);
}
/*from channel1 of cycle to channel2 of cycle.
return InvalidValue when one or both of them are unknown.*/
float MsCheckBetween(int channel1, int channel2, int cycle, float InvalidValue = -1.0f);
/*from channel1 of current cycle to channel2 of current cycle.
return InvalidValue when one or both of them are unknown.*/
inline float MsCheckBetween(int channel1, int channel2, float InvalidValue = -1.0f){
return MsCheckBetween(channel1, channel2, current_cycle, InvalidValue);
}
//from event to channel of cycle
inline float MsFromEvent(int event, int channel, int cycle){
return MsBetween(Events[event], Channels[channel].Data(cycle));
}
//from event to channel of current cycle
inline float MsFromEvent(int event, int channel){
return MsBetween(Events[event], Channels[channel].Data(current_cycle));
}
//Time elapsed since channel of cycle.
float TimeElapsed(int channel, int cycle);
//Time elapsed since channel of current cycle.
inline float TimeElapsed(int channel){
return TimeElapsed(channel, current_cycle);
}
//Time elapsed since event.
float TimeElapsed_E(int event);
/*Decide whether event occurs before channel of cycle
return true when it does*/
inline bool IsPrior_E(int event, int channel, int cycle){
return bool( MsFromEvent(event, channel, cycle) > 0);
}
/*Extented functions to provide direct access to data*/
inline TIME_T GetRawData_Channel(int channel, int cycle){
return Channels[channel].Data(cycle);
}
TIME_T GetRawData_Event(int event);
inline TIME_T GetRawData_Cache(){
return cachetime;
}
inline void SetRawData_Channel(TIME_T& t, int no, int cycle){
Channels[no].Setdata(t, cycle);
}
inline void SetRawData_Event(TIME_T& t, int event){
Events[event] = t;
}
inline void SetRawData_Cache(TIME_T& t){
cachetime = t;
}
UniformTime FormatTime(TIME_T& t);
TIME_T DeFormatTime(UniformTime& t);
void Estimate_correction_factor();
inline float Get_correction_factor() const{return correction_factor;}
};
namespace World{
extern Stopwatch stopwatch;
}
#endif //_STOPWATCH_H
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?