A game framework written with osu! in mind.
at master 92 lines 2.4 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Runtime.InteropServices; 6 7namespace osu.Framework.Platform.Windows 8{ 9 /// <summary> 10 /// Set the windows multimedia timer to a specific accuracy. 11 /// </summary> 12 internal class TimePeriod : IDisposable 13 { 14 private static readonly TimeCaps time_capabilities; 15 16 private readonly int period; 17 18 [DllImport(@"winmm.dll", ExactSpelling = true)] 19 private static extern int timeGetDevCaps(ref TimeCaps ptc, int cbtc); 20 21 [DllImport(@"winmm.dll", ExactSpelling = true)] 22 private static extern int timeBeginPeriod(int uPeriod); 23 24 [DllImport(@"winmm.dll", ExactSpelling = true)] 25 private static extern int timeEndPeriod(int uPeriod); 26 27 internal static int MinimumPeriod => time_capabilities.wPeriodMin; 28 internal static int MaximumPeriod => time_capabilities.wPeriodMax; 29 30 private readonly bool didAdjust; 31 32 static TimePeriod() 33 { 34 timeGetDevCaps(ref time_capabilities, Marshal.SizeOf(typeof(TimeCaps))); 35 } 36 37 internal TimePeriod(int period) 38 { 39 this.period = period; 40 41 if (MaximumPeriod <= 0) 42 return; 43 44 try 45 { 46 didAdjust = timeBeginPeriod(Math.Clamp(period, MinimumPeriod, MaximumPeriod)) == 0; 47 } 48 catch { } 49 } 50 51 #region IDisposable Support 52 53 private bool disposedValue; // To detect redundant calls 54 55 protected virtual void Dispose(bool disposing) 56 { 57 if (!disposedValue) 58 { 59 disposedValue = true; 60 61 if (!didAdjust) 62 return; 63 64 try 65 { 66 timeEndPeriod(period); 67 } 68 catch { } 69 } 70 } 71 72 ~TimePeriod() 73 { 74 Dispose(false); 75 } 76 77 public void Dispose() 78 { 79 Dispose(true); 80 GC.SuppressFinalize(this); 81 } 82 83 #endregion 84 85 [StructLayout(LayoutKind.Sequential)] 86 private readonly struct TimeCaps 87 { 88 internal readonly int wPeriodMin; 89 internal readonly int wPeriodMax; 90 } 91 } 92}