using Google.Protobuf.WellKnownTypes; using System; using System.Threading; namespace Preparation.Utility { //其对应属性不应当有set访问器,避免不安全的=赋值 public abstract class Atomic { } public class AtomicInt : Atomic { protected int v; public AtomicInt(int x) { v = x; } public override string ToString() => Interlocked.CompareExchange(ref v, -1, -1).ToString(); public int Get() => Interlocked.CompareExchange(ref v, -1, -1); public static implicit operator int(AtomicInt aint) => Interlocked.CompareExchange(ref aint.v, -1, -1); /// 返回操作前的值 public virtual int SetReturnOri(int value) => Interlocked.Exchange(ref v, value); public virtual int Add(int x) => Interlocked.Add(ref v, x); /// /// 注意:确保参数为非负数 /// public virtual int AddPositive(int x) => Interlocked.Add(ref v, x); public virtual int Sub(int x) => Interlocked.Add(ref v, -x); /// /// 注意:确保参数为非负数 /// public virtual int SubPositive(int x) => Interlocked.Add(ref v, -x); public virtual int Inc() => Interlocked.Increment(ref v); public int Dec() => Interlocked.Decrement(ref v); /// 返回操作前的值 public virtual int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); } /// /// 参数要求倍率speed(默认1)以及AtomicInt类的Score, /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。 /// 注意:AtomicIntOnlyAddScore本身为AtomicInt,提供的Score可能构成环而死锁。 /// public class AtomicIntOnlyAddScore : AtomicInt { public AtomicInt Score { get; set; }; public AtomicDouble speed; public AtomicIntOnlyAddScore(int x, AtomicInt Score, double speed = 1.0) : base(x) { this.Score = Score; this.speed = new(speed); } /// 返回操作前的值 public override int SetReturnOri(int value) { int previousV = Interlocked.Exchange(ref v, value); if (value - previousV > 0) Score.AddPositive((int)(speed * (value - previousV))); return previousV; } public override int Add(int x) { if (x > 0) Score.AddPositive((int)(speed * x)); return Interlocked.Add(ref v, x); } /// /// 注意:确保参数为非负数 /// public override int AddPositive(int x) { Score.AddPositive((int)(speed * x)); return Interlocked.Add(ref v, x); } public override int Sub(int x) { if (x < 0) Score.AddPositive((int)(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((int)(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((int)(speed * (newV - previousV))); return previousV; } } public class AtomicLong : Atomic { protected long v; public AtomicLong(long x) { v = x; } public override string ToString() => Interlocked.CompareExchange(ref v, -1, -1).ToString(); public long Get() => Interlocked.CompareExchange(ref v, -1, -1); public static implicit operator long(AtomicLong along) => Interlocked.CompareExchange(ref along.v, -1, -1); /// 返回操作前的值 public virtual long SetReturnOri(long value) => Interlocked.Exchange(ref v, value); public virtual long Add(long x) => Interlocked.Add(ref v, x); /// /// 注意:确保参数为非负数 /// public virtual long AddPositive(long x) => Interlocked.Add(ref v, x); public virtual long Sub(long x) => Interlocked.Add(ref v, -x); /// /// 注意:确保参数为非负数 /// public virtual long SubPositive(long x) => Interlocked.Add(ref v, -x); public virtual long Inc() => Interlocked.Increment(ref v); public long Dec() => Interlocked.Decrement(ref v); /// 返回操作前的值 public virtual long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); } /// /// 参数要求倍率speed(默认1)以及AtomicLong类的Score, /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。 /// 注意:AtomicLongOnlyAddScore本身为AtomicLong,提供的Score可能构成环而死锁。 /// public class AtomicLongOnlyAddScore : AtomicLong { public AtomicInt Score { get; set; }; public AtomicDouble speed; public AtomicLongOnlyAddScore(long x, AtomicLong Score, double speed = 1.0) : base(x) { this.Score = Score; this.speed = new(speed); } /// 返回操作前的值 public override long SetReturnOri(long value) { long previousV = Interlocked.Exchange(ref v, value); if (value - previousV > 0) Score.AddPositive((long)(speed * (value - previousV))); return previousV; } public override long Add(long x) { if (x > 0) Score.AddPositive((long)(speed * x)); return Interlocked.Add(ref v, x); } /// /// 注意:确保参数为非负数 /// public override long AddPositive(long x) { Score.AddPositive((long)(speed * x)); return Interlocked.Add(ref v, x); } public override long Sub(long x) { if (x < 0) Score.AddPositive((long)(speed * -x)); return Interlocked.Add(ref v, -x); } /// /// 注意:确保参数为非负数 /// public override long SubPositive(long x) { return Interlocked.Add(ref v, -x); } public override long Inc() { Score.AddPositive((long)(speed)); return Interlocked.Increment(ref v); } /// 返回操作前的值 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))); return previousV; } } public class AtomicDouble : Atomic { private double v; public AtomicDouble(double x) { v = x; } public override string ToString() => Interlocked.CompareExchange(ref v, -2.0, -2.0).ToString(); public double Get() => Interlocked.CompareExchange(ref v, -2.0, -2.0); public static implicit operator double(AtomicDouble adouble) => Interlocked.CompareExchange(ref adouble.v, -2.0, -2.0); /// 返回操作前的值 public double SetReturnOri(double value) => Interlocked.Exchange(ref v, value); /// 返回操作前的值 public double CompareExReturnOri(double newV, double compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); } public class AtomicBool : Atomic { private int v;//v&1==0为false,v&1==1为true public AtomicBool(bool x) { v = x ? 1 : 0; } public override string ToString() => ((Interlocked.CompareExchange(ref v, -2, -2) & 1) == 0) ? "false" : "true"; public bool Get() => ((Interlocked.CompareExchange(ref v, -2, -2) & 1) == 1); public static implicit operator bool(AtomicBool abool) => abool.Get(); /// 返回操作前的值 public bool SetReturnOri(bool value) => ((Interlocked.Exchange(ref v, value ? 1 : 0) & 1) == 1); /// 赋值前的值是否与将赋予的值不相同 public bool TrySet(bool value) { return ((Interlocked.Exchange(ref v, value ? 1 : 0) & 1) != (value ? 1 : 0)); } public bool And(bool x) => (Interlocked.And(ref v, x ? 1 : 0) & 1) == 1; public bool Or(bool x) => (Interlocked.Or(ref v, x ? 1 : 0) & 1) == 1; /// 返回操作后的值 public bool Reverse() => (Interlocked.Increment(ref v) & 1) == 1; public bool Xor(bool x) => (Interlocked.Add(ref v, x ? 1 : 0) & 1) == 1; } }