private void OnClockTimeChanged(object sender, GameClockEventArgs eventArgs) { // Scale incoming deltaTime. long ticks = (long)(eventArgs.DeltaTime.Ticks * Speed); // Determine time since last time step AccumulatedTime += new TimeSpan(ticks); TimeSpan duration = AccumulatedTime.Duration(); // Absolute value if (duration < MinDeltaTime) { // ----- Idle // Time left before next time step. // Set idle time and trigger Idle event. DeltaTime = TimeSpan.Zero; LostTime = TimeSpan.Zero; IdleTime = MinDeltaTime - duration; UpdateEventArgs(); OnIdle(_eventArgs); } else { // ----- Time Step FrameCount++; if (duration > MaxDeltaTime) { // Drop time above MaxDeltaTime LostTime = duration - MaxDeltaTime; DeltaTime = (AccumulatedTime.Ticks >= 0) ? MaxDeltaTime : -MaxDeltaTime; } else { // Default LostTime = TimeSpan.Zero; DeltaTime = AccumulatedTime; } AccumulatedTime = TimeSpan.Zero; IdleTime = TimeSpan.Zero; // Update time and trigger next time step Time += DeltaTime; UpdateEventArgs(); OnTimeChanged(_eventArgs); } }
private void OnClockTimeChanged(object sender, GameClockEventArgs eventArgs) { // Scale incoming deltaTime. long ticks = (long)(eventArgs.DeltaTime.Ticks * Speed); // Determine time since last time step AccumulatedTime += new TimeSpan(ticks); TimeSpan duration = AccumulatedTime.Duration(); // Absolute value // Ignore small deviations (e.g. on 59.94 Hz displays). if (Math.Abs(duration.Ticks - StepSize.Ticks) < StepSizeTolerance.Ticks) { duration = StepSize; } if (duration < StepSize) { // ----- Idle // Time left before next time step. // Set idle time and trigger Idle event. DeltaTime = TimeSpan.Zero; LostTime = TimeSpan.Zero; IdleTime = StepSize - duration; UpdateEventArgs(); OnIdle(_eventArgs); } else { // ----- Time Step if (duration > _maxStepSize) { // Drop time above MaxDeltaTime AccumulatedSteps = _maxNumberOfSteps; LostTime = duration - _maxStepSize; DeltaTime = (ticks >= 0) ? _maxStepSize : -_maxStepSize; AccumulatedTime = TimeSpan.Zero; } else { // Adjust Δt to an integer multiple of StepSize AccumulatedSteps = (int)(duration.Ticks / StepSize.Ticks); duration = new TimeSpan(AccumulatedSteps * StepSize.Ticks); LostTime = TimeSpan.Zero; DeltaTime = (ticks >= 0) ? duration : -duration; AccumulatedTime -= DeltaTime; } IdleTime = TimeSpan.Zero; // Update time and trigger next time step if (AccumulateTimeSteps) { // Trigger one big time step. FrameCount++; Time += DeltaTime; UpdateEventArgs(); OnTimeChanged(_eventArgs); } else { // Trigger several constant time steps. var accumulatedTimeBackup = AccumulatedTime; // DeltaTime is always equal to the step size. DeltaTime = StepSize; // AccumulatedTime is 0. Only in the last time step it is set to the actual rest time. AccumulatedTime = TimeSpan.Zero; PendingSteps = AccumulatedSteps - 1; AccumulatedSteps = 1; for (; PendingSteps >= 0; PendingSteps--) { FrameCount++; Time += StepSize; if (PendingSteps == 0) { AccumulatedTime = accumulatedTimeBackup; } UpdateEventArgs(); OnTimeChanged(_eventArgs); } Debug.Assert(AccumulatedTime == accumulatedTimeBackup); } AccumulatedSteps = 0; PendingSteps = 0; } }