From 4e5e4fd52a138396d54c17cd54ac126ed750a26a Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sat, 2 Dec 2023 22:45:15 +0800
Subject: [PATCH] feat: :sparkles: add AtomicIntOnlyAddLongScore
---
logic/Preparation/Utility/SafeValue/Atomic.cs | 136 +++++++++++++++---
1 file changed, 115 insertions(+), 21 deletions(-)
diff --git a/logic/Preparation/Utility/SafeValue/Atomic.cs b/logic/Preparation/Utility/SafeValue/Atomic.cs
index 5f9b31ec..fe475218 100644
--- a/logic/Preparation/Utility/SafeValue/Atomic.cs
+++ b/logic/Preparation/Utility/SafeValue/Atomic.cs
@@ -38,29 +38,106 @@ public AtomicInt(int x)
///
/// 参数要求倍率speed(默认1)以及AtomicInt类的Score,
- /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed取整。
+ /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。
/// 注意:AtomicIntOnlyAddScore本身为AtomicInt,提供的Score可能构成环而死锁。
///
public class AtomicIntOnlyAddScore : AtomicInt
{
public AtomicInt Score { get; set; }
public AtomicDouble speed;
+ public AtomicDouble remainder = new(0);
public AtomicIntOnlyAddScore(int x, AtomicInt Score, double speed = 1.0) : base(x)
{
this.Score = Score;
this.speed = new(speed);
}
+ private int DealWithRemainder(double v)
+ {
+ double q = v + remainder;
+ int ans = (int)(q);
+ remainder.SetReturnOri(q - ans);
+ return ans;
+ }
+ /// 返回操作前的值
+ public override int SetReturnOri(int value)
+ {
+ int previousV = Interlocked.Exchange(ref v, value);
+ if (value - previousV > 0)
+ Score.AddPositive((DealWithRemainder(speed * (value - previousV))));
+ return previousV;
+ }
+ public override int Add(int x)
+ {
+ if (x > 0) Score.AddPositive(DealWithRemainder(speed * x));
+ return Interlocked.Add(ref v, x);
+ }
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public override int AddPositive(int x)
+ {
+ Score.AddPositive(DealWithRemainder(speed * x));
+ return Interlocked.Add(ref v, x);
+ }
+ public override int Sub(int x)
+ {
+ if (x < 0) Score.AddPositive(DealWithRemainder(speed * -x));
+ return Interlocked.Add(ref v, -x);
+ }
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public override int SubPositive(int x)
+ {
+ return Interlocked.Add(ref v, -x);
+ }
+ public override int Inc()
+ {
+ Score.AddPositive(DealWithRemainder(speed));
+ return Interlocked.Increment(ref v);
+ }
+ /// 返回操作前的值
+ public override int CompareExReturnOri(int newV, int compareTo)
+ {
+ int previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
+ if (newV - previousV > 0)
+ Score.AddPositive(DealWithRemainder(speed * (newV - previousV)));
+ return previousV;
+ }
+ }
+
+ ///
+ /// 参数要求倍率speed(默认1)以及AtomicLong类的Score,
+ /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。
+ ///
+ public class AtomicIntOnlyAddLongScore : AtomicInt
+ {
+ public AtomicLong Score { get; set; }
+ public AtomicDouble speed;
+ public AtomicDouble remainder = new(0);
+ public AtomicIntOnlyAddLongScore(int x, AtomicLong Score, double speed = 1.0) : base(x)
+ {
+ this.Score = Score;
+ this.speed = new(speed);
+ }
+ private long DealWithRemainder(double v)
+ {
+ double q = v + remainder;
+ long ans = (long)(q);
+ remainder.SetReturnOri(q - ans);
+ return ans;
+ }
/// 返回操作前的值
public override int SetReturnOri(int value)
{
int previousV = Interlocked.Exchange(ref v, value);
if (value - previousV > 0)
- Score.AddPositive((int)(speed * (value - previousV)));
+ Score.AddPositive((DealWithRemainder(speed * (value - previousV))));
return previousV;
}
public override int Add(int x)
{
- if (x > 0) Score.AddPositive((int)(speed * x));
+ if (x > 0) Score.AddPositive(DealWithRemainder(speed * x));
return Interlocked.Add(ref v, x);
}
///
@@ -68,12 +145,12 @@ public override int Add(int x)
///
public override int AddPositive(int x)
{
- Score.AddPositive((int)(speed * x));
+ Score.AddPositive(DealWithRemainder(speed * x));
return Interlocked.Add(ref v, x);
}
public override int Sub(int x)
{
- if (x < 0) Score.AddPositive((int)(speed * -x));
+ if (x < 0) Score.AddPositive(DealWithRemainder(speed * -x));
return Interlocked.Add(ref v, -x);
}
///
@@ -85,7 +162,7 @@ public override int SubPositive(int x)
}
public override int Inc()
{
- Score.AddPositive((int)(speed));
+ Score.AddPositive(DealWithRemainder(speed));
return Interlocked.Increment(ref v);
}
/// 返回操作前的值
@@ -93,7 +170,7 @@ public override int CompareExReturnOri(int newV, int compareTo)
{
int previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
if (newV - previousV > 0)
- Score.AddPositive((int)(speed * (newV - previousV)));
+ Score.AddPositive(DealWithRemainder(speed * (newV - previousV)));
return previousV;
}
}
@@ -107,21 +184,29 @@ public class AtomicIntChangeAffectScore : AtomicInt
{
public AtomicInt Score { get; set; }
public AtomicDouble speed;
+ public AtomicDouble remainder = new(0);
public AtomicIntChangeAffectScore(int x, AtomicInt Score, double speed = 1.0) : base(x)
{
this.Score = Score;
this.speed = new(speed);
}
+ private int DealWithRemainder(double v)
+ {
+ double q = v + remainder;
+ int ans = (int)(q);
+ remainder.SetReturnOri(q - ans);
+ return ans;
+ }
/// 返回操作前的值
public override int SetReturnOri(int value)
{
int previousV = Interlocked.Exchange(ref v, value);
- Score.Add((int)(speed * (value - previousV)));
+ Score.Add(DealWithRemainder(speed * (value - previousV)));
return previousV;
}
public override int Add(int x)
{
- Score.Add((int)(speed * x));
+ Score.Add(DealWithRemainder(speed * x));
return Interlocked.Add(ref v, x);
}
///
@@ -129,12 +214,12 @@ public override int Add(int x)
///
public override int AddPositive(int x)
{
- Score.AddPositive((int)(speed * x));
+ Score.AddPositive(DealWithRemainder(speed * x));
return Interlocked.Add(ref v, x);
}
public override int Sub(int x)
{
- Score.Sub((int)(speed * x));
+ Score.Sub(DealWithRemainder(speed * x));
return Interlocked.Add(ref v, -x);
}
///
@@ -142,24 +227,24 @@ public override int Sub(int x)
///
public override int SubPositive(int x)
{
- Score.SubPositive((int)(speed * x));
+ Score.SubPositive(DealWithRemainder(speed * x));
return Interlocked.Add(ref v, -x);
}
public override int Inc()
{
- Score.AddPositive((int)(speed));
+ Score.AddPositive(DealWithRemainder(speed));
return Interlocked.Increment(ref v);
}
public override int Dec()
{
- Score.SubPositive((int)(speed));
+ Score.SubPositive(DealWithRemainder(speed));
return Interlocked.Decrement(ref v);
}
/// 返回操作前的值
public override int CompareExReturnOri(int newV, int compareTo)
{
int previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
- Score.Add((int)(speed * (newV - previousV)));
+ Score.Add(DealWithRemainder(speed * (newV - previousV)));
return previousV;
}
}
@@ -201,22 +286,31 @@ public class AtomicLongOnlyAddScore : AtomicLong
{
public AtomicLong Score { get; set; }
public AtomicDouble speed;
+ public AtomicDouble remainder;
public AtomicLongOnlyAddScore(long x, AtomicLong score, double speed = 1.0) : base(x)
{
this.Score = score;
this.speed = new(speed);
}
+ private long DealWithRemainder(double v)
+ {
+ double q = v + remainder;
+ long ans = (long)(q);
+ remainder.SetReturnOri(q - ans);
+ return ans;
+ }
+
/// 返回操作前的值
public override long SetReturnOri(long value)
{
long previousV = Interlocked.Exchange(ref v, value);
if (value - previousV > 0)
- Score.AddPositive((long)(speed * (value - previousV)));
+ Score.AddPositive(DealWithRemainder(speed * (value - previousV)));
return previousV;
}
public override long Add(long x)
{
- if (x > 0) Score.AddPositive((long)(speed * x));
+ if (x > 0) Score.AddPositive(DealWithRemainder(speed * x));
return Interlocked.Add(ref v, x);
}
///
@@ -224,12 +318,12 @@ public override long Add(long x)
///
public override long AddPositive(long x)
{
- Score.AddPositive((long)(speed * x));
+ Score.AddPositive(DealWithRemainder(speed * x));
return Interlocked.Add(ref v, x);
}
public override long Sub(long x)
{
- if (x < 0) Score.AddPositive((long)(speed * -x));
+ if (x < 0) Score.AddPositive(DealWithRemainder(speed * -x));
return Interlocked.Add(ref v, -x);
}
///
@@ -241,7 +335,7 @@ public override long SubPositive(long x)
}
public override long Inc()
{
- Score.AddPositive((long)(speed));
+ Score.AddPositive(DealWithRemainder(speed));
return Interlocked.Increment(ref v);
}
/// 返回操作前的值
@@ -249,7 +343,7 @@ public override long CompareExReturnOri(long newV, long compareTo)
{
long previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
if (newV - previousV > 0)
- Score.AddPositive((long)(speed * (newV - previousV)));
+ Score.AddPositive(DealWithRemainder(speed * (newV - previousV)));
return previousV;
}
}