/******************************************************************** created: 2008/11/20 created: 20:11:2008 10:07 file: SynchCliTime.h author: 管传淇 purpose: *********************************************************************/ #include "ace/OS.h" #include "ace/Time_Value.h" #define VALID_SCOPE 25 class CPlayer; struct SynchElement { unsigned int synchEleID;//同步编号 ACE_Time_Value starttime;//同步开始的时间 ACE_Time_Value endtime;//同步结束的时间 unsigned int passtime;//经过的时间 bool isGetPassTime;//取得本次同步所经过的时间(单位:ms) bool isEnd;//是否已经完成同步 SynchElement():synchEleID(0),passtime(0),isGetPassTime(false),isEnd(false){} unsigned int GetPassTime() { if( isGetPassTime == false ) { ACE_Time_Value tmValue = endtime - starttime ; passtime = tmValue.msec()/2; isGetPassTime = true; } return passtime; } void Reset() { synchEleID = passtime = 0; endtime = starttime = ACE_Time_Value(0); isGetPassTime = isEnd = false; } //同步开始 void SynchStart( unsigned int synchID ) { synchEleID = synchID; //获取本次同步的开始时间 starttime = ACE_OS::gettimeofday(); } //同步结束 void SynchEnd() { endtime = ACE_OS::gettimeofday(); isEnd = true; } //返回同步是否结束 bool IsSynchEnded() { return isEnd ; } //是否在合法范围 bool IsValidScope() { if ( passtime <= VALID_SCOPE ) return true; return false; } }; #define MAX_SYNCH_COUNT 50 //最大的同步次数 #define MAX_SYNCHARR_COUNT MAX_SYNCH_COUNT+1 class SynchTime { public: SynchTime():mdelayTime(0),mSynchSuccess(false),pAttachPlayer(NULL){} private: //最后一步,同步客户端和服务器的时间 void SynchClientTime(); //发送对应ID的消息去同步时间 void SendMsgToSync( unsigned int synID ); //开始第一轮时间同步 void StartFirstSynch(); //第一轮同步失败,延迟>25ms,需要多测试几次,已测试延迟的最精确值..开始第二轮同步 void StartSecondSynch(); public: //开始同步时间的操作 void StartSynch() { StartFirstSynch(); } //结束对应索引的同步事件 bool EndSynch( unsigned int synchID ); void ResetSynchTime() { pAttachPlayer = NULL; msynchstarttime = mdelayTime = 0; mSynchSuccess =false; mFirstSynchEle.Reset(); for( unsigned int i = 1 ; i< MAX_SYNCHARR_COUNT ; i++ ) { if ( i >= ARRAY_SIZE(mSynchEleArr) ) { D_ERROR( "ResetSynchTime, i(%d) >= ARRAY_SIZE(mSynchEleArr)\n", i ); return; } SynchElement& tmpEle = mSynchEleArr[i]; tmpEle.Reset(); } } void AttachPlayer( CPlayer* pPlayer ) { pAttachPlayer = pPlayer; } private: //同步步骤的开始时间 unsigned int msynchstarttime; // 最终测试得到延迟时间 unsigned int mdelayTime; //第一次同步时的纪录 SynchElement mFirstSynchEle; //第二次同步时的纪录 SynchElement mSynchEleArr[MAX_SYNCHARR_COUNT]; //同步是否成功 bool mSynchSuccess; CPlayer* pAttachPlayer; };