\82«ã\82¦ã\83³ã\82¿/QPCTimer.cs - RSS feed" href="/view?p=strokestylet/CsWin10Desktop3.git;a=rss;f=FDK24/%C3%A3%C2%82%C2%AB%C3%A3%C2%82%C2%A6%C3%A3%C2%83%C2%B3%C3%A3%C2%82%C2%BF/QPCTimer.cs" type="application/rss+xml" /> \82«ã\82¦ã\83³ã\82¿/QPCTimer.cs - RSS feed (no merges)" href="/view?p=strokestylet/CsWin10Desktop3.git;a=rss;f=FDK24/%C3%A3%C2%82%C2%AB%C3%A3%C2%82%C2%A6%C3%A3%C2%83%C2%B3%C3%A3%C2%82%C2%BF/QPCTimer.cs;opt=--no-merges" type="application/rss+xml" /> \82«ã\82¦ã\83³ã\82¿/QPCTimer.cs - Atom feed" href="/view?p=strokestylet/CsWin10Desktop3.git;a=atom;f=FDK24/%C3%A3%C2%82%C2%AB%C3%A3%C2%82%C2%A6%C3%A3%C2%83%C2%B3%C3%A3%C2%82%C2%BF/QPCTimer.cs" type="application/atom+xml" /> \82«ã\82¦ã\83³ã\82¿/QPCTimer.cs - Atom feed (no merges)" href="/view?p=strokestylet/CsWin10Desktop3.git;a=atom;f=FDK24/%C3%A3%C2%82%C2%AB%C3%A3%C2%82%C2%A6%C3%A3%C2%83%C2%B3%C3%A3%C2%82%C2%BF/QPCTimer.cs;opt=--no-merges" type="application/atom+xml" />

OSDN Git Service

文字列テクスチャクラスで文字列が表示されないバグを修正。
[strokestylet/CsWin10Desktop3.git] / FDK24 / ã\82«ã\82¦ã\83³ã\82¿ / QPCTimer.cs
1 using System;
2 using System.Collections.Generic;
3
4 namespace FDK.カウンタ
5 {
6         /// <summary>
7         /// パフォーマンスカウンタを使用した高精度タイマ。
8         /// </summary>
9         /// <remarks>
10         /// 以下の2種類の使い方を想定する。
11         /// (A) 正確に同一の時刻を複数の処理で共有できるように、現在時刻をキャプチャしてから取得する方法。
12         ///    1. 最初に「現在のカウントをキャプチャする()」を呼び出し、その時点での時刻を内部に保存する。
13         ///    2. キャプチャされたカウントを、「現在のキャプチャカウントを……取得する()」を呼び出して、希望する単位で取得する。
14         ///      (次に1.を行うまで、2.はずっと同じ時刻を返し続ける。)
15         /// (B) 常に現時刻(メソッド呼び出し時点の時刻)を取得する方法。
16         ///    a. 「現在のリアルタイムカウントを……取得する()」を呼び出して、希望する単位で取得する。
17         ///    または、
18         ///    b. 「生カウントを取得する()」を呼び出して、生カウンタを取得する。
19         ///
20         /// 時刻の単位としては、[カウント], [秒], [100ナノ秒] を用意する。
21         /// 
22         /// 用語:
23         /// "カウント" …………………… タイマインスタンスの生成時(または前回のリセット時)から「前回キャプチャされた時点」までの、パフォーマンスカウンタの差分(相対値)。
24         /// "リアルタイムカウント" …… タイマインスタンスの生成時(または前回のリセット時)から「現時点」までの、パフォーマンスカウンタの差分(相対値)。
25         /// "生カウント" ………………… パフォーマンスカウンタの生の値。::QueryPerformanceCounter() で取得できる値に等しい。システム依存の絶対値。
26         /// </remarks>
27         public class QPCTimer
28         {
29                 /// <summary>
30                 /// カウントが無効であることを示す定数。
31                 /// </summary>
32                 public const long 未使用 = -1;
33
34                 public QPCTimer()
35                 {
36                         var dummy = QPCTimer.周波数;  // プロパティの get() 内で qpc周波数 を更新させるためのダミーアクセス。
37                         var now = QPCTimer.生カウント;
38                         this.bs_前回リセットした時点の生カウント = now;
39                         this.最後にキャプチャされたカウント = now;
40                         this.稼働中に一時停止した時点のキャプチャカウント = now;
41                         this.一時停止回数 = 0;
42                 }
43
44                 public static long 周波数
45                 {
46                         get
47                         {
48                                 if( 0 > QPCTimer.qpc周波数Hz )
49                                 {
50                                         // 初めてのアクセスならシステムから値を取得する。
51                                         QPCTimer.qpc周波数Hz = System.Diagnostics.Stopwatch.Frequency;
52                                 }
53                                 return QPCTimer.qpc周波数Hz;
54                         }
55                 }
56                 public static long 生カウント
57                         => System.Diagnostics.Stopwatch.GetTimestamp();
58                 public static double 生カウント相対値を秒へ変換して返す( long 生カウント相対値 )
59                         => (double) 生カウント相対値 / (double) QPCTimer.qpc周波数Hz;
60
61                 public long 現在のカウントをキャプチャする()
62                 {
63                         lock( this.排他利用 )
64                         {
65                                 this.最後にキャプチャされたカウント = QPCTimer.生カウント;
66                                 return this.最後にキャプチャされたカウント;
67                         }
68                 }
69
70                 public long 現在のキャプチャカウント
71                 {
72                         get
73                         {
74                                 lock( this.排他利用 )
75                                 {
76                                         long count = ( 0 != this.一時停止回数 ) ?
77                                                 ( this.稼働中に一時停止した時点のキャプチャカウント - this.bs_前回リセットした時点の生カウント ) :    // 停止中
78                                                 ( this.最後にキャプチャされたカウント - this.bs_前回リセットした時点の生カウント );                    // 稼働中
79                                         return count;
80                                 }
81                         }
82                 }
83                 public double 現在のキャプチャカウント秒単位
84                         => ( (double) this.現在のキャプチャカウント / (double) QPCTimer.周波数 );
85                 public long 現在のキャプチャカウント100ns単位
86                         => ( 1000 * 1000 * 10 * this.現在のキャプチャカウント / QPCTimer.周波数 );
87
88                 public long 現在のリアルタイムカウント
89                 {
90                         get
91                         {
92                                 lock( this.排他利用 )
93                                 {
94                                         long count = ( 0 != this.一時停止回数 ) ?
95                                                 ( this.稼働中に一時停止した時点のキャプチャカウント - this.bs_前回リセットした時点の生カウント ) :    // 停止中
96                                                 ( QPCTimer.生カウント - this.bs_前回リセットした時点の生カウント );                             // 稼働中
97                                         return count;
98                                 }
99                         }
100                 }
101                 public double 現在のリアルタイムカウント秒単位
102                         => ( (double) this.現在のリアルタイムカウント / (double) QPCTimer.周波数 );
103                 public long 現在のリアルタイムカウント100ns単位
104                         => ( 1000 * 1000 * 10 * this.現在のリアルタイムカウント / QPCTimer.周波数 );
105
106                 public long 前回リセットした時点の生カウント
107                 {
108                         get
109                         {
110                                 lock( this.排他利用 )
111                                 {
112                                         return this.bs_前回リセットした時点の生カウント;
113                                 }
114                         }
115                 }
116
117                 public bool 停止中である
118                 {
119                         get
120                         {
121                                 lock( this.排他利用 )
122                                 {
123                                         return ( 0 != this.一時停止回数 ) ? true : false;
124                                 }
125                         }
126                 }
127                 public bool 稼働中である
128                 {
129                         get
130                         {
131                                 lock( this.排他利用 )
132                                 {
133                                         return ( 0 == this.一時停止回数 ) ? true : false;
134                                 }
135                         }
136                 }
137
138                 public void リセットする()
139                 {
140                         lock( this.排他利用 )
141                         {
142                                 this.bs_前回リセットした時点の生カウント = QPCTimer.生カウント;
143                         }
144                 }
145                 public void リセットする( long 新しいカウント )
146                 {
147                         lock( this.排他利用 )
148                         {
149                                 this.bs_前回リセットした時点の生カウント = QPCTimer.生カウント - 新しいカウント;
150                         }
151                 }
152                 public void 一時停止する()
153                 {
154                         lock( this.排他利用 )
155                         {
156                                 if( 0 == this.一時停止回数 ) // 稼働中である
157                                 {
158                                         this.稼働中に一時停止した時点のキャプチャカウント = this.最後にキャプチャされたカウント;
159                                 }
160                                 this.一時停止回数++;
161                         }
162                 }
163                 public void 再開する()
164                 {
165                         lock( this.排他利用 )
166                         {
167                                 if( 0 != this.一時停止回数 ) // 停止中である
168                                 {
169                                         this.一時停止回数--;
170
171                                         if( 0 == this.一時停止回数 )
172                                         {
173                                                 this.最後にキャプチャされたカウント = QPCTimer.生カウント;
174                                                 this.bs_前回リセットした時点の生カウント = this.最後にキャプチャされたカウント - this.稼働中に一時停止した時点のキャプチャカウント;
175                                         }
176                                 }
177                         }
178                 }
179
180                 private static long qpc周波数Hz = -1;      // キャッシュ
181                 private long bs_前回リセットした時点の生カウント = 0;
182                 private long 最後にキャプチャされたカウント = 0;
183                 private long 稼働中に一時停止した時点のキャプチャカウント = 0;
184                 private int 一時停止回数 = 0;
185                 private readonly object 排他利用 = new object();
186         }
187 }