diff --git a/logic/GameClass/GameObj/Character/Character.BuffManager.cs b/logic/GameClass/GameObj/Character/Character.BuffManager.cs index 1677eaa7..4979e42e 100644 --- a/logic/GameClass/GameObj/Character/Character.BuffManager.cs +++ b/logic/GameClass/GameObj/Character/Character.BuffManager.cs @@ -15,35 +15,15 @@ public partial class Character /// private class BuffManager { - [StructLayout(LayoutKind.Explicit, Size = 8)] - private struct BuffValue // buff参数联合体类型,可能是int或double - { - [FieldOffset(0)] - public int iValue; - [FieldOffset(0)] - public double lfValue; - - public BuffValue(int intValue) - { - this.lfValue = 0.0; - this.iValue = intValue; - } - public BuffValue(double longFloatValue) - { - this.iValue = 0; - this.lfValue = longFloatValue; - } - } - /// /// buff列表 /// - private readonly LinkedList[] buffList; + private readonly LinkedList[] buffList; private readonly object[] buffListLock; - private void AddBuff(BuffValue bf, int buffTime, BuffType buffType, Action ReCalculateFunc) + private void AddBuff(double bf, int buffTime, BuffType buffType, Action ReCalculateFunc) { - LinkedListNode buffNode; + LinkedListNode buffNode; lock (buffListLock[(int)buffType]) { buffNode = buffList[(int)buffType].AddLast(bf); @@ -80,13 +60,13 @@ public int ReCalculateFloatBuff(BuffType buffType, int orgVal, int maxVal, int m { foreach (var add in buffList[(int)buffType]) { - times *= add.lfValue; + times *= add; } } return Math.Max(Math.Min((int)Math.Round(orgVal * times), maxVal), minVal); } - public void AddMoveSpeed(double add, int buffTime, Action SetNewMoveSpeed, int orgMoveSpeed) => AddBuff(new BuffValue(add), buffTime, BuffType.AddSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.AddSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed))); + public void AddMoveSpeed(double add, int buffTime, Action SetNewMoveSpeed, int orgMoveSpeed) => AddBuff(add, buffTime, BuffType.AddSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.AddSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed))); public bool HasFasterSpeed { get @@ -98,7 +78,7 @@ public bool HasFasterSpeed } } - public void AddShield(int shieldTime) => AddBuff(new BuffValue(), shieldTime, BuffType.Shield, () => + public void AddShield(int shieldTime) => AddBuff(0, shieldTime, BuffType.Shield, () => { }); public bool HasShield { @@ -123,7 +103,7 @@ public bool TryUseShield() return false; } - public void AddAp(int time) => AddBuff(new BuffValue(), time, BuffType.AddAp, () => { }); + public void AddAp(int time) => AddBuff(0, time, BuffType.AddAp, () => { }); public bool HasAp { get @@ -147,7 +127,7 @@ public bool TryAddAp() return false; } - public void AddLife(int totelTime) => AddBuff(new BuffValue(), totelTime, BuffType.AddLife, () => + public void AddLife(int totelTime) => AddBuff(0, totelTime, BuffType.AddLife, () => { }); public bool HasLIFE { @@ -172,7 +152,7 @@ public bool TryActivatingLIFE() return false; } - public void AddSpear(int spearTime) => AddBuff(new BuffValue(), spearTime, BuffType.Spear, () => + public void AddSpear(int spearTime) => AddBuff(0, spearTime, BuffType.Spear, () => { }); public bool HasSpear { @@ -210,7 +190,7 @@ public bool TryDeleteInvisible() return false; } - public void AddClairaudience(int shieldTime) => AddBuff(new BuffValue(), shieldTime, BuffType.Clairaudience, () => + public void AddClairaudience(int shieldTime) => AddBuff(0, shieldTime, BuffType.Clairaudience, () => { }); public bool HasClairaudience { @@ -223,7 +203,7 @@ public bool HasClairaudience } } - public void AddInvisible(int shieldTime) => AddBuff(new BuffValue(), shieldTime, BuffType.Invisible, () => + public void AddInvisible(int shieldTime) => AddBuff(0, shieldTime, BuffType.Invisible, () => { }); public bool HasInvisible { @@ -253,12 +233,12 @@ public void ClearAll() public BuffManager() { var buffTypeArray = Enum.GetValues(typeof(BuffType)); - buffList = new LinkedList[buffTypeArray.Length]; + buffList = new LinkedList[buffTypeArray.Length]; buffListLock = new object[buffList.Length]; int i = 0; foreach (BuffType type in buffTypeArray) { - buffList[i] = new LinkedList(); + buffList[i] = new LinkedList(); buffListLock[i++] = new object(); } } diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 1461b7a8..720171c3 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -101,22 +101,13 @@ public void AddBgm(BgmType bgm, double value) #endregion #region 交互相关的基本属性及方法 private readonly int speedOfOpeningOrLocking; - public int SpeedOfOpeningOrLocking - { - get => speedOfOpeningOrLocking; - } + public int SpeedOfOpeningOrLocking => speedOfOpeningOrLocking; private readonly int speedOfClimbingThroughWindows; - public int SpeedOfClimbingThroughWindows - { - get => speedOfClimbingThroughWindows; - } + public int SpeedOfClimbingThroughWindows => speedOfClimbingThroughWindows; private readonly int speedOfOpenChest; - public int SpeedOfOpenChest - { - get => speedOfOpenChest; - } + public int SpeedOfOpenChest => speedOfOpenChest; #endregion #region 血量相关的基本属性及方法 public LongWithVariableRange HP { get; } diff --git a/logic/Preparation/Utility/SafeValue.cs b/logic/Preparation/Utility/SafeValue.cs deleted file mode 100644 index 286b721b..00000000 --- a/logic/Preparation/Utility/SafeValue.cs +++ /dev/null @@ -1,778 +0,0 @@ -using System; -using System.Threading; - -namespace Preparation.Utility -{ - //理论上结构体最好不可变,这里采用了可变结构。 - //其对应属性不应当有set访问器,避免不安全的=赋值 - public class AtomicInt - { - private 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 int SetReturnOri(int value) => Interlocked.Exchange(ref v, value); - public int Add(int x) => Interlocked.Add(ref v, x); - public int Sub(int x) => Interlocked.Add(ref v, -x); - public int Inc() => Interlocked.Increment(ref v); - public int Dec() => Interlocked.Decrement(ref v); - /// 返回操作前的值 - public int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); - } - - public class AtomicLong - { - private long v; - public AtomicLong(long x) - { - v = x; - } - public override string ToString() => Interlocked.Read(ref v).ToString(); - public long Get() => Interlocked.Read(ref v); - public static implicit operator long(AtomicLong aint) => Interlocked.Read(ref aint.v); - /// 返回操作前的值 - public long SetReturnOri(long value) => Interlocked.Exchange(ref v, value); - public long Add(long x) => Interlocked.Add(ref v, x); - public long Sub(long x) => Interlocked.Add(ref v, -x); - public long Inc() => Interlocked.Increment(ref v); - public long Dec() => Interlocked.Decrement(ref v); - /// 返回操作前的值 - public long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); - } - - public class AtomicBool - { - private int v;//v==0为false,v==1为true - public AtomicBool(bool x) - { - v = x ? 1 : 0; - } - public override string ToString() => (Interlocked.CompareExchange(ref v, -2, -2) == 0) ? "false" : "true"; - public bool Get() => (Interlocked.CompareExchange(ref v, -1, -1) != 0); - public static implicit operator bool(AtomicBool abool) => (Interlocked.CompareExchange(ref abool.v, -1, -1) != 0); - /// 返回操作前的值 - public bool SetReturnOri(bool value) => (Interlocked.Exchange(ref v, value ? 1 : 0) != 0); - /// 赋值前的值是否与将赋予的值不相同 - public bool TrySet(bool value) - { - return (Interlocked.CompareExchange(ref v, value ? 1 : 0, value ? 0 : 1) ^ (value ? 1 : 0)) != 0; - } - public bool And(bool x) => Interlocked.And(ref v, x ? 1 : 0) != 0; - public bool Or(bool x) => Interlocked.Or(ref v, x ? 1 : 0) != 0; - } - - /// - /// 根据时间推算Start后完成多少进度的进度条(long)。 - /// 只允许Start时修改needTime(请确保大于0); - /// 支持TrySet0使未完成的进度条终止清零;支持Set0使进度条强制终止清零; - /// 通过原子操作实现。 - /// - public class LongProgressByTime - { - private long endT = long.MaxValue; - private long needT; - - public LongProgressByTime(long needTime) - { - if (needTime <= 0) Debugger.Output("Bug:LongProgressByTime.needTime (" + needTime.ToString() + ") is less than 0."); - this.needT = needTime; - } - public LongProgressByTime() - { - this.needT = 0; - } - public long GetEndTime() => Interlocked.CompareExchange(ref endT, -2, -2); - public long GetNeedTime() => Interlocked.CompareExchange(ref needT, -2, -2); - public override string ToString() => "EndTime:" + Interlocked.CompareExchange(ref endT, -2, -2).ToString() + " ms, NeedTime:" + Interlocked.CompareExchange(ref needT, -2, -2).ToString() + " ms"; - public bool IsFinished() - { - return Interlocked.CompareExchange(ref endT, -2, -2) <= Environment.TickCount64; - } - public bool IsOpened() => Interlocked.Read(ref endT) != long.MaxValue; - /// - /// GetProgress<0则表明未开始 - /// - public long GetProgress() - { - long cutime = Interlocked.CompareExchange(ref endT, -2, -2) - Environment.TickCount64; - if (cutime <= 0) return Interlocked.CompareExchange(ref needT, -2, -2); - return Interlocked.CompareExchange(ref needT, -2, -2) - cutime; - } - public long GetNonNegativeProgress() - { - long cutime = Interlocked.CompareExchange(ref endT, -2, -2) - Environment.TickCount64; - if (cutime <= 0) return Interlocked.CompareExchange(ref needT, -2, -2); - long progress = Interlocked.CompareExchange(ref needT, -2, -2) - cutime; - return progress < 0 ? 0 : progress; - } - /// - /// GetProgress<0则表明未开始 - /// - public long GetProgress(long time) - { - long cutime = Interlocked.CompareExchange(ref endT, -2, -2) - time; - if (cutime <= 0) return Interlocked.CompareExchange(ref needT, -2, -2); - return Interlocked.CompareExchange(ref needT, -2, -2) - cutime; - } - public long GetNonNegativeProgress(long time) - { - long cutime = Interlocked.Read(ref endT) - time; - if (cutime <= 0) return Interlocked.CompareExchange(ref needT, -2, -2); - long progress = Interlocked.CompareExchange(ref needT, -2, -2) - cutime; - return progress < 0 ? 0 : progress; - } - /// - /// <0则表明未开始 - /// - public static implicit operator long(LongProgressByTime pLong) => pLong.GetProgress(); - - /// - /// GetProgressDouble<0则表明未开始 - /// - public double GetProgressDouble() - { - long cutime = Interlocked.CompareExchange(ref endT, -2, -2) - Environment.TickCount64; - if (cutime <= 0) return 1; - long needTime = Interlocked.CompareExchange(ref needT, -2, -2); - if (needTime == 0) return 0; - return 1.0 - ((double)cutime / needTime); - } - public double GetNonNegativeProgressDouble(long time) - { - long cutime = Interlocked.Read(ref endT) - time; - if (cutime <= 0) return 1; - long needTime = Interlocked.CompareExchange(ref needT, -2, -2); - if (needTime <= cutime) return 0; - return 1.0 - ((double)cutime / needTime); - } - - public bool Start(long needTime) - { - if (needTime <= 0) - { - Debugger.Output("Warning:Start LongProgressByTime with the needTime (" + needTime.ToString() + ") which is less than 0."); - return false; - } - //规定只有Start可以修改needT,且需要先访问endTime,从而避免锁(某种程度上endTime可以认为是needTime的锁) - if (Interlocked.CompareExchange(ref endT, Environment.TickCount64 + needTime, long.MaxValue) != long.MaxValue) return false; - if (needTime <= 2) Debugger.Output("Warning:the field of LongProgressByTime is " + needTime.ToString() + ",which is too small."); - Interlocked.Exchange(ref needT, needTime); - return true; - } - public bool Start() - { - long needTime = Interlocked.CompareExchange(ref needT, -2, -2); - if (Interlocked.CompareExchange(ref endT, Environment.TickCount64 + needTime, long.MaxValue) != long.MaxValue) return false; - return true; - } - /// - /// 使进度条强制终止清零 - /// - public void Set0() => Interlocked.Exchange(ref endT, long.MaxValue); - /// - /// 使未完成的进度条终止清零 - /// - public bool TrySet0() - { - if (Environment.TickCount64 < Interlocked.CompareExchange(ref endT, -2, -2)) - { - Interlocked.Exchange(ref endT, long.MaxValue); - return true; - } - return false; - } - //增加其他新的写操作可能导致不安全 - } - - /* - /// - /// 记录(不是根据时间)完成多少进度的进度条(long)。 - /// - public struct IntProgressByAdding - { - private int completedProgress = -1; - private int requiredProgress; - public IntProgressByAdding(int completedProgress, int requiredProgress) - { - this.completedProgress = completedProgress; - this.requiredProgress = requiredProgress; - } - public IntProgressByAdding(int requiredProgress) - { - this.requiredProgress = requiredProgress; - } - public IntProgressByAdding() - { - this.requiredProgress=int.MaxValue; - } - } - */ - - /// - /// 一个保证在[0,maxValue]的可变int,支持可变的maxValue(请确保大于0) - /// - public class IntWithVariableRange - { - private int v; - private int maxV; - private readonly object vLock = new(); - public IntWithVariableRange(int value, int maxValue) - { - if (maxValue < 0) - { - Debugger.Output("Warning:Try to set IntWithVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; - } - v = value < maxValue ? value : maxValue; - this.maxV = maxValue; - } - /// - /// 默认使Value=maxValue - /// - public IntWithVariableRange(int maxValue) - { - if (maxValue < 0) - { - Debugger.Output("Warning:Try to set IntWithVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; - } - v = this.maxV = maxValue; - } - public IntWithVariableRange() - { - v = this.maxV = int.MaxValue; - } - - public override string ToString() - { - lock (vLock) - { - return "value:" + v.ToString() + " ,maxValue:" + maxV.ToString(); - } - } - public int GetValue() { lock (vLock) return v; } - public static implicit operator int(IntWithVariableRange aint) => aint.GetValue(); - public int GetMaxV() { lock (vLock) return maxV; } - - /// - /// 若maxValue<=0则maxValue设为0并返回False - /// - public bool SetMaxV(int maxValue) - { - if (maxValue < 0) maxValue = 0; - lock (vLock) - { - maxV = maxValue; - if (v > maxValue) v = maxValue; - } - return maxValue > 0; - } - /// - /// 应当保证该maxValue>=0 - /// - public void SetPositiveMaxV(int maxValue) - { - lock (vLock) - { - maxV = maxValue; - if (v > maxValue) v = maxValue; - } - } - /// - /// 应当保证该value>=0 - /// - public int SetPositiveV(int value) - { - lock (vLock) - { - return v = (value > maxV) ? maxV : value; - } - } - public int SetV(int value) - { - if (value < 0) value = 0; - lock (vLock) - { - return v = (value > maxV) ? maxV : value; - } - } - /// - /// 返回实际改变量 - /// - public int AddV(int addV) - { - lock (vLock) - { - int previousV = v; - v += addV; - if (v < 0) v = 0; - if (v > maxV) v = maxV; - return v - previousV; - } - } - /// - /// 应当保证该增加值大于0,返回实际改变量 - /// - public int AddPositiveV(int addPositiveV) - { - lock (vLock) - { - addPositiveV = Math.Min(addPositiveV, maxV - v); - v += addPositiveV; - } - return addPositiveV; - } - /// - /// 应当保证该减少值大于0,返回实际改变量 - /// - public int SubPositiveV(int subPositiveV) - { - lock (vLock) - { - subPositiveV = Math.Min(subPositiveV, v); - v -= subPositiveV; - } - return subPositiveV; - } - - /// - /// 试图加到满,如果无法加到maxValue则不加并返回-1 - /// - public int TryAddAll(int addV) - { - lock (vLock) - { - if (maxV - v <= addV) - { - addV = maxV - v; - v = maxV; - return addV; - } - return 0; - } - } - } - - /// - /// 一个保证在[0,maxValue]的可变long,支持可变的maxValue(请确保大于0) - /// - public class LongWithVariableRange - { - private long v; - private long maxV; - private readonly object vLock = new(); - public LongWithVariableRange(long value, long maxValue) - { - if (maxValue < 0) - { - Debugger.Output("Warning:Try to set SafaValues.LongWithVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; - } - v = value < maxValue ? value : maxValue; - this.maxV = maxValue; - } - /// - /// 默认使Value=maxValue - /// - public LongWithVariableRange(long maxValue) - { - if (maxValue < 0) - { - Debugger.Output("Warning:Try to set SafaValues.LongWithVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; - } - v = this.maxV = maxValue; - } - public LongWithVariableRange() - { - v = this.maxV = long.MaxValue; - } - - public override string ToString() - { - lock (vLock) - { - return "value:" + v.ToString() + " ,maxValue:" + maxV.ToString(); - } - } - public long GetValue() { lock (vLock) return v; } - public static implicit operator long(LongWithVariableRange aint) => aint.GetValue(); - public long GetMaxV() { lock (vLock) return maxV; } - - /// - /// 若maxValue<=0则maxValue设为0并返回False - /// - public bool SetMaxV(long maxValue) - { - if (maxValue < 0) maxValue = 0; - lock (vLock) - { - maxV = maxValue; - if (v > maxValue) v = maxValue; - } - return maxValue > 0; - } - /// - /// 应当保证该maxValue>=0 - /// - public void SetPositiveMaxV(long maxValue) - { - lock (vLock) - { - maxV = maxValue; - if (v > maxValue) v = maxValue; - } - } - /// - /// 应当保证该value>=0 - /// - public long SetPositiveV(long value) - { - lock (vLock) - { - return v = (value > maxV) ? maxV : value; - } - } - public long SetV(long value) - { - if (value < 0) value = 0; - lock (vLock) - { - return v = (value > maxV) ? maxV : value; - } - } - /// - /// 返回实际改变量 - /// - public long AddV(long addV) - { - lock (vLock) - { - long previousV = v; - v += addV; - if (v < 0) v = 0; - if (v > maxV) v = maxV; - return v - previousV; - } - } - /// - /// 应当保证该增加值大于0,返回实际改变量 - /// - public long AddPositiveV(long addPositiveV) - { - lock (vLock) - { - addPositiveV = Math.Min(addPositiveV, maxV - v); - v += addPositiveV; - } - return addPositiveV; - } - /// - /// 应当保证该减少值大于0,返回实际改变量 - /// - public long SubPositiveV(long subPositiveV) - { - lock (vLock) - { - subPositiveV = Math.Min(subPositiveV, v); - v -= subPositiveV; - } - return subPositiveV; - } - - /// - /// 试图加到满,如果无法加到maxValue则不加并返回-1 - /// - public long TryAddAll(long addV) - { - lock (vLock) - { - if (maxV - v <= addV) - { - addV = maxV - v; - v = maxV; - return addV; - } - return -1; - } - } - } - - /// - /// 一个保证在[0,maxNum],每CDms自动+1的int,支持可变的CD、maxNum(请确保大于0) - /// - public class IntNumUpdateByCD - { - private int num; - private int maxNum; - private int cd; - private long updateTime = 0; - private readonly object numLock = new(); - public IntNumUpdateByCD(int num, int maxNum, int cd) - { - if (num < 0) Debugger.Output("Bug:IntNumUpdateByCD.num (" + num.ToString() + ") is less than 0."); - if (maxNum < 0) Debugger.Output("Bug:IntNumUpdateByCD.maxNum (" + maxNum.ToString() + ") is less than 0."); - if (cd <= 0) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 0."); - this.num = (num < maxNum) ? num : maxNum; - this.maxNum = maxNum; - this.cd = cd; - this.updateTime = Environment.TickCount64; - } - /// - /// 默认使num=maxNum - /// - public IntNumUpdateByCD(int maxNum, int cd) - { - if (maxNum < 0) Debugger.Output("Bug:IntNumUpdateByCD.maxNum (" + maxNum.ToString() + ") is less than 0."); - if (cd <= 0) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 0."); - this.num = this.maxNum = maxNum; - this.cd = cd; - } - public IntNumUpdateByCD() - { - this.num = this.maxNum = 0; - this.cd = int.MaxValue; - } - - public int GetMaxNum() { lock (numLock) return maxNum; } - public int GetCD() { lock (numLock) return cd; } - public int GetNum(long time) - { - lock (numLock) - { - if (num < maxNum && time - updateTime >= cd) - { - int add = (int)Math.Min(maxNum - num, (time - updateTime) / cd); - updateTime += add * cd; - return (num += add); - } - return num; - } - } - public static implicit operator int(IntNumUpdateByCD aint) => aint.GetNum(Environment.TickCount64); - - /// - /// 应当保证该subV>=0 - /// - public int TrySub(int subV) - { - if (subV < 0) Debugger.Output("Bug:IntNumUpdateByCD Try to sub " + subV.ToString() + ", which is less than 0."); - long time = Environment.TickCount64; - lock (numLock) - { - if (num < maxNum && time - updateTime >= cd) - { - int add = (int)Math.Min(maxNum - num, (time - updateTime) / cd); - updateTime += add * cd; - num += add; - } - if (num == maxNum) updateTime = time; - num -= subV = Math.Min(subV, num); - } - return subV; - } - /// - /// 应当保证该addV>=0 - /// - public void TryAdd(int addV) - { - if (addV < 0) Debugger.Output("Bug:IntNumUpdateByCD Try to add " + addV.ToString() + ", which is less than 0."); - lock (numLock) - { - num += Math.Min(addV, maxNum - num); - } - } - /// - /// 若maxNum<=0则maxNum及Num设为0并返回False - /// - public bool SetMaxNumAndNum(int maxNum) - { - if (maxNum < 0) maxNum = 0; - lock (numLock) - { - this.num = this.maxNum = maxNum; - } - return maxNum > 0; - } - /// - /// 应当保证该maxnum>=0 - /// - public void SetPositiveMaxNumAndNum(int maxNum) - { - lock (numLock) - { - this.num = this.maxNum = maxNum; - } - } - /// - /// 应当保证该maxnum>=0 - /// - public void SetPositiveMaxNum(int maxNum) - { - lock (numLock) - { - if ((this.maxNum = maxNum) < num) - num = maxNum; - } - } - /// - /// 若maxNum<=0则maxNum及Num设为0并返回False - /// - public bool SetMaxNum(int maxNum) - { - if (maxNum < 0) maxNum = 0; - lock (numLock) - { - if ((this.maxNum = maxNum) < num) - num = maxNum; - } - return maxNum > 0; - } - /// - /// 若num<0则num设为0并返回False - /// - public bool SetNum(int num) - { - lock (numLock) - { - if (num < 0) - { - this.num = 0; - updateTime = Environment.TickCount64; - return false; - } - if (num < maxNum) - { - if (this.num == maxNum) updateTime = Environment.TickCount64; - this.num = num; - } - else this.num = maxNum; - return true; - } - } - /// - /// 应当保证该num>=0 - /// - public void SetPositiveNum(int num) - { - lock (numLock) - { - if (num < maxNum) - { - if (this.num == maxNum) updateTime = Environment.TickCount64; - this.num = num; - } - else this.num = maxNum; - } - } - public void SetCD(int cd) - { - lock (numLock) - { - if (cd <= 0) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); - this.cd = cd; - } - } - } - - /// - /// 一个每CDms自动更新冷却的bool,支持可变的无锁CD,不支持查看当前进度,初始为True - /// - public class BoolCoolingDownByCD - { - private long cd; - private long nextUpdateTime = 0; - public BoolCoolingDownByCD(int cd) - { - if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); - this.cd = cd; - } - public BoolCoolingDownByCD(long cd) - { - if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); - this.cd = cd; - } - public BoolCoolingDownByCD(long cd, long startTime) - { - if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); - this.cd = cd; - this.nextUpdateTime = startTime; - } - - public long GetCD() => Interlocked.Read(ref cd); - - public bool TryUse() - { - long needTime = Interlocked.Exchange(ref nextUpdateTime, long.MaxValue); - if (needTime <= Environment.TickCount64) - { - Interlocked.Exchange(ref nextUpdateTime, Environment.TickCount64 + Interlocked.Read(ref cd)); - return true; - } - Interlocked.Exchange(ref nextUpdateTime, needTime); - return false; - } - public void SetCD(int cd) - { - if (cd <= 1) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); - Interlocked.Exchange(ref this.cd, cd); - } - } - - /// - /// 一个每CDms自动更新的进度条,支持可变的CD,初始为满 - /// - public class LongProgressCoolingDownByCD - { - private int isusing = 0; - private long cd; - private long nextUpdateTime = 0; - public LongProgressCoolingDownByCD(int cd) - { - if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); - this.cd = cd; - } - public LongProgressCoolingDownByCD(long cd) - { - if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); - this.cd = cd; - } - public LongProgressCoolingDownByCD(long cd, long startTime) - { - if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); - this.cd = cd; - this.nextUpdateTime = startTime; - } - - public long GetRemainingTime() - { - long v = Interlocked.Read(ref nextUpdateTime) - Environment.TickCount64; - return v < 0 ? 0 : v; - } - public long GetCD() => Interlocked.Read(ref cd); - - public bool TryUse() - { - if (Interlocked.Exchange(ref isusing, 1) == 1) return false; - long needTime = Interlocked.Read(ref nextUpdateTime); - if (needTime <= Environment.TickCount64) - { - Interlocked.Exchange(ref nextUpdateTime, Environment.TickCount64 + Interlocked.Read(ref cd)); - Interlocked.Exchange(ref isusing, 0); - return true; - } - Interlocked.Exchange(ref isusing, 0); - return false; - } - public void SetCD(int cd) - { - if (cd <= 1) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); - Interlocked.Exchange(ref this.cd, cd); - } - } -} \ No newline at end of file diff --git a/logic/Preparation/Utility/SafeValue/SafeValueDouble.cs b/logic/Preparation/Utility/SafeValue/SafeValueDouble.cs new file mode 100644 index 00000000..e3ac9c6d --- /dev/null +++ b/logic/Preparation/Utility/SafeValue/SafeValueDouble.cs @@ -0,0 +1,8 @@ +using System; +using System.Threading; + +namespace Preparation.Utility +{ + //其对应属性不应当有set访问器,避免不安全的=赋值 + +} \ No newline at end of file diff --git a/logic/Preparation/Utility/SafeValue/SafeValueInt.cs b/logic/Preparation/Utility/SafeValue/SafeValueInt.cs new file mode 100644 index 00000000..c26dc6b9 --- /dev/null +++ b/logic/Preparation/Utility/SafeValue/SafeValueInt.cs @@ -0,0 +1,371 @@ +using System; +using System.Threading; + +namespace Preparation.Utility +{ + //其对应属性不应当有set访问器,避免不安全的=赋值 + public class AtomicInt + { + private 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 int SetReturnOri(int value) => Interlocked.Exchange(ref v, value); + public int Add(int x) => Interlocked.Add(ref v, x); + public int Sub(int x) => Interlocked.Add(ref v, -x); + public int Inc() => Interlocked.Increment(ref v); + public int Dec() => Interlocked.Decrement(ref v); + /// 返回操作前的值 + public int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); + } + + /* + /// + /// 记录(不是根据时间)完成多少进度的进度条(long)。 + /// + public struct IntProgressByAdding + { + private int completedProgress = -1; + private int requiredProgress; + public IntProgressByAdding(int completedProgress, int requiredProgress) + { + this.completedProgress = completedProgress; + this.requiredProgress = requiredProgress; + } + public IntProgressByAdding(int requiredProgress) + { + this.requiredProgress = requiredProgress; + } + public IntProgressByAdding() + { + this.requiredProgress=int.MaxValue; + } + } + */ + + /// + /// 一个保证在[0,maxValue]的可变int,支持可变的maxValue(请确保大于0) + /// + public class IntWithVariableRange + { + private int v; + private int maxV; + private readonly object vLock = new(); + public IntWithVariableRange(int value, int maxValue) + { + if (maxValue < 0) + { + Debugger.Output("Warning:Try to set IntWithVariableRange.maxValue to " + maxValue.ToString() + "."); + maxValue = 0; + } + v = value < maxValue ? value : maxValue; + this.maxV = maxValue; + } + /// + /// 默认使Value=maxValue + /// + public IntWithVariableRange(int maxValue) + { + if (maxValue < 0) + { + Debugger.Output("Warning:Try to set IntWithVariableRange.maxValue to " + maxValue.ToString() + "."); + maxValue = 0; + } + v = this.maxV = maxValue; + } + public IntWithVariableRange() + { + v = this.maxV = int.MaxValue; + } + + public override string ToString() + { + lock (vLock) + { + return "value:" + v.ToString() + " ,maxValue:" + maxV.ToString(); + } + } + public int GetValue() { lock (vLock) return v; } + public static implicit operator int(IntWithVariableRange aint) => aint.GetValue(); + public int GetMaxV() { lock (vLock) return maxV; } + + /// + /// 若maxValue<=0则maxValue设为0并返回False + /// + public bool SetMaxV(int maxValue) + { + if (maxValue < 0) maxValue = 0; + lock (vLock) + { + maxV = maxValue; + if (v > maxValue) v = maxValue; + } + return maxValue > 0; + } + /// + /// 应当保证该maxValue>=0 + /// + public void SetPositiveMaxV(int maxValue) + { + lock (vLock) + { + maxV = maxValue; + if (v > maxValue) v = maxValue; + } + } + /// + /// 应当保证该value>=0 + /// + public int SetPositiveV(int value) + { + lock (vLock) + { + return v = (value > maxV) ? maxV : value; + } + } + public int SetV(int value) + { + if (value < 0) value = 0; + lock (vLock) + { + return v = (value > maxV) ? maxV : value; + } + } + /// 返回实际改变量 + public int AddV(int addV) + { + lock (vLock) + { + int previousV = v; + v += addV; + if (v < 0) v = 0; + if (v > maxV) v = maxV; + return v - previousV; + } + } + /// + /// 应当保证增加值大于0 + /// + /// 返回实际改变量 + public int AddPositiveV(int addPositiveV) + { + lock (vLock) + { + addPositiveV = Math.Min(addPositiveV, maxV - v); + v += addPositiveV; + } + return addPositiveV; + } + /// + /// 应当保证该减少值大于0,返回实际改变量 + /// + public int SubPositiveV(int subPositiveV) + { + lock (vLock) + { + subPositiveV = Math.Min(subPositiveV, v); + v -= subPositiveV; + } + return subPositiveV; + } + + /// + /// 试图加到满,如果无法加到maxValue则不加并返回-1 + /// + public int TryAddAll(int addV) + { + lock (vLock) + { + if (maxV - v <= addV) + { + addV = maxV - v; + v = maxV; + return addV; + } + return 0; + } + } + } + + /// + /// 一个保证在[0,maxNum],每CDms自动+1的int,支持可变的CD、maxNum(请确保大于0) + /// + public class IntNumUpdateByCD + { + private int num; + private int maxNum; + private int cd; + private long updateTime = 0; + private readonly object numLock = new(); + public IntNumUpdateByCD(int num, int maxNum, int cd) + { + if (num < 0) Debugger.Output("Bug:IntNumUpdateByCD.num (" + num.ToString() + ") is less than 0."); + if (maxNum < 0) Debugger.Output("Bug:IntNumUpdateByCD.maxNum (" + maxNum.ToString() + ") is less than 0."); + if (cd <= 0) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 0."); + this.num = (num < maxNum) ? num : maxNum; + this.maxNum = maxNum; + this.cd = cd; + this.updateTime = Environment.TickCount64; + } + /// + /// 默认使num=maxNum + /// + public IntNumUpdateByCD(int maxNum, int cd) + { + if (maxNum < 0) Debugger.Output("Bug:IntNumUpdateByCD.maxNum (" + maxNum.ToString() + ") is less than 0."); + if (cd <= 0) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 0."); + this.num = this.maxNum = maxNum; + this.cd = cd; + } + public IntNumUpdateByCD() + { + this.num = this.maxNum = 0; + this.cd = int.MaxValue; + } + + public int GetMaxNum() { lock (numLock) return maxNum; } + public int GetCD() { lock (numLock) return cd; } + public int GetNum(long time) + { + lock (numLock) + { + if (num < maxNum && time - updateTime >= cd) + { + int add = (int)Math.Min(maxNum - num, (time - updateTime) / cd); + updateTime += add * cd; + return (num += add); + } + return num; + } + } + public static implicit operator int(IntNumUpdateByCD aint) => aint.GetNum(Environment.TickCount64); + + /// + /// 应当保证该subV>=0 + /// + public int TrySub(int subV) + { + if (subV < 0) Debugger.Output("Bug:IntNumUpdateByCD Try to sub " + subV.ToString() + ", which is less than 0."); + long time = Environment.TickCount64; + lock (numLock) + { + if (num < maxNum && time - updateTime >= cd) + { + int add = (int)Math.Min(maxNum - num, (time - updateTime) / cd); + updateTime += add * cd; + num += add; + } + if (num == maxNum) updateTime = time; + num -= subV = Math.Min(subV, num); + } + return subV; + } + /// + /// 应当保证该addV>=0 + /// + public void TryAdd(int addV) + { + if (addV < 0) Debugger.Output("Bug:IntNumUpdateByCD Try to add " + addV.ToString() + ", which is less than 0."); + lock (numLock) + { + num += Math.Min(addV, maxNum - num); + } + } + /// + /// 若maxNum<=0则maxNum及Num设为0并返回False + /// + public bool SetMaxNumAndNum(int maxNum) + { + if (maxNum < 0) maxNum = 0; + lock (numLock) + { + this.num = this.maxNum = maxNum; + } + return maxNum > 0; + } + /// + /// 应当保证该maxnum>=0 + /// + public void SetPositiveMaxNumAndNum(int maxNum) + { + lock (numLock) + { + this.num = this.maxNum = maxNum; + } + } + /// + /// 应当保证该maxnum>=0 + /// + public void SetPositiveMaxNum(int maxNum) + { + lock (numLock) + { + if ((this.maxNum = maxNum) < num) + num = maxNum; + } + } + /// + /// 若maxNum<=0则maxNum及Num设为0并返回False + /// + public bool SetMaxNum(int maxNum) + { + if (maxNum < 0) maxNum = 0; + lock (numLock) + { + if ((this.maxNum = maxNum) < num) + num = maxNum; + } + return maxNum > 0; + } + /// + /// 若num<0则num设为0并返回False + /// + public bool SetNum(int num) + { + lock (numLock) + { + if (num < 0) + { + this.num = 0; + updateTime = Environment.TickCount64; + return false; + } + if (num < maxNum) + { + if (this.num == maxNum) updateTime = Environment.TickCount64; + this.num = num; + } + else this.num = maxNum; + return true; + } + } + /// + /// 应当保证该num>=0 + /// + public void SetPositiveNum(int num) + { + lock (numLock) + { + if (num < maxNum) + { + if (this.num == maxNum) updateTime = Environment.TickCount64; + this.num = num; + } + else this.num = maxNum; + } + } + public void SetCD(int cd) + { + lock (numLock) + { + if (cd <= 0) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); + this.cd = cd; + } + } + } +} \ No newline at end of file diff --git a/logic/Preparation/Utility/SafeValue/SafeValueLong.cs b/logic/Preparation/Utility/SafeValue/SafeValueLong.cs new file mode 100644 index 00000000..345d683b --- /dev/null +++ b/logic/Preparation/Utility/SafeValue/SafeValueLong.cs @@ -0,0 +1,171 @@ +using System; +using System.Threading; + +namespace Preparation.Utility +{ + //其对应属性不应当有set访问器,避免不安全的=赋值 + public class AtomicLong + { + private long v; + public AtomicLong(long x) + { + v = x; + } + public override string ToString() => Interlocked.Read(ref v).ToString(); + public long Get() => Interlocked.Read(ref v); + public static implicit operator long(AtomicLong aint) => Interlocked.Read(ref aint.v); + /// 返回操作前的值 + public long SetReturnOri(long value) => Interlocked.Exchange(ref v, value); + public long Add(long x) => Interlocked.Add(ref v, x); + public long Sub(long x) => Interlocked.Add(ref v, -x); + public long Inc() => Interlocked.Increment(ref v); + public long Dec() => Interlocked.Decrement(ref v); + /// 返回操作前的值 + public long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); + } + + /// + /// 一个保证在[0,maxValue]的可变long,支持可变的maxValue(请确保大于0) + /// + public class LongWithVariableRange + { + private long v; + private long maxV; + private readonly object vLock = new(); + public LongWithVariableRange(long value, long maxValue) + { + if (maxValue < 0) + { + Debugger.Output("Warning:Try to set SafaValues.LongWithVariableRange.maxValue to " + maxValue.ToString() + "."); + maxValue = 0; + } + v = value < maxValue ? value : maxValue; + this.maxV = maxValue; + } + /// + /// 默认使Value=maxValue + /// + public LongWithVariableRange(long maxValue) + { + if (maxValue < 0) + { + Debugger.Output("Warning:Try to set SafaValues.LongWithVariableRange.maxValue to " + maxValue.ToString() + "."); + maxValue = 0; + } + v = this.maxV = maxValue; + } + public LongWithVariableRange() + { + v = this.maxV = long.MaxValue; + } + + public override string ToString() + { + lock (vLock) + { + return "value:" + v.ToString() + " ,maxValue:" + maxV.ToString(); + } + } + public long GetValue() { lock (vLock) return v; } + public static implicit operator long(LongWithVariableRange aint) => aint.GetValue(); + public long GetMaxV() { lock (vLock) return maxV; } + + /// + /// 若maxValue<=0则maxValue设为0并返回False + /// + public bool SetMaxV(long maxValue) + { + if (maxValue < 0) maxValue = 0; + lock (vLock) + { + maxV = maxValue; + if (v > maxValue) v = maxValue; + } + return maxValue > 0; + } + /// + /// 应当保证该maxValue>=0 + /// + public void SetPositiveMaxV(long maxValue) + { + lock (vLock) + { + maxV = maxValue; + if (v > maxValue) v = maxValue; + } + } + /// + /// 应当保证该value>=0 + /// + public long SetPositiveV(long value) + { + lock (vLock) + { + return v = (value > maxV) ? maxV : value; + } + } + public long SetV(long value) + { + if (value < 0) value = 0; + lock (vLock) + { + return v = (value > maxV) ? maxV : value; + } + } + /// + /// 返回实际改变量 + /// + public long AddV(long addV) + { + lock (vLock) + { + long previousV = v; + v += addV; + if (v < 0) v = 0; + if (v > maxV) v = maxV; + return v - previousV; + } + } + /// + /// 应当保证该增加值大于0,返回实际改变量 + /// + public long AddPositiveV(long addPositiveV) + { + lock (vLock) + { + addPositiveV = Math.Min(addPositiveV, maxV - v); + v += addPositiveV; + } + return addPositiveV; + } + /// + /// 应当保证该减少值大于0,返回实际改变量 + /// + public long SubPositiveV(long subPositiveV) + { + lock (vLock) + { + subPositiveV = Math.Min(subPositiveV, v); + v -= subPositiveV; + } + return subPositiveV; + } + + /// + /// 试图加到满,如果无法加到maxValue则不加并返回-1 + /// + public long TryAddAll(long addV) + { + lock (vLock) + { + if (maxV - v <= addV) + { + addV = maxV - v; + v = maxV; + return addV; + } + return -1; + } + } + } +} \ No newline at end of file diff --git a/logic/Preparation/Utility/SafeValue/SafeValueOther.cs b/logic/Preparation/Utility/SafeValue/SafeValueOther.cs new file mode 100644 index 00000000..d839da72 --- /dev/null +++ b/logic/Preparation/Utility/SafeValue/SafeValueOther.cs @@ -0,0 +1,28 @@ +using System; +using System.Threading; + +namespace Preparation.Utility +{ + //其对应属性不应当有set访问器,避免不安全的=赋值 + + public class AtomicBool + { + private int v;//v==0为false,v==1为true + public AtomicBool(bool x) + { + v = x ? 1 : 0; + } + public override string ToString() => (Interlocked.CompareExchange(ref v, -2, -2) == 0) ? "false" : "true"; + public bool Get() => (Interlocked.CompareExchange(ref v, -1, -1) != 0); + public static implicit operator bool(AtomicBool abool) => (Interlocked.CompareExchange(ref abool.v, -1, -1) != 0); + /// 返回操作前的值 + public bool SetReturnOri(bool value) => (Interlocked.Exchange(ref v, value ? 1 : 0) != 0); + /// 赋值前的值是否与将赋予的值不相同 + public bool TrySet(bool value) + { + return (Interlocked.CompareExchange(ref v, value ? 1 : 0, value ? 0 : 1) ^ (value ? 1 : 0)) != 0; + } + public bool And(bool x) => Interlocked.And(ref v, x ? 1 : 0) != 0; + public bool Or(bool x) => Interlocked.Or(ref v, x ? 1 : 0) != 0; + } +} \ No newline at end of file diff --git a/logic/Preparation/Utility/SafeValue/SafeValueTime.cs b/logic/Preparation/Utility/SafeValue/SafeValueTime.cs new file mode 100644 index 00000000..41f911dc --- /dev/null +++ b/logic/Preparation/Utility/SafeValue/SafeValueTime.cs @@ -0,0 +1,226 @@ +using System; +using System.Threading; + +namespace Preparation.Utility +{ + //其对应属性不应当有set访问器,避免不安全的=赋值 + + /// + /// 根据时间推算Start后完成多少进度的进度条(long)。 + /// 只允许Start时修改needTime(请确保大于0); + /// 支持TrySet0使未完成的进度条终止清零;支持Set0使进度条强制终止清零; + /// 通过原子操作实现。 + /// + public class LongProgressByTime + { + private long endT = long.MaxValue; + private long needT; + + public LongProgressByTime(long needTime) + { + if (needTime <= 0) Debugger.Output("Bug:LongProgressByTime.needTime (" + needTime.ToString() + ") is less than 0."); + this.needT = needTime; + } + public LongProgressByTime() + { + this.needT = 0; + } + public long GetEndTime() => Interlocked.CompareExchange(ref endT, -2, -2); + public long GetNeedTime() => Interlocked.CompareExchange(ref needT, -2, -2); + public override string ToString() => "EndTime:" + Interlocked.CompareExchange(ref endT, -2, -2).ToString() + " ms, NeedTime:" + Interlocked.CompareExchange(ref needT, -2, -2).ToString() + " ms"; + public bool IsFinished() + { + return Interlocked.CompareExchange(ref endT, -2, -2) <= Environment.TickCount64; + } + public bool IsOpened() => Interlocked.Read(ref endT) != long.MaxValue; + /// + /// GetProgress<0则表明未开始 + /// + public long GetProgress() + { + long cutime = Interlocked.CompareExchange(ref endT, -2, -2) - Environment.TickCount64; + if (cutime <= 0) return Interlocked.CompareExchange(ref needT, -2, -2); + return Interlocked.CompareExchange(ref needT, -2, -2) - cutime; + } + public long GetNonNegativeProgress() + { + long cutime = Interlocked.CompareExchange(ref endT, -2, -2) - Environment.TickCount64; + if (cutime <= 0) return Interlocked.CompareExchange(ref needT, -2, -2); + long progress = Interlocked.CompareExchange(ref needT, -2, -2) - cutime; + return progress < 0 ? 0 : progress; + } + /// + /// GetProgress<0则表明未开始 + /// + public long GetProgress(long time) + { + long cutime = Interlocked.CompareExchange(ref endT, -2, -2) - time; + if (cutime <= 0) return Interlocked.CompareExchange(ref needT, -2, -2); + return Interlocked.CompareExchange(ref needT, -2, -2) - cutime; + } + public long GetNonNegativeProgress(long time) + { + long cutime = Interlocked.Read(ref endT) - time; + if (cutime <= 0) return Interlocked.CompareExchange(ref needT, -2, -2); + long progress = Interlocked.CompareExchange(ref needT, -2, -2) - cutime; + return progress < 0 ? 0 : progress; + } + /// + /// <0则表明未开始 + /// + public static implicit operator long(LongProgressByTime pLong) => pLong.GetProgress(); + + /// + /// GetProgressDouble<0则表明未开始 + /// + public double GetProgressDouble() + { + long cutime = Interlocked.CompareExchange(ref endT, -2, -2) - Environment.TickCount64; + if (cutime <= 0) return 1; + long needTime = Interlocked.CompareExchange(ref needT, -2, -2); + if (needTime == 0) return 0; + return 1.0 - ((double)cutime / needTime); + } + public double GetNonNegativeProgressDouble(long time) + { + long cutime = Interlocked.Read(ref endT) - time; + if (cutime <= 0) return 1; + long needTime = Interlocked.CompareExchange(ref needT, -2, -2); + if (needTime <= cutime) return 0; + return 1.0 - ((double)cutime / needTime); + } + + public bool Start(long needTime) + { + if (needTime <= 0) + { + Debugger.Output("Warning:Start LongProgressByTime with the needTime (" + needTime.ToString() + ") which is less than 0."); + return false; + } + //规定只有Start可以修改needT,且需要先访问endTime,从而避免锁(某种程度上endTime可以认为是needTime的锁) + if (Interlocked.CompareExchange(ref endT, Environment.TickCount64 + needTime, long.MaxValue) != long.MaxValue) return false; + if (needTime <= 2) Debugger.Output("Warning:the field of LongProgressByTime is " + needTime.ToString() + ",which is too small."); + Interlocked.Exchange(ref needT, needTime); + return true; + } + public bool Start() + { + long needTime = Interlocked.CompareExchange(ref needT, -2, -2); + if (Interlocked.CompareExchange(ref endT, Environment.TickCount64 + needTime, long.MaxValue) != long.MaxValue) return false; + return true; + } + /// + /// 使进度条强制终止清零 + /// + public void Set0() => Interlocked.Exchange(ref endT, long.MaxValue); + /// + /// 使未完成的进度条终止清零 + /// + public bool TrySet0() + { + if (Environment.TickCount64 < Interlocked.CompareExchange(ref endT, -2, -2)) + { + Interlocked.Exchange(ref endT, long.MaxValue); + return true; + } + return false; + } + //增加其他新的写操作可能导致不安全 + } + + /// + /// 一个每CDms自动更新冷却的bool,支持可变的无锁CD,不支持查看当前进度,初始为True + /// + public class BoolCoolingDownByCD + { + private long cd; + private long nextUpdateTime = 0; + public BoolCoolingDownByCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public BoolCoolingDownByCD(long cd) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public BoolCoolingDownByCD(long cd, long startTime) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + this.nextUpdateTime = startTime; + } + + public long GetCD() => Interlocked.Read(ref cd); + + public bool TryUse() + { + long needTime = Interlocked.Exchange(ref nextUpdateTime, long.MaxValue); + if (needTime <= Environment.TickCount64) + { + Interlocked.Exchange(ref nextUpdateTime, Environment.TickCount64 + Interlocked.Read(ref cd)); + return true; + } + Interlocked.Exchange(ref nextUpdateTime, needTime); + return false; + } + public void SetCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); + Interlocked.Exchange(ref this.cd, cd); + } + } + + /// + /// 一个每CDms自动更新的进度条,支持可变的CD,初始为满 + /// + public class LongProgressCoolingDownByCD + { + private int isusing = 0; + private long cd; + private long nextUpdateTime = 0; + public LongProgressCoolingDownByCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public LongProgressCoolingDownByCD(long cd) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public LongProgressCoolingDownByCD(long cd, long startTime) + { + if (cd <= 1) Debugger.Output("Bug:IntNumUpdateByCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + this.nextUpdateTime = startTime; + } + + public long GetRemainingTime() + { + long v = Interlocked.Read(ref nextUpdateTime) - Environment.TickCount64; + return v < 0 ? 0 : v; + } + public long GetCD() => Interlocked.Read(ref cd); + + public bool TryUse() + { + if (Interlocked.Exchange(ref isusing, 1) == 1) return false; + long needTime = Interlocked.Read(ref nextUpdateTime); + if (needTime <= Environment.TickCount64) + { + Interlocked.Exchange(ref nextUpdateTime, Environment.TickCount64 + Interlocked.Read(ref cd)); + Interlocked.Exchange(ref isusing, 0); + return true; + } + Interlocked.Exchange(ref isusing, 0); + return false; + } + public void SetCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); + Interlocked.Exchange(ref this.cd, cd); + } + } +} \ No newline at end of file