From 33cd7dc98d5127b7441312fe3b41d75eca5dff8c Mon Sep 17 00:00:00 2001 From: shangfengh <3495281661@qq.com> Date: Tue, 10 Oct 2023 20:35:22 +0800 Subject: [PATCH] style: :art: change some names of values --- .../GameClass/GameObj/Character/Character.cs | 2 +- logic/GameClass/GameObj/Map/Chest.cs | 4 +- logic/Preparation/Interface/ICharacter.cs | 2 +- logic/Preparation/Interface/ISkill.cs | 36 +- logic/Preparation/Utility/SafeValue/Atomic.cs | 67 +++ .../Utility/SafeValue/InTheRange.cs | 359 ++++++++++++++++ .../Utility/SafeValue/SafeValueDouble.cs | 8 - .../Utility/SafeValue/SafeValueInt.cs | 371 ---------------- .../Utility/SafeValue/SafeValueLong.cs | 171 -------- .../Utility/SafeValue/SafeValueOther.cs | 28 -- .../Utility/SafeValue/SafeValueTime.cs | 226 ---------- .../Utility/SafeValue/TimeBased.cs | 403 ++++++++++++++++++ 12 files changed, 851 insertions(+), 826 deletions(-) create mode 100644 logic/Preparation/Utility/SafeValue/Atomic.cs create mode 100644 logic/Preparation/Utility/SafeValue/InTheRange.cs delete mode 100644 logic/Preparation/Utility/SafeValue/SafeValueDouble.cs delete mode 100644 logic/Preparation/Utility/SafeValue/SafeValueInt.cs delete mode 100644 logic/Preparation/Utility/SafeValue/SafeValueLong.cs delete mode 100644 logic/Preparation/Utility/SafeValue/SafeValueOther.cs delete mode 100644 logic/Preparation/Utility/SafeValue/SafeValueTime.cs create mode 100644 logic/Preparation/Utility/SafeValue/TimeBased.cs diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 720171c..b0c2d10 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -10,7 +10,7 @@ namespace GameClass.GameObj { #region 装弹、攻击相关的基本属性及方法 private readonly object attackLock = new(); - public IntNumUpdateByCD BulletNum { get; } = new IntNumUpdateByCD(); + public IntNumUpdateEachCD BulletNum { get; } = new IntNumUpdateEachCD(); private int orgCD; public int OrgCD { diff --git a/logic/GameClass/GameObj/Map/Chest.cs b/logic/GameClass/GameObj/Map/Chest.cs index 0fc6979..aae11fa 100644 --- a/logic/GameClass/GameObj/Map/Chest.cs +++ b/logic/GameClass/GameObj/Map/Chest.cs @@ -18,7 +18,7 @@ namespace GameClass.GameObj private readonly Gadget[] propInChest = new Gadget[GameData.maxNumOfPropInChest] { new NullProp(), new NullProp() }; public Gadget[] PropInChest => propInChest; - private LongProgressByTime openProgress = new LongProgressByTime(); - public LongProgressByTime OpenProgress { get => openProgress; } + private TimeBasedProgressForInterrupting openProgress = new TimeBasedProgressForInterrupting(); + public TimeBasedProgressForInterrupting OpenProgress { get => openProgress; } } } diff --git a/logic/Preparation/Interface/ICharacter.cs b/logic/Preparation/Interface/ICharacter.cs index dbddda8..4211ada 100644 --- a/logic/Preparation/Interface/ICharacter.cs +++ b/logic/Preparation/Interface/ICharacter.cs @@ -13,7 +13,7 @@ namespace Preparation.Interface public BulletType BulletOfPlayer { get; set; } public CharacterType CharacterType { get; } public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType); - public IntNumUpdateByCD BulletNum { get; } + public IntNumUpdateEachCD BulletNum { get; } public long SetPlayerState(RunningStateType running, PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null); public bool ResetPlayerState(long state, RunningStateType running = RunningStateType.Null, PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null); diff --git a/logic/Preparation/Interface/ISkill.cs b/logic/Preparation/Interface/ISkill.cs index d7b9330..02aa640 100644 --- a/logic/Preparation/Interface/ISkill.cs +++ b/logic/Preparation/Interface/ISkill.cs @@ -13,7 +13,7 @@ namespace Preparation.Interface } public interface IActiveSkill : ISkill { - public LongProgressCoolingDownByCD SkillCD { get; } + public LongProgressUpdateEachCD SkillCD { get; } public int DurationTime { get; } //技能持续时间 public object ActiveSkillUseLock { get; } public bool IsBeingUsed { get; set; } @@ -21,7 +21,7 @@ namespace Preparation.Interface public abstract class ActiveSkill : IActiveSkill { - public abstract LongProgressCoolingDownByCD SkillCD { get; } + public abstract LongProgressUpdateEachCD SkillCD { get; } public abstract int DurationTime { get; } private readonly object activeSkillUseLock = new(); @@ -40,79 +40,79 @@ namespace Preparation.Interface public class CanBeginToCharge : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 2); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 2); public override int DurationTime => GameData.commonSkillTime * 3 / 10; } public class BecomeInvisible : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4 / 3); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 4 / 3); public override int DurationTime => GameData.commonSkillTime; } public class Punish : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 45 / 30); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 45 / 30); public override int DurationTime => 0; } public class HaveTea : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 3); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 3); public override int DurationTime => 0; } public class Rouse : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 4); public override int DurationTime => 0; } public class Encourage : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 4); public override int DurationTime => 0; } public class Inspire : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 4); public override int DurationTime => 0; } public class Howl : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 25 / 30); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 25 / 30); public override int DurationTime => 0; } public class ShowTime : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 8 / 3); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 8 / 3); public override int DurationTime => GameData.commonSkillTime; } public class JumpyBomb : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD / 2); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD / 2); public override int DurationTime => GameData.commonSkillTime * 3 / 10; } public class SparksNSplash : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 45 / 30); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 45 / 30); public override int DurationTime => GameData.commonSkillTime; } public class UseKnife : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD); public override int DurationTime => GameData.commonSkillTime / 10; } public class UseRobot : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD / 300); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD / 300); public override int DurationTime => 0; private int nowPlayerID; @@ -149,7 +149,7 @@ namespace Preparation.Interface public class WriteAnswers : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD); public override int DurationTime => 0; private AtomicInt degreeOfMeditation = new(0); @@ -158,7 +158,7 @@ namespace Preparation.Interface public class SummonGolem : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD * 4 / 3); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD * 4 / 3); public override int DurationTime => 6000; private int[] golemStateArray = new int[GameData.maxSummonedGolemNum] { 0, 0, 0 }; @@ -211,7 +211,7 @@ namespace Preparation.Interface public class NullSkill : ActiveSkill { - public override LongProgressCoolingDownByCD SkillCD { get; } = new(GameData.commonSkillCD); + public override LongProgressUpdateEachCD SkillCD { get; } = new(GameData.commonSkillCD); public override int DurationTime => GameData.commonSkillTime; } diff --git a/logic/Preparation/Utility/SafeValue/Atomic.cs b/logic/Preparation/Utility/SafeValue/Atomic.cs new file mode 100644 index 0000000..5486c4a --- /dev/null +++ b/logic/Preparation/Utility/SafeValue/Atomic.cs @@ -0,0 +1,67 @@ +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; + } +} \ No newline at end of file diff --git a/logic/Preparation/Utility/SafeValue/InTheRange.cs b/logic/Preparation/Utility/SafeValue/InTheRange.cs new file mode 100644 index 0000000..2aa6bbb --- /dev/null +++ b/logic/Preparation/Utility/SafeValue/InTheRange.cs @@ -0,0 +1,359 @@ +using System; +using System.Threading; + +namespace Preparation.Utility +{ + + //其对应属性不应当有set访问器,避免不安全的=赋值 + /// + /// 一个保证在[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) + { + lock (vLock) + { + v = maxV = 0; + return false; + } + } + lock (vLock) + { + maxV = maxValue; + if (v > maxValue) v = maxValue; + } + return true; + } + /// + /// 应当保证该maxValue>=0 + /// + public void SetPositiveMaxV(int maxValue) + { + lock (vLock) + { + maxV = maxValue; + if (v > maxValue) v = maxValue; + } + } + /// + /// 如果当前值大于maxValue,则更新maxValue失败 + /// + public bool TrySetMaxV(int maxValue) + { + lock (vLock) + { + if (v > maxValue) return false; + maxV = maxValue; + return true; + } + } + + /// + /// 应当保证该value>=0 + /// + public int SetPositiveV(int value) + { + lock (vLock) + { + return v = (value > maxV) ? maxV : value; + } + } + public int SetV(int value) + { + if (value <= 0) + { + lock (vLock) + { + return v = 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; + } + public void MulV(int mulV) + { + if (mulV <= 0) + { + lock (vLock) v = 0; + return; + } + lock (vLock) + { + v *= mulV; + if (v > maxV) v = maxV; + } + } + /// + /// 应当保证乘数大于0 + /// + public void MulPositiveV(int mulPositiveV) + { + lock (vLock) + { + v *= mulPositiveV; + if (v > maxV) v = maxV; + } + } + /// 返回实际改变量 + public int SubV(int subV) + { + + lock (vLock) + { + subPositiveV = Math.Min(subPositiveV, v); + v -= subPositiveV; + } + return subPositiveV; + } + /// + /// 应当保证该减少值大于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 -1; + } + } + } + + /// + /// 一个保证在[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/SafeValueDouble.cs b/logic/Preparation/Utility/SafeValue/SafeValueDouble.cs deleted file mode 100644 index e3ac9c6..0000000 --- a/logic/Preparation/Utility/SafeValue/SafeValueDouble.cs +++ /dev/null @@ -1,8 +0,0 @@ -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 deleted file mode 100644 index c26dc6b..0000000 --- a/logic/Preparation/Utility/SafeValue/SafeValueInt.cs +++ /dev/null @@ -1,371 +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); - } - - /* - /// - /// 记录(不是根据时间)完成多少进度的进度条(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 deleted file mode 100644 index 345d683..0000000 --- a/logic/Preparation/Utility/SafeValue/SafeValueLong.cs +++ /dev/null @@ -1,171 +0,0 @@ -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 deleted file mode 100644 index d839da7..0000000 --- a/logic/Preparation/Utility/SafeValue/SafeValueOther.cs +++ /dev/null @@ -1,28 +0,0 @@ -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 deleted file mode 100644 index 41f911d..0000000 --- a/logic/Preparation/Utility/SafeValue/SafeValueTime.cs +++ /dev/null @@ -1,226 +0,0 @@ -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 diff --git a/logic/Preparation/Utility/SafeValue/TimeBased.cs b/logic/Preparation/Utility/SafeValue/TimeBased.cs new file mode 100644 index 0000000..566441c --- /dev/null +++ b/logic/Preparation/Utility/SafeValue/TimeBased.cs @@ -0,0 +1,403 @@ +using System; +using System.Threading; + +namespace Preparation.Utility +{ + //其对应属性不应当有set访问器,避免不安全的=赋值 + + /// + /// 根据时间推算Start后完成多少进度的进度条(long)。 + /// 只允许Start(清零状态的进度条才可以Start)时修改needTime(请确保大于0); + /// 支持InterruptToSet0使未完成的进度条终止清零;支持Set0使进度条强制终止清零; + /// 通过原子操作实现。 + /// + public class TimeBasedProgressForInterrupting + { + private long endT = long.MaxValue; + private long needT; + + public TimeBasedProgressForInterrupting(long needTime) + { + if (needTime <= 0) Debugger.Output("Bug:TimeBasedProgressForInterrupting.needTime (" + needTime.ToString() + ") is less than 0."); + this.needT = needTime; + } + public TimeBasedProgressForInterrupting() + { + 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(TimeBasedProgressForInterrupting 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 TimeBasedProgressForInterrupting 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 TimeBasedProgressForInterrupting 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 InterruptToSet0() + { + if (Environment.TickCount64 < Interlocked.CompareExchange(ref endT, -2, -2)) + { + Interlocked.Exchange(ref endT, long.MaxValue); + return true; + } + return false; + } + //增加其他新的写操作可能导致不安全 + } + + /// + /// 冷却时间为可变的CDms的bool,不支持查看当前进度,初始为True + /// + public class BoolUpdateEachCD + { + private long cd; + private long nextUpdateTime = 0; + public BoolUpdateEachCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:BoolUpdateEachCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public BoolUpdateEachCD(long cd) + { + if (cd <= 1) Debugger.Output("Bug:BoolUpdateEachCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public BoolUpdateEachCD(long cd, long startTime) + { + if (cd <= 1) Debugger.Output("Bug:BoolUpdateEachCD.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:BoolUpdateEachCD.cd to " + cd.ToString() + "."); + Interlocked.Exchange(ref this.cd, cd); + } + } + + /// + /// 冷却时间为可变的CDms的进度条,初始为满 + /// + public class LongProgressUpdateEachCD + { + private int isusing = 0; + private long cd; + private long nextUpdateTime = 0; + public LongProgressUpdateEachCD(int cd) + { + if (cd <= 1) Debugger.Output("Bug:LongProgressUpdateEachCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public LongProgressUpdateEachCD(long cd) + { + if (cd <= 1) Debugger.Output("Bug:LongProgressUpdateEachCD.cd (" + cd.ToString() + ") is less than 1."); + this.cd = cd; + } + public LongProgressUpdateEachCD(long cd, long startTime) + { + if (cd <= 1) Debugger.Output("Bug:LongProgressUpdateEachCD.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:Set LongProgressUpdateEachCD.cd to " + cd.ToString() + "."); + Interlocked.Exchange(ref this.cd, cd); + } + } + + /// + /// 一个保证在[0,maxNum],每CDms自动+1的int,支持可变的CD、maxNum(请确保大于0) + /// + public class IntNumUpdateEachCD + { + private int num; + private int maxNum; + private int cd; + private long updateTime = 0; + private readonly object numLock = new(); + public IntNumUpdateEachCD(int num, int maxNum, int cd) + { + if (num < 0) Debugger.Output("Bug:IntNumUpdateEachCD.num (" + num.ToString() + ") is less than 0."); + if (maxNum < 0) Debugger.Output("Bug:IntNumUpdateEachCD.maxNum (" + maxNum.ToString() + ") is less than 0."); + if (cd <= 0) Debugger.Output("Bug:IntNumUpdateEachCD.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 IntNumUpdateEachCD(int maxNum, int cd) + { + if (maxNum < 0) Debugger.Output("Bug:IntNumUpdateEachCD.maxNum (" + maxNum.ToString() + ") is less than 0."); + if (cd <= 0) Debugger.Output("Bug:IntNumUpdateEachCD.cd (" + cd.ToString() + ") is less than 0."); + this.num = this.maxNum = maxNum; + this.cd = cd; + } + public IntNumUpdateEachCD() + { + 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(IntNumUpdateEachCD aint) => aint.GetNum(Environment.TickCount64); + + /// + /// 应当保证该subV>=0 + /// + public int TrySub(int subV) + { + if (subV < 0) Debugger.Output("Bug:IntNumUpdateEachCD 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:IntNumUpdateEachCD 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:Set IntNumUpdateEachCD.cd to " + cd.ToString() + "."); + this.cd = cd; + } + } + } +} \ No newline at end of file