eTimer Class Reference

#include <eTimer.h>

Inheritance diagram for eTimer:

Inheritance graph
[legend]
Collaboration diagram for eTimer:

Collaboration graph
[legend]

List of all members.

Public Member Functions

 eTimer ()
 eTimer (nMessage &m)
virtual ~eTimer ()
virtual void WriteSync (nMessage &m)
virtual void ReadSync (nMessage &m)
virtual nDescriptorCreatorDescriptor () const
REAL Time ()
REAL TimeNoSync ()
void pause (bool p)
void SyncTime ()
void Reset (REAL t=0)
REAL AverageFPS ()
REAL AverageFrameTime ()
REAL FrameTime ()
bool IsSynced () const
 returns whether the timer is synced sufficiently well to allow rendering

Public Attributes

REAL speed

Private Attributes

double creationSystemTime_
 the rough system time this timer was created at
double smoothedSystemTime_
 the smoothed system time
double startTime_
 when was the last game started?
nAverager startTimeOffset_
 the smoothed average of this averager is added to the start time on the client
REAL startTimeSmoothedOffset_
 the smoothed average of startTimeOffset_
nAverager qualityTester_
 averager that tells us about the quality of the sync messages
REAL spf_
 last frame time
nAverager averageSpf_
 averager over seconds per frame
double lastTime_
 the smoothed system time of the last update
double nextSync_
 system time of the next sync to the clients


Detailed Description

Definition at line 35 of file eTimer.h.


Constructor & Destructor Documentation

eTimer::eTimer (  ) 

Definition at line 42 of file eTimer.cpp.

References nAverager::Add(), averageSpf_, creationSystemTime_, nSERVER, nNetObject::RequestSync(), nAverager::Reset(), Reset(), sn_GetNetState(), speed, and tSysTimeFloat().

00042               :nNetObject(), startTimeSmoothedOffset_(0){
00043     //con << "Creating own eTimer.\n";
00044 
00045     speed = 1.0;
00046 
00047     Reset(0);
00048 
00049     if (se_mainGameTimer)
00050         delete se_mainGameTimer;
00051     se_mainGameTimer=this;
00052     if (sn_GetNetState()==nSERVER)
00053         RequestSync();
00054 
00055     averageSpf_.Reset();
00056     averageSpf_.Add(1/60.0,5);
00057 
00058     creationSystemTime_ = tSysTimeFloat();
00059 }

Here is the call graph for this function:

eTimer::eTimer ( nMessage m  ) 

Definition at line 61 of file eTimer.cpp.

References nAverager::Add(), averageSpf_, creationSystemTime_, nAverager::Reset(), Reset(), speed, and tSysTimeFloat().

00061                          :nNetObject(m), startTimeSmoothedOffset_(0){
00062     //con << "Creating remote eTimer.\n";
00063 
00064     speed = 1.0;
00065 
00066     Reset(0);
00067 
00068     if (se_mainGameTimer)
00069         delete se_mainGameTimer;
00070     se_mainGameTimer=this;
00071 
00072     averageSpf_.Reset();
00073     averageSpf_.Add(1/60.0,5);
00074 
00075     creationSystemTime_ = tSysTimeFloat();
00076 }

Here is the call graph for this function:

eTimer::~eTimer (  )  [virtual]

Definition at line 78 of file eTimer.cpp.

References NULL.

00078                {
00079     //con << "Deleting eTimer.\n";
00080     se_mainGameTimer=NULL;
00081 }


Member Function Documentation

void eTimer::WriteSync ( nMessage m  )  [virtual]

Reimplemented from nNetObject.

Definition at line 90 of file eTimer.cpp.

References nextSync_, REAL, se_clientLagCompensation, se_lagOffsetLegacy, smoothedSystemTime_, speed, nVersionFeature::Supported(), nNetObject::SyncedUser(), Time(), and nNetObject::WriteSync().

00090                                  {
00091     nNetObject::WriteSync(m);
00092     REAL time = Time();
00093 
00094     if ( SyncedUser() > 0 && !se_clientLagCompensation.Supported( SyncedUser() ) )
00095         time += se_lagOffsetLegacy;
00096 
00097     m << time;
00098     m << speed;
00099     //std::cerr << "syncing:" << currentTime << ":" << speed << '\n';
00100 
00101     // plan next sync
00102     const REAL stopFast = 3;
00103     const REAL maxFast  = 3;
00104     if ( time < stopFast )
00105     {
00106         nextSync_ = smoothedSystemTime_ + maxFast/(stopFast+maxFast-time);
00107     }
00108     else
00109     {
00110         nextSync_ = smoothedSystemTime_ + 1;
00111     }
00112 }

Here is the call graph for this function:

void eTimer::ReadSync ( nMessage m  )  [virtual]

Reimplemented from nNetObject.

Definition at line 119 of file eTimer.cpp.

References nAverager::Add(), EPS, nAverager::GetAverageVariance(), nPingAverager::GetFastAverager(), nPingAverager::GetPing(), nConnectionInfo::ping, qualityTester_, nNetObject::ReadSync(), REAL, nAverager::Reset(), se_timerStartFudge, se_timerStartFudgeStop, nMessage::SenderID(), smoothedSystemTime_, sn_Connections, sn_pingCharityServer, speed, startTime_, startTimeOffset_, and nAverager::Timestep().

00119                                 {
00120     nNetObject::ReadSync(m);
00121 
00122     //std::cerr << "Got sync:" << remote_currentTime << ":" << speed << '\n';
00123 
00124     // determine the best estimate of the start time offset that reproduces the sent remote
00125     // time and its expected quality.
00126     REAL remoteStartTimeOffset = 0;
00127     REAL remoteTimeNonQuality = 0;
00128     {
00129         //REAL oldTime=currentTime;
00130         REAL remote_currentTime, remoteSpeed;
00131         m >> remote_currentTime; // read in the remote time
00132         m >> remoteSpeed;
00133 
00134         // forget about earlier syncs if the speed changed
00135         if ( fabs( speed - remoteSpeed ) > 10 * EPS )
00136         {
00137             qualityTester_.Timestep( 100 );
00138             startTimeOffset_.Reset();
00139         }
00140 
00141         speed = remoteSpeed;
00142 
00143         // determine ping
00144         nPingAverager & averager = sn_Connections[m.SenderID()].ping;
00145         // pingAverager_.Add( rawAverager.GetPing(), remote_currentTime > .01 ? remote_currentTime : .01 );
00146         REAL ping = averager.GetPing();
00147 
00148         // add half our ping (see Einsteins SRT on clock syncronisation)
00149         REAL real_remoteTime=remote_currentTime+ping*speed*.5;
00150 
00151         // and the normal time including ping charity
00152         REAL min_remoteTime=remote_currentTime+ping*speed-
00153                             sn_pingCharityServer*.001;
00154 
00155         if (real_remoteTime<min_remoteTime)
00156             remote_currentTime=min_remoteTime;
00157         else
00158             remote_currentTime=real_remoteTime;
00159 
00160         // HACK: warp time into the future at the beginning of the round.
00161         // I can't explain why this is required; without it, the timer is late.
00162         if ( remote_currentTime < se_timerStartFudgeStop )
00163         {
00164             remote_currentTime += ping * ( se_timerStartFudgeStop - remote_currentTime ) * se_timerStartFudge;
00165         }
00166 
00167         // determine quality from ping variance
00168         remoteTimeNonQuality = averager.GetFastAverager().GetAverageVariance();
00169 
00170         // determine start time
00171         remoteStartTimeOffset = smoothedSystemTime_ - startTime_ - remote_currentTime;
00172 
00173         // let the averagers decay faster at the beginning
00174         if ( remote_currentTime < 0 )
00175         {
00176             qualityTester_.Timestep( .2 );
00177             startTimeOffset_.Timestep( .2 );
00178         }
00179     }
00180 
00181     // try to get independend quality measure: get the variance of the received start times
00182     qualityTester_.Add( remoteStartTimeOffset );
00183 
00184     // add the variance to the non-quality, along with an offset to avoid division by zero
00185     remoteTimeNonQuality += 0.00001 + 4 * qualityTester_.GetAverageVariance();
00186 
00187     // add the offset to the statistics, weighted by the quality
00188     startTimeOffset_.Add( remoteStartTimeOffset, 1/remoteTimeNonQuality );
00189 }

Here is the call graph for this function:

nDescriptor & eTimer::CreatorDescriptor ( void   )  const [virtual]

Implements nNetObject.

Definition at line 193 of file eTimer.cpp.

References eTimer_init.

00193                                             {
00194     return eTimer_init;
00195 }

REAL eTimer::Time (  ) 

Definition at line 215 of file eTimer.cpp.

References eLag::Current(), smoothedSystemTime_, startTime_, and startTimeSmoothedOffset_.

Referenced by gCycle::Act(), gWallRim::RenderReal(), se_GameTime(), SyncTime(), TimeNoSync(), and WriteSync().

00216 {
00217     return ( smoothedSystemTime_ - startTime_ ) - startTimeSmoothedOffset_ + eLag::Current();
00218 }

Here is the call graph for this function:

Here is the caller graph for this function:

REAL eTimer::TimeNoSync (  )  [inline]

Definition at line 47 of file eTimer.h.

References lastTime_, REAL, speed, Time(), and tSysTimeFloat().

Referenced by se_GameTimeNoSync().

00047 {return REAL(Time()+(tSysTimeFloat()-lastTime_)*speed);}

Here is the call graph for this function:

Here is the caller graph for this function:

void eTimer::pause ( bool  p  ) 

Definition at line 362 of file eTimer.cpp.

References nSERVER, nNetObject::RequestSync(), sn_GetNetState(), and speed.

Referenced by se_PauseGameTimer().

00362                         {
00363     if (p){
00364         if(speed!=0){
00365             speed=0;
00366             if (sn_GetNetState()==nSERVER)
00367                 RequestSync();
00368         }
00369     }
00370     else{
00371         if (speed!=1){
00372             speed=1;
00373             //Reset(currentTime_);
00374 
00375             if (sn_GetNetState()==nSERVER)
00376                 RequestSync();
00377         }
00378     }
00379 }

Here is the call graph for this function:

Here is the caller graph for this function:

void eTimer::SyncTime (  ) 

Definition at line 220 of file eTimer.cpp.

References nAverager::Add(), averageSpf_, nAverager::GetAverage(), nAverager::GetAverageVariance(), tRecorderBase::IsRunning(), lastTime_, nextSync_, nSERVER, nSTANDALONE, qualityTester_, REAL, nNetObject::RequestSync(), se_SmoothTime(), smoothedSystemTime_, sn_GetNetState(), speed, spf_, st_Breakpoint(), startTime_, startTimeOffset_, startTimeSmoothedOffset_, Time(), nAverager::Timestep(), eLag::Timestep(), tSysTimeFloat(), and tTimerIsAccurate().

Referenced by se_SyncGameTimer().

00220                      {
00221     // get current system time
00222     {
00223         double newTime=tSysTimeFloat();
00224 
00225         static bool smooth = se_SmoothTime();
00226 
00227         // recheck if no recording/playback is running
00228         if ( !tRecorder::IsRunning() )
00229         {
00230             smooth = !tTimerIsAccurate();
00231         }
00232 
00233         if ( !smooth )
00234         {
00235             // take it
00236             smoothedSystemTime_ = newTime;
00237         }
00238         else
00239         {
00240             // smooth it
00241             REAL smoothDecay = .2f;
00242             smoothedSystemTime_ = ( smoothedSystemTime_ + smoothDecay * newTime )/( 1 + smoothDecay );
00243         }
00244     }
00245 
00246     // update timers
00247     REAL timeStep=smoothedSystemTime_ - lastTime_;
00248     lastTime_ = smoothedSystemTime_;
00249 
00250 #ifdef DEBUG
00251 #ifndef DEDICATED
00252     // maximum effective timestep in SP debug mode: .1s
00253     if (timeStep > .1f && sn_GetNetState() == nSTANDALONE && !tRecorder::IsRunning() )
00254     {
00255         startTime_ += timeStep - .1f;
00256         timeStep = .1f;
00257     }
00258 #endif
00259 #endif
00260 
00261     // update lag compensation
00262     eLag::Timestep( timeStep );
00263 
00264     // store and average frame times
00265     spf_ = timeStep;
00266     if ( timeStep > 0 && speed > 0 )
00267     {
00268         averageSpf_.Add( timeStep );
00269         averageSpf_.Timestep( timeStep );
00270     }
00271 
00272     // let averagers decay
00273     startTimeOffset_.Timestep( timeStep * .1 );
00274     qualityTester_  .Timestep( timeStep * .3 );
00275     // pingAverager_   .Timestep( timeStep * .05);
00276 
00277     // if we're not running at default speed, update the virtual start time
00278     startTime_ += ( 1.0 - speed ) * timeStep;
00279 
00280     // smooth time offset
00281     {
00282         REAL startTimeOffset = startTimeOffset_.GetAverage();
00283 
00284         // correct huge deviations (compared to variance) faster
00285         REAL deviation = startTimeSmoothedOffset_ - startTimeOffset;
00286         REAL extraSmooth = deviation * deviation / ( startTimeOffset_.GetAverageVariance() + .0001 );
00287 
00288         // allow for faster smoothing at the beginning of the round
00289         REAL time = Time();
00290         if ( time < 0 )
00291             extraSmooth -= 4 * time;
00292 
00293         REAL smooth = timeStep * ( .5 + extraSmooth );
00294         startTimeSmoothedOffset_ = ( startTimeSmoothedOffset_ + startTimeOffset * smooth )/(1 + smooth);
00295 
00296         if ( !finite( startTimeSmoothedOffset_ ) )
00297         {
00298             // emergency, smoothing the timer produced infinite results
00299             st_Breakpoint();
00300             startTimeSmoothedOffset_ = startTimeOffset;
00301         }
00302     }
00303 
00304     // request syncs
00305     if (sn_GetNetState()==nSERVER && smoothedSystemTime_ >= nextSync_ )
00306     {
00307 #ifdef nSIMULATE_PING
00308         RequestSync(); // ack.
00309 #else
00310         RequestSync(false); // NO ack.
00311 #endif
00312     }
00313 }

Here is the call graph for this function:

Here is the caller graph for this function:

void eTimer::Reset ( REAL  t = 0  ) 

Definition at line 315 of file eTimer.cpp.

References nAverager::Add(), EPS, nAverager::GetAverage(), lastTime_, nCLIENT, nextSync_, qualityTester_, REAL, nAverager::Reset(), smoothedSystemTime_, sn_GetNetState(), speed, sqrt(), startTime_, startTimeOffset_, startTimeSmoothedOffset_, and tSysTimeFloat().

Referenced by eTimer(), and se_ResetGameTimer().

00315                         {
00316     if (sn_GetNetState()!=nCLIENT)
00317         speed=1;
00318 
00319     // reset start time
00320     smoothedSystemTime_ = tSysTimeFloat();
00321     startTime_ = smoothedSystemTime_ - t;
00322 
00323     // reset averagers
00324     startTimeOffset_.Reset();
00325     startTimeOffset_.Add(100,EPS);
00326     startTimeOffset_.Add(-100,EPS);
00327 
00328     qualityTester_.Reset();
00329     static const REAL qual = sqrt(1/EPS);
00330     qualityTester_.Add(qual,EPS);
00331     qualityTester_.Add(-qual,EPS);
00332 
00333     // reset times of actions
00334     lastTime_ = nextSync_ = smoothedSystemTime_;
00335     startTimeSmoothedOffset_ = startTimeOffset_.GetAverage();
00336 }

Here is the call graph for this function:

Here is the caller graph for this function:

REAL eTimer::AverageFPS (  )  [inline]

Definition at line 54 of file eTimer.h.

References averageSpf_, EPS, and nAverager::GetAverage().

Referenced by se_AverageFPS().

00054 {return 1/(averageSpf_.GetAverage()+EPS);}

Here is the call graph for this function:

Here is the caller graph for this function:

REAL eTimer::AverageFrameTime (  )  [inline]

Definition at line 55 of file eTimer.h.

References averageSpf_, and nAverager::GetAverage().

00055 {return averageSpf_.GetAverage();}

Here is the call graph for this function:

REAL eTimer::FrameTime (  )  [inline]

Definition at line 56 of file eTimer.h.

References spf_.

00056 {return spf_;}

bool eTimer::IsSynced (  )  const

returns whether the timer is synced sufficiently well to allow rendering

Definition at line 338 of file eTimer.cpp.

References creationSystemTime_, nAverager::GetAverage(), nAverager::GetAverageVariance(), tRecorderBase::IsPlayingBack(), nCLIENT, tRecorder::Playback(), tRecorder::Record(), section, smoothedSystemTime_, sn_GetNetState(), startTimeOffset_, and startTimeSmoothedOffset_.

Referenced by display_cockpit_lucifer(), and gGame::GameLoop().

00339 {
00340     // allow non-synced status only during the first ten seconds of a connection
00341     if ( smoothedSystemTime_ - creationSystemTime_ > 10 || sn_GetNetState() != nCLIENT )
00342         return true;
00343 
00344     // the quality of the start time offset needs to be good enough (to .1 s, variance is the square of the expected)
00345     bool synced = startTimeOffset_.GetAverageVariance() < .01 &&
00346                   fabs( startTimeOffset_.GetAverage() - startTimeSmoothedOffset_ ) < .01;
00347 
00348     static char const * section = "TIMER_SYNCED";
00349 
00350     if ( tRecorder::IsPlayingBack() ? tRecorder::Playback( section ) : synced )
00351     {
00352         tRecorder::Record( section );
00353 
00354         // and make sure the next calls also return true.
00355         creationSystemTime_ = smoothedSystemTime_ - 11;
00356         return true;
00357     }
00358 
00359     return false;
00360 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

REAL eTimer::speed

Definition at line 37 of file eTimer.h.

Referenced by gCycle::Act(), gGame::Analysis(), display_cockpit_lucifer(), eTimer(), pause(), ReadSync(), Reset(), sg_FullscreenMessage(), SyncTime(), TimeNoSync(), and WriteSync().

double eTimer::creationSystemTime_ [mutable, private]

the rough system time this timer was created at

Definition at line 61 of file eTimer.h.

Referenced by eTimer(), and IsSynced().

double eTimer::smoothedSystemTime_ [private]

the smoothed system time

Definition at line 62 of file eTimer.h.

Referenced by IsSynced(), ReadSync(), Reset(), SyncTime(), Time(), and WriteSync().

double eTimer::startTime_ [private]

when was the last game started?

Definition at line 63 of file eTimer.h.

Referenced by ReadSync(), Reset(), SyncTime(), and Time().

nAverager eTimer::startTimeOffset_ [private]

the smoothed average of this averager is added to the start time on the client

Definition at line 64 of file eTimer.h.

Referenced by IsSynced(), ReadSync(), Reset(), and SyncTime().

REAL eTimer::startTimeSmoothedOffset_ [private]

the smoothed average of startTimeOffset_

Definition at line 65 of file eTimer.h.

Referenced by IsSynced(), Reset(), SyncTime(), and Time().

nAverager eTimer::qualityTester_ [private]

averager that tells us about the quality of the sync messages

Definition at line 66 of file eTimer.h.

Referenced by ReadSync(), Reset(), and SyncTime().

REAL eTimer::spf_ [private]

last frame time

Definition at line 70 of file eTimer.h.

Referenced by FrameTime(), and SyncTime().

nAverager eTimer::averageSpf_ [private]

averager over seconds per frame

Definition at line 71 of file eTimer.h.

Referenced by AverageFPS(), AverageFrameTime(), eTimer(), and SyncTime().

double eTimer::lastTime_ [private]

the smoothed system time of the last update

Definition at line 73 of file eTimer.h.

Referenced by Reset(), SyncTime(), and TimeNoSync().

double eTimer::nextSync_ [private]

system time of the next sync to the clients

Definition at line 74 of file eTimer.h.

Referenced by Reset(), SyncTime(), and WriteSync().


The documentation for this class was generated from the following files:
Generated on Sat Mar 15 23:30:55 2008 for Armagetron Advanced by  doxygen 1.5.4