1+ using System ;
2+ using System . Numerics ;
3+ using System . Threading ;
4+
5+ namespace Preparation . Utility
6+ {
7+ /// <summary>
8+ /// 一个保证大于0的可变值
9+ /// 其对应属性不应当有set访问器,避免不安全的=赋值
10+ /// </summary>
11+ public class PositiveValue < T > : LockedValue
12+ where T : IConvertible , IComparable < T > , IComparable < int > , INumber < T >
13+ {
14+ protected T v ;
15+ #region 构造与读取
16+ public PositiveValue ( T value ) : base ( )
17+ {
18+ if ( value . CompareTo ( 0 ) < 0 )
19+ {
20+ Debugger . Output ( "Warning:Try to set PositiveValue to " + value . ToString ( ) + "." ) ;
21+ value = T . Zero ;
22+ }
23+ v = value ;
24+ }
25+ public PositiveValue ( ) : base ( )
26+ {
27+ v = T . Zero ;
28+ }
29+
30+ public override string ToString ( )
31+ {
32+ lock ( vLock )
33+ {
34+ return "value:" + v . ToString ( ) ;
35+ }
36+ }
37+ public T Get ( ) { lock ( vLock ) return v ; }
38+ public static implicit operator T ( PositiveValue < T > aint ) => aint . Get ( ) ;
39+ public bool IsZero ( ) { lock ( vLock ) return v == T . Zero ; }
40+ #endregion
41+
42+ #region 内嵌读取(在锁的情况下读取内容同时读取其他更基本的外部数据)
43+ public ( T , long ) GetValue ( StartTime startTime )
44+ {
45+ lock ( vLock )
46+ {
47+ return ( v , startTime . Get ( ) ) ;
48+ }
49+ }
50+ #endregion
51+
52+ #region 普通设置与计算
53+ public T SetRNow ( T value )
54+ {
55+ if ( value . CompareTo ( 0 ) < 0 )
56+ {
57+ lock ( vLock )
58+ {
59+ return v = T . Zero ;
60+ }
61+ }
62+ lock ( vLock )
63+ {
64+ return v = value ;
65+ }
66+ }
67+ /// <summary>
68+ /// 应当保证该value>=0
69+ /// </summary>
70+ public T SetPositiveVRNow ( T value )
71+ {
72+ lock ( vLock )
73+ {
74+ return v = value ;
75+ }
76+ }
77+
78+ public void Add ( T addV )
79+ {
80+ lock ( vLock )
81+ {
82+ v += addV ;
83+ if ( v . CompareTo ( 0 ) < 0 ) v = T . Zero ;
84+ }
85+ }
86+ /// <returns>返回实际改变量</returns>
87+ public T AddRChange ( T addV )
88+ {
89+ lock ( vLock )
90+ {
91+ T previousV = v ;
92+ v += addV ;
93+ if ( v . CompareTo ( 0 ) < 0 ) v = T . Zero ;
94+ return v - previousV ;
95+ }
96+ }
97+ /// <summary>
98+ /// 应当保证增加值大于0
99+ /// </summary>
100+ /// <returns>返回实际改变量</returns>
101+ public T AddPositiveVRChange ( T addPositiveV )
102+ {
103+ lock ( vLock )
104+ {
105+ v += addPositiveV ;
106+ }
107+ return addPositiveV ;
108+ }
109+ public void MulV ( T mulV )
110+ {
111+ if ( mulV . CompareTo ( 0 ) <= 0 )
112+ {
113+ lock ( vLock ) v = T . Zero ;
114+ return ;
115+ }
116+ lock ( vLock )
117+ {
118+ v *= mulV ;
119+ }
120+ }
121+ public void MulV < TA > ( TA mulV ) where TA : IConvertible , INumber < TA >
122+ {
123+ if ( mulV . CompareTo ( 0 ) < 0 )
124+ {
125+ lock ( vLock ) v = T . Zero ;
126+ return ;
127+ }
128+ lock ( vLock )
129+ {
130+ v = T . CreateChecked ( v . ToDouble ( null ) * mulV . ToDouble ( null ) ) ;
131+ }
132+ }
133+ /// <summary>
134+ /// 应当保证乘数大于0
135+ /// </summary>
136+ public void MulPositiveV ( T mulPositiveV )
137+ {
138+ lock ( vLock )
139+ {
140+ v *= mulPositiveV ;
141+ }
142+ }
143+
144+ /// <returns>返回实际改变量</returns>
145+ public T SubRChange ( T subV )
146+ {
147+ lock ( vLock )
148+ {
149+ subV = ( subV . CompareTo ( v ) > 0 ) ? v : subV ;
150+ v -= subV ;
151+ }
152+ return subV ;
153+ }
154+ #endregion
155+
156+ #region 特殊条件的设置和运算
157+ public bool Set0IfNot0 ( )
158+ {
159+ lock ( vLock )
160+ {
161+ if ( v . CompareTo ( 0 ) > 0 )
162+ {
163+ v = T . Zero ;
164+ return true ;
165+ }
166+ }
167+ return false ;
168+ }
169+ #endregion
170+
171+ #region 与LockedValue类的运算,运算会影响该对象的值
172+ public T AddRChange ( IntInTheVariableRange a )
173+ {
174+ return EnterOtherLock < T > ( a , ( ) =>
175+ {
176+ T previousV = v ;
177+ v += T . CreateChecked ( a . GetValue ( ) ) ;
178+ a . SubPositiveV ( ( v - previousV ) . ToInt32 ( null ) ) ;
179+ return v - previousV ;
180+ } ) ! ;
181+ }
182+ public T SubV ( IntInTheVariableRange a )
183+ {
184+ return EnterOtherLock < T > ( a , ( ) =>
185+ {
186+ T previousV = v ;
187+ v -= T . CreateChecked ( a . GetValue ( ) ) ;
188+ if ( v . CompareTo ( 0 ) < 0 ) v = T . Zero ;
189+ a . SubPositiveV ( ( previousV - v ) . ToInt32 ( null ) ) ;
190+ return previousV - v ;
191+ } ) ! ;
192+ }
193+ #endregion
194+
195+ #region 与StartTime类的特殊条件的运算,运算会影响StartTime类的值
196+ /// <summary>
197+ /// 增加量为时间差*速度,并将startTime变为long.MaxValue
198+ /// </summary>
199+ /// <returns>返回实际改变量</returns>
200+ public T AddV ( StartTime startTime , double speed = 1.0 )
201+ {
202+ lock ( vLock )
203+ {
204+ T previousV = v ;
205+ T addV = T . CreateChecked ( ( Environment . TickCount64 - startTime . Stop ( ) ) * speed ) ;
206+ if ( addV . CompareTo ( T . Zero ) <= 0 ) return T . Zero ;
207+ else v += addV ;
208+ return v - previousV ;
209+ }
210+ }
211+ #endregion
212+ }
213+ }
0 commit comments