Skip to content

Commit a51e6ec

Browse files
authored
Merge branch 'dev' into dev
2 parents 835c44f + 8bafabc commit a51e6ec

5 files changed

Lines changed: 246 additions & 10 deletions

File tree

logic/Preparation/Utility/Value/SafeValue/ISafeAddable.cs renamed to logic/Preparation/Utility/Value/IAddable.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
namespace Preparation.Utility
22
{
3-
public interface ISafeAddable<T>
3+
public interface IAddable<T>
44
{
55
public void Add(T value);
66
}

logic/Preparation/Utility/Value/SafeValue/Atomic.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ public class AtomicDouble(double x) : Atomic
3333
public double CompareExROri(double newV, double compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
3434
}
3535

36-
public class AtomicBool(bool x) : Atomic, ISafeAddable<bool>
36+
//许多情况下,volatile即可
37+
public class AtomicBool(bool x) : Atomic, IAddable<bool>
3738
{
3839
private int v = x ? 1 : 0;//v&1==0为false,v&1==1为true
3940

logic/Preparation/Utility/Value/SafeValue/AtomicInt.cs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace Preparation.Utility
55
{
66
//其对应属性不应当有set访问器,避免不安全的=赋值
77

8-
public class AtomicInt(int x) : Atomic, ISafeAddable<int>
8+
public class AtomicInt(int x) : Atomic, IAddable<int>
99
{
1010
protected int v = x;
1111

@@ -49,8 +49,8 @@ public class AtomicInt(int x) : Atomic, ISafeAddable<int>
4949
/// </summary>
5050
public class AtomicIntOnlyAddScore(int x, double speed = 1.0) : AtomicInt(x)
5151
{
52-
public ISafeAddable<int> score = new AtomicInt(0);
53-
public ISafeAddable<int> Score
52+
public IAddable<int> score = new AtomicInt(0);
53+
public IAddable<int> Score
5454
{
5555
get
5656
{
@@ -154,7 +154,18 @@ public int CompareExROriNotAddScore(int newV, int compareTo)
154154
/// </summary>
155155
public class AtomicIntChangeAffectScore(int x, double speed = 1.0) : AtomicInt(x)
156156
{
157-
public ISafeAddable<int> Score { get; set; } = new AtomicInt(0);
157+
public IAddable<int> score = new AtomicInt(0);
158+
public IAddable<int> Score
159+
{
160+
get
161+
{
162+
return Interlocked.CompareExchange(ref score, null, null);
163+
}
164+
set
165+
{
166+
Interlocked.Exchange(ref score, value);
167+
}
168+
}
158169
public AtomicDouble speed = new(speed);
159170

160171
/// <returns>返回操作前的值</returns>
@@ -249,7 +260,7 @@ public int CompareExROriNotAddScore(int newV, int compareTo)
249260
}
250261
}
251262

252-
public class AtomicLong(long x) : Atomic, ISafeAddable<int>, ISafeAddable<long>
263+
public class AtomicLong(long x) : Atomic, IAddable<int>, IAddable<long>
253264
{
254265
protected long v = x;
255266

@@ -280,7 +291,18 @@ public class AtomicLong(long x) : Atomic, ISafeAddable<int>, ISafeAddable<long>
280291
/// </summary>
281292
public class AtomicLongOnlyAddScore(long x, double speed = 1.0) : AtomicLong(x)
282293
{
283-
public ISafeAddable<long> Score { get; set; } = new AtomicLong(0);
294+
public IAddable<long> score = new AtomicLong(0);
295+
public IAddable<long> Score
296+
{
297+
get
298+
{
299+
return Interlocked.CompareExchange(ref score, null, null);
300+
}
301+
set
302+
{
303+
Interlocked.Exchange(ref score, value);
304+
}
305+
}
284306
public AtomicDouble speed = new(speed);
285307

286308
/// <returns>返回操作前的值</returns>

logic/Preparation/Utility/Value/SafeValue/LockedValue/InTheRange.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -374,8 +374,8 @@ public int AddV(StartTime startTime, double speed = 1.0)
374374
{
375375
int previousV = v;
376376
int addV = (int)((Environment.TickCount64 - startTime.Stop()) * speed);
377-
if (addV < 0) v += addV;
378-
else return 0;
377+
if (addV <= 0) return 0;
378+
else v += addV;
379379
if (v > maxV) v = maxV;
380380
return v - previousV;
381381
}
Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,213 @@
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

Comments
 (0)