OSDN Git Service

DTXManiaソリューション、DTXManiaプロジェクト、DTXCreatorプロジェクト、FDKプロジェクトについて英語化。
[dtxmania/dtxmania.git] / FDK / コード / 01.フレームワーク / Core / GameClock.cs
diff --git a/FDK/コード/01.フレームワーク/Core/GameClock.cs b/FDK/コード/01.フレームワーク/Core/GameClock.cs
new file mode 100644 (file)
index 0000000..fe201f1
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+* Copyright (c) 2007-2009 SlimDX Group
+* 
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+* 
+* The above copyright notice and this permission notice shall be included in
+* all copies or substantial portions of the Software.
+* 
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+* THE SOFTWARE.
+*/
+using System;
+using System.Diagnostics;
+
+namespace SampleFramework
+{
+    class GameClock
+    {
+        long baseRealTime;
+        long lastRealTime;
+        bool lastRealTimeValid;
+        int suspendCount;
+        long suspendStartTime;
+        long timeLostToSuspension;
+        TimeSpan currentTimeBase;
+        TimeSpan currentTimeOffset;
+
+        public TimeSpan CurrentTime
+        {
+            get { return currentTimeBase + currentTimeOffset; }
+        }
+
+        public TimeSpan ElapsedTime
+        {
+            get;
+            private set;
+        }
+
+        public TimeSpan ElapsedAdjustedTime
+        {
+            get;
+            private set;
+        }
+
+        public static long Frequency
+        {
+            get { return Stopwatch.Frequency; }
+        }
+
+        public GameClock()
+        {
+            Reset();
+        }
+
+        public void Reset()
+        {
+            currentTimeBase = TimeSpan.Zero;
+            currentTimeOffset = TimeSpan.Zero;
+            baseRealTime = Stopwatch.GetTimestamp();
+            lastRealTimeValid = false;
+        }
+
+        public void Suspend()
+        {
+            suspendCount++;
+            if (suspendCount == 1)
+                suspendStartTime = Stopwatch.GetTimestamp();
+        }
+
+        /// <summary>
+        /// Resumes a previously suspended clock.
+        /// </summary>
+        public void Resume()
+        {
+            suspendCount--;
+            if (suspendCount <= 0)
+            {
+                timeLostToSuspension += Stopwatch.GetTimestamp() - suspendStartTime;
+                suspendStartTime = 0;
+            }
+        }
+
+        public void Step()
+        {
+            long counter = Stopwatch.GetTimestamp();
+
+            if (!lastRealTimeValid)
+            {
+                lastRealTime = counter;
+                lastRealTimeValid = true;
+            }
+
+            try
+            {
+                currentTimeOffset = CounterToTimeSpan(counter - baseRealTime);
+            }
+            catch (OverflowException)
+            {
+                // update the base value and try again to adjust for overflow
+                currentTimeBase += currentTimeOffset;
+                baseRealTime = lastRealTime;
+
+                try
+                {
+                    // get the current offset
+                    currentTimeOffset = CounterToTimeSpan(counter - baseRealTime);
+                }
+                catch (OverflowException)
+                {
+                    // account for overflow
+                    baseRealTime = counter;
+                    currentTimeOffset = TimeSpan.Zero;
+                }
+            }
+
+            try
+            {
+                ElapsedTime = CounterToTimeSpan(counter - lastRealTime);
+            }
+            catch (OverflowException)
+            {
+                ElapsedTime = TimeSpan.Zero;
+            }
+
+            try
+            {
+                ElapsedAdjustedTime = CounterToTimeSpan(counter - (lastRealTime + timeLostToSuspension));
+                timeLostToSuspension = 0;
+            }
+            catch (OverflowException)
+            {
+                ElapsedAdjustedTime = TimeSpan.Zero;
+            }
+
+            lastRealTime = counter;
+        }
+
+        static TimeSpan CounterToTimeSpan(long delta)
+        {
+            return TimeSpan.FromTicks((delta * 10000000) / Frequency);
+        }
+    }
+}