OSDN Git Service

Merge branch 'feature/37178_プロジェクトとソリューションファイルの英語化' into develop
[dtxmania/dtxmania.git] / FDK / コード / 00.共通 / CTimer.cs
diff --git a/FDK/コード/00.共通/CTimer.cs b/FDK/コード/00.共通/CTimer.cs
new file mode 100644 (file)
index 0000000..d9e9fbb
--- /dev/null
@@ -0,0 +1,162 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+using DirectShowLib;
+
+namespace FDK
+{
+       public class CTimer : CTimerBase
+       {
+               public enum E種別
+               {
+                       Unknown = -1,
+                       PerformanceCounter = 0,
+                       MultiMedia = 1,
+                       GetTickCount = 2,
+               }
+               public E種別 eタイマ種別
+               {
+                       get;
+                       protected set;
+               }
+
+
+               public override long nシステム時刻ms
+               {
+                       get
+                       {
+                               switch( this.eタイマ種別 )
+                               {
+                                       case E種別.PerformanceCounter:
+                                               {
+                                                       double num = 0.0;
+                                                       if( this.n現在の周波数 != 0L )
+                                                       {
+                                                               long x = 0L;
+                                                               QueryPerformanceCounter( ref x );
+                                                               num = ( (double) x ) / ( ( (double) this.n現在の周波数 ) / 1000.0 );
+                                                       }
+                                                       return (long) num;
+                                               }
+                                       case E種別.MultiMedia:
+                                               return (long) timeGetTime();
+
+                                       case E種別.GetTickCount:
+                                               return (long) Environment.TickCount;
+                               }
+                               return 0;
+                       }
+               }
+
+               public CTimer( E種別 eタイマ種別 )
+                       :base()
+               {
+                       this.eタイマ種別 = eタイマ種別;
+
+                       if( n参照カウント[ (int) this.eタイマ種別 ] == 0 )
+                       {
+                               switch( this.eタイマ種別 )
+                               {
+                                       case E種別.PerformanceCounter:
+                                               if( !this.b確認と設定_PerformanceCounter() && !this.b確認と設定_MultiMedia() )
+                                                       this.b確認と設定_GetTickCount();
+                                               break;
+
+                                       case E種別.MultiMedia:
+                                               if( !this.b確認と設定_MultiMedia() && !this.b確認と設定_PerformanceCounter() )
+                                                       this.b確認と設定_GetTickCount();
+                                               break;
+
+                                       case E種別.GetTickCount:
+                                               this.b確認と設定_GetTickCount();
+                                               break;
+
+                                       default:
+                                               throw new ArgumentException( string.Format( "未知のタイマ種別です。[{0}]", this.eタイマ種別 ) );
+                               }
+                       }
+       
+                       base.tリセット();
+
+                       n参照カウント[ (int) this.eタイマ種別 ]++;
+               }
+               
+               public override void Dispose()
+               {
+                       if( this.eタイマ種別 == E種別.Unknown )
+                               return;
+
+                       int type = (int) this.eタイマ種別;
+
+                       n参照カウント[ type ] = Math.Max( n参照カウント[ type ] - 1, 0 );
+
+                       if( n参照カウント[ type ] == 0 )
+                       {
+                               if( this.eタイマ種別 == E種別.MultiMedia )
+                                       timeEndPeriod( this.timeCaps.wPeriodMin );
+                       }
+
+                       this.eタイマ種別 = E種別.Unknown;
+               }
+
+               #region [ protected ]
+               //-----------------
+               protected long n現在の周波数;
+               protected static int[] n参照カウント = new int[ 3 ];
+               protected TimeCaps timeCaps;
+
+               protected bool b確認と設定_GetTickCount()
+               {
+                       this.eタイマ種別 = E種別.GetTickCount;
+                       return true;
+               }
+               protected bool b確認と設定_MultiMedia()
+               {
+                       this.timeCaps = new TimeCaps();
+                       if( ( timeGetDevCaps( out this.timeCaps, (uint) Marshal.SizeOf( typeof( TimeCaps ) ) ) == 0 ) && ( this.timeCaps.wPeriodMin < 10 ) )
+                       {
+                               this.eタイマ種別 = E種別.MultiMedia;
+                               timeBeginPeriod( this.timeCaps.wPeriodMin );
+                               return true;
+                       }
+                       return false;
+               }
+               protected bool b確認と設定_PerformanceCounter()
+               {
+                       if( QueryPerformanceFrequency( ref this.n現在の周波数 ) != 0 )
+                       {
+                               this.eタイマ種別 = E種別.PerformanceCounter;
+                               return true;
+                       }
+                       return false;
+               }
+               //-----------------
+               #endregion
+
+               #region [ DllImport ]
+               //-----------------
+               [DllImport( "kernel32.dll" )]
+               protected static extern short QueryPerformanceCounter( ref long x );
+               [DllImport( "kernel32.dll" )]
+               protected static extern short QueryPerformanceFrequency( ref long x );
+               [DllImport( "winmm.dll" )]
+               protected static extern void timeBeginPeriod( uint x );
+               [DllImport( "winmm.dll" )]
+               protected static extern void timeEndPeriod( uint x );
+               [DllImport( "winmm.dll" )]
+               protected static extern uint timeGetDevCaps( out TimeCaps timeCaps, uint size );
+               [DllImport( "winmm.dll" )]
+               protected static extern uint timeGetTime();
+
+               [StructLayout( LayoutKind.Sequential )]
+               protected struct TimeCaps
+               {
+                       public uint wPeriodMin;
+                       public uint wPeriodMax;
+               }
+               //-----------------
+               #endregion
+       }
+}