OSDN Git Service

インストーラでインストールした SSTFEditor を起動するとメッセージが規定(英語)になるミスを修正。
[strokestylet/CsWin10Desktop3.git] / FDK24 / カウンタ / 単純増加後反復カウンタ.cs
1 using System;
2 using System.Diagnostics;
3
4 namespace FDK.カウンタ
5 {
6         /// <summary>
7         ///             ある int 型整数を、開始値から終了値まで、一定間隔で単純増加させるカウンタ。
8         ///             終了値に達したら開始値に戻る。以降、それを繰り返す。
9         /// </summary>
10         public class 単純増加後反復カウンタ
11         {
12                 /// <summary>
13                 ///             カウンタを進行し、現在の値を取得する。
14                 /// </summary>
15                 public int 現在値
16                 {
17                         get
18                         {
19                                 lock( this._スレッド間同期 )
20                                 {
21                                         this._進行する();
22                                         return this._現在値;
23                                 }
24                         }
25                 }
26
27                 /// <summary>
28                 ///             カウンタを進行し、現在の値を割合(0.0:開始値 ~ 1.0:終了値)に変換して取得する。
29                 /// </summary>
30                 public float 現在値の割合
31                 {
32                         get
33                         {
34                                 lock( this._スレッド間同期 )
35                                 {
36                                         Debug.Assert( 0 != ( this._終了値 - this._開始値 ) );
37                                         this._進行する();
38                                         return (float) ( this._現在値 - this._開始値 ) / (float) ( this._終了値 - this._開始値 );
39                                 }
40                         }
41                 }
42
43                 public int 開始値
44                 {
45                         get
46                         {
47                                 lock( this._スレッド間同期 )
48                                 {
49                                         return this._開始値;
50                                 }
51                         }
52                 }
53
54                 public int 終了値
55                 {
56                         get
57                         {
58                                 lock( this._スレッド間同期 )
59                                 {
60                                         return this._終了値;
61                                 }
62                         }
63                 }
64
65                 /// <summary>
66                 ///             カウンタを進行し、その結果、カウンタの進行がまだ動作中なら true を返す。
67                 ///             (終了値に達しているかどうかは別問題。)
68                 /// </summary>
69                 public bool 動作中である
70                 {
71                         get
72                         {
73                                 lock( this._スレッド間同期 )
74                                 {
75                                         this._進行する();    // 終了してるかどうか判定する前に、溜まってる進行を全部消化する。
76                                         return this._動作中;
77                                 }
78                         }
79                 }
80
81                 /// <summary>
82                 ///             カウンタの進行が一時停止されているなら true を返す。
83                 ///             (終了値に達しているかどうかは別問題。)
84                 /// </summary>
85                 public bool 停止中である => !this.動作中である;
86
87                 /// <summary>
88                 ///             初期化のみ行い、カウンタは開始しない。
89                 /// </summary>
90                 public 単純増加後反復カウンタ()
91                 {
92                         this._間隔ms = QPCTimer.未使用;
93                         this._定間隔進行 = null;
94
95                         this._開始値 = 0;
96                         this._終了値 = 0;
97                         this._現在値 = 0;
98                         this._動作中 = false;
99                 }
100
101                 /// <summary>
102                 ///             初期化し、同時にカウンタを開始する。
103                 /// </summary>
104                 public 単純増加後反復カウンタ( int 最初の値, int 最後の値, long 値をひとつ増加させるのにかける時間ms = 1000 ) : this()
105                 {
106                         this.開始する( 最初の値, 最後の値, 値をひとつ増加させるのにかける時間ms );
107                 }
108
109                 public void 開始する( int 最初の値, int 最後の値, long 値をひとつ増加させるのにかける時間ms = 1000 )
110                 {
111                         lock( this._スレッド間同期 )
112                         {
113                                 this._間隔ms = 値をひとつ増加させるのにかける時間ms;
114                                 this._定間隔進行 = new 定間隔進行(); // 同時に開始する。
115                                 this._開始値 = 最初の値;
116                                 this._終了値 = System.Math.Max( 最初の値, 最後の値 );    // 逆転しないことを保証。
117                                 this._現在値 = 最初の値;
118                                 this._動作中 = true;
119                         }
120                 }
121
122                 public void 一時停止する()
123                 {
124                         lock( this._スレッド間同期 )
125                         {
126                                 this._定間隔進行.経過時間の計測を一時停止する();
127                                 this._動作中 = false;
128                         }
129                 }
130
131                 public void 再開する()
132                 {
133                         lock( this._スレッド間同期 )
134                         {
135                                 this._定間隔進行.経過時間の計測を再開する();
136                                 this._動作中 = true;
137                         }
138                 }
139
140                 private int _開始値 = 0;
141
142                 private int _終了値 = 0;
143
144                 private int _現在値 = 0;
145
146                 private bool _動作中 = false;
147
148                 private long _間隔ms = QPCTimer.未使用;
149
150                 private 定間隔進行 _定間隔進行 = null;
151
152                 private readonly object _スレッド間同期 = new object();
153
154                 /// <summary>
155                 ///             前回のこのメソッドの呼び出しからの経過時間をもとに、必要なだけ現在値を増加させる。
156                 ///             カウント値が終了値に達している場合は、開始値に繰り戻す。
157                 /// </summary>
158                 private void _進行する()
159                 {
160                         if( this._間隔ms == QPCTimer.未使用 )
161                                 return; // 開始されていないなら無視。
162
163                         lock( this._スレッド間同期 )
164                         {
165                                 this._定間隔進行?.経過時間の分だけ進行する( this._間隔ms, () => {
166
167                                         if( this._動作中 )
168                                         {
169                                                 this._現在値++;
170
171                                                 // 終了値を超えていれば開始値に戻る。
172                                                 if( this._現在値 > this._終了値 )
173                                                         this._現在値 = this._開始値;
174                                         }
175
176                                 } );
177                         }
178                 }
179         }
180 }