using System; using System.Collections.Generic; using System.Diagnostics; namespace Nuclex { internal class GameClock { // Methods public GameClock() { this.Reset(); } private static TimeSpan CounterToTimeSpan(long delta) { long num = 0x989680; long num2 = (delta * num) / Frequency; return TimeSpan.FromTicks(num2); } internal void Reset() { this.currentTimeBase = TimeSpan.Zero; this.currentTimeOffset = TimeSpan.Zero; this.baseRealTime = Counter; this.lastRealTimeValid = false; } internal void Resume() { this.suspendCount--; if (this.suspendCount <= 0) { long counter = Counter; this.timeLostToSuspension += counter - this.suspendStartTime; this.suspendStartTime = 0; } } internal void Step() { long counter = Counter; if (!this.lastRealTimeValid) { this.lastRealTime = counter; this.lastRealTimeValid = true; } try { this.currentTimeOffset = CounterToTimeSpan(counter - this.baseRealTime); } catch (OverflowException) { this.currentTimeBase += this.currentTimeOffset; this.baseRealTime = this.lastRealTime; try { this.currentTimeOffset = CounterToTimeSpan(counter - this.baseRealTime); } catch (OverflowException) { this.baseRealTime = counter; this.currentTimeOffset = TimeSpan.Zero; } } try { this.elapsedTime = CounterToTimeSpan(counter - this.lastRealTime); } catch (OverflowException) { this.elapsedTime = TimeSpan.Zero; } try { long num2 = this.lastRealTime + this.timeLostToSuspension; this.elapsedAdjustedTime = CounterToTimeSpan(counter - num2); this.timeLostToSuspension = 0L; } catch (OverflowException) { this.elapsedAdjustedTime = TimeSpan.Zero; } this.lastRealTime = counter; } internal void Suspend() { this.suspendCount++; if (this.suspendCount == 1) { this.suspendStartTime = Counter; } } // Properties internal static long Counter { get { return Stopwatch.GetTimestamp(); } } internal TimeSpan CurrentTime { get { return (this.currentTimeBase + this.currentTimeOffset); } } internal TimeSpan ElapsedAdjustedTime { get { return this.elapsedAdjustedTime; } } internal TimeSpan ElapsedTime { get { return this.elapsedTime; } } internal static long Frequency { get { return Stopwatch.Frequency; } } // Fields private long baseRealTime; private TimeSpan currentTimeBase; private TimeSpan currentTimeOffset; private TimeSpan elapsedAdjustedTime; private TimeSpan elapsedTime; private long lastRealTime; private bool lastRealTimeValid; private int suspendCount; private long suspendStartTime; private long timeLostToSuspension; } } // namespace Nuclex