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; } }