diff --git a/logic/GameClass/GameObj/Areas/Construction.cs b/logic/GameClass/GameObj/Areas/Construction.cs index 9cfde48d..961c289f 100755 --- a/logic/GameClass/GameObj/Areas/Construction.cs +++ b/logic/GameClass/GameObj/Areas/Construction.cs @@ -6,7 +6,7 @@ public class Construction(XY initPos) : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Construction) { public AtomicLong TeamID { get; } = new(long.MaxValue); - public LongInTheVariableRange HP { get; } = new(0, GameData.CommunityHP); + public InVariableRange HP { get; } = new(0, GameData.CommunityHP); public override bool IsRigid => constructionType == ConstructionType.Community; public override ShapeType Shape => ShapeType.Square; @@ -58,7 +58,7 @@ public bool Construct(int constructSpeed, ConstructionType constructionType, Shi { return false; } - return ship.MoneyPool.SubMoney(HP.AddV(addHP) / 10) > 0; + return ship.MoneyPool.SubMoney(HP.AddPositiveVRChange(addHP) / 10) > 0; } public void BeAttacked(Bullet bullet) { diff --git a/logic/GameClass/GameObj/Areas/Home.cs b/logic/GameClass/GameObj/Areas/Home.cs index 68c1f812..629b3d93 100755 --- a/logic/GameClass/GameObj/Areas/Home.cs +++ b/logic/GameClass/GameObj/Areas/Home.cs @@ -7,7 +7,7 @@ public class Home(XY initPos, long id) : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Home), IHome { public long TeamID { get; } = id; - public LongInTheVariableRange HP => new(GameData.HomeHP); + public InVariableRange HP => new(GameData.HomeHP); public override bool IsRigid => false; public override ShapeType Shape => ShapeType.Square; diff --git a/logic/GameClass/GameObj/Areas/Resource.cs b/logic/GameClass/GameObj/Areas/Resource.cs index 2cd32dc1..dfc2ea5e 100755 --- a/logic/GameClass/GameObj/Areas/Resource.cs +++ b/logic/GameClass/GameObj/Areas/Resource.cs @@ -5,13 +5,13 @@ namespace GameClass.GameObj.Areas; public class Resource(XY initPos) : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Resource) { - public LongInTheVariableRange HP { get; } = new LongInTheVariableRange(GameData.ResourceHP); + public InVariableRange HP { get; } = new InVariableRange(GameData.ResourceHP); public override bool IsRigid => true; public override ShapeType Shape => ShapeType.Square; public AtomicInt ProduceNum { get; } = new AtomicInt(0); public bool Produce(int produceSpeed, Ship ship) { - return ship.MoneyPool.AddMoney(HP.SubV(produceSpeed)) > 0; + return ship.MoneyPool.AddMoney(HP.SubRChange(produceSpeed)) > 0; } public void AddProduceNum(int add = 1) { diff --git a/logic/GameClass/GameObj/Areas/Wormhole.cs b/logic/GameClass/GameObj/Areas/Wormhole.cs index fcc48dd3..b834fb23 100755 --- a/logic/GameClass/GameObj/Areas/Wormhole.cs +++ b/logic/GameClass/GameObj/Areas/Wormhole.cs @@ -7,7 +7,7 @@ namespace GameClass.GameObj.Areas; public class Wormhole(XY initPos, List grids) : Immovable(initPos, GameData.NumOfPosGridPerCell / 2, GameObjType.Wormhole), IWormhole { - public LongInTheVariableRange HP = new(GameData.WormholeHP); + public InVariableRange HP = new(GameData.WormholeHP); private readonly List grids = grids; public List Grids => grids; public override bool IsRigid => HP > GameData.WormholeHP / 2; @@ -20,7 +20,7 @@ public bool Repair(int constructSpeed, Ship ship) { return false; } - return ship.MoneyPool.SubMoney(HP.AddV(addHP) / 10) > 0; + return ship.MoneyPool.SubMoney(HP.AddRChange(addHP) / 10) > 0; } public void BeAttacked(Bullet bullet) { diff --git a/logic/GameClass/GameObj/Ship.cs b/logic/GameClass/GameObj/Ship.cs index a186824c..f0dfd93c 100755 --- a/logic/GameClass/GameObj/Ship.cs +++ b/logic/GameClass/GameObj/Ship.cs @@ -24,9 +24,9 @@ public override bool IgnoreCollideExecutor(IGameObj targetObj) return false; } // 属性值 - public LongInTheVariableRange HP { get; } - public LongInTheVariableRange Armor { get; } - public LongInTheVariableRange Shield { get; } + public InVariableRange HP { get; } + public InVariableRange Armor { get; } + public InVariableRange Shield { get; } public ShipType ShipType { get; } private ShipStateType shipState = ShipStateType.Null; public ShipStateType ShipState => shipState; @@ -160,37 +160,37 @@ public bool InstallModule(ModuleType moduleType) case ModuleType.Armor1: armorType = ArmorType.Armor1; armor = ModuleFactory.FindIArmor(ShipType, armorType); - Armor.SetV(armor.ArmorHP); + Armor.SetRNow(armor.ArmorHP); SubMoney(armor.Cost); return true; case ModuleType.Armor2: armorType = ArmorType.Armor2; armor = ModuleFactory.FindIArmor(ShipType, armorType); - Armor.SetV(armor.ArmorHP); + Armor.SetRNow(armor.ArmorHP); SubMoney(armor.Cost); return true; case ModuleType.Armor3: armorType = ArmorType.Armor3; armor = ModuleFactory.FindIArmor(ShipType, armorType); - Armor.SetV(armor.ArmorHP); + Armor.SetRNow(armor.ArmorHP); SubMoney(armor.Cost); return true; case ModuleType.Shield1: shieldType = ShieldType.Shield1; shield = ModuleFactory.FindIShield(ShipType, shieldType); - Shield.SetV(shield.ShieldHP); + Shield.SetRNow(shield.ShieldHP); SubMoney(shield.Cost); return true; case ModuleType.Shield2: shieldType = ShieldType.Shield2; shield = ModuleFactory.FindIShield(ShipType, shieldType); - Shield.SetV(shield.ShieldHP); + Shield.SetRNow(shield.ShieldHP); SubMoney(shield.Cost); return true; case ModuleType.Shield3: shieldType = ShieldType.Shield3; shield = ModuleFactory.FindIShield(ShipType, shieldType); - Shield.SetV(shield.ShieldHP); + Shield.SetRNow(shield.ShieldHP); SubMoney(shield.Cost); return true; case ModuleType.LaserGun: diff --git a/logic/Gaming/ShipManager.cs b/logic/Gaming/ShipManager.cs index b53e3c9f..51a6a639 100755 --- a/logic/Gaming/ShipManager.cs +++ b/logic/Gaming/ShipManager.cs @@ -125,8 +125,7 @@ public bool Recover(Ship ship, long recover) { return false; } - long actualRecover = ship.HP.AddPositiveV(recover); - Debugger.Output(ship, " 's HP is recovered to " + ship.HP.ToString()); + long actualRecover = ship.HP.AddPositiveVRChange(recover); ship.SubMoney((long)(actualRecover * 1.2)); return true; } diff --git a/logic/Preparation/Interface/IHome.cs b/logic/Preparation/Interface/IHome.cs index b21ec621..996fa847 100755 --- a/logic/Preparation/Interface/IHome.cs +++ b/logic/Preparation/Interface/IHome.cs @@ -5,6 +5,6 @@ namespace Preparation.Interface public interface IHome { public long TeamID { get; } - public LongInTheVariableRange HP { get; } + public InVariableRange HP { get; } } } diff --git a/logic/Preparation/Interface/IShip.cs b/logic/Preparation/Interface/IShip.cs index 3044a845..de261198 100755 --- a/logic/Preparation/Interface/IShip.cs +++ b/logic/Preparation/Interface/IShip.cs @@ -4,9 +4,9 @@ namespace Preparation.Interface { public interface IShip : IMovable, IPlayer { - public LongInTheVariableRange HP { get; } - public LongInTheVariableRange Armor { get; } - public LongInTheVariableRange Shield { get; } + public InVariableRange HP { get; } + public InVariableRange Armor { get; } + public InVariableRange Shield { get; } public ShipType ShipType { get; } public ShipStateType ShipState { get; } public IntNumUpdateEachCD BulletNum { get; } diff --git a/logic/Preparation/Utility/Value/IAddable.cs b/logic/Preparation/Utility/Value/IAddable.cs index 2df56199..c574389e 100644 --- a/logic/Preparation/Utility/Value/IAddable.cs +++ b/logic/Preparation/Utility/Value/IAddable.cs @@ -4,4 +4,9 @@ public interface IAddable { public void Add(T value); } + + public interface IIntAddable + { + public void Add(int value); + } } \ No newline at end of file diff --git a/logic/Preparation/Utility/Value/SafeValue/AtomicInt.cs b/logic/Preparation/Utility/Value/SafeValue/AtomicInt.cs index 835004bc..c37d6f77 100644 --- a/logic/Preparation/Utility/Value/SafeValue/AtomicInt.cs +++ b/logic/Preparation/Utility/Value/SafeValue/AtomicInt.cs @@ -5,7 +5,7 @@ namespace Preparation.Utility { //其对应属性不应当有set访问器,避免不安全的=赋值 - public class AtomicInt(int x) : Atomic, IAddable + public class AtomicInt(int x) : Atomic, IIntAddable { protected int v = x; @@ -49,8 +49,8 @@ public class AtomicInt(int x) : Atomic, IAddable /// public class AtomicIntOnlyAddScore(int x, double speed = 1.0) : AtomicInt(x) { - public IAddable score = new AtomicInt(0); - public IAddable Score + public IIntAddable score = new AtomicInt(0); + public IIntAddable Score { get { @@ -154,8 +154,8 @@ public int CompareExROriNotAddScore(int newV, int compareTo) /// public class AtomicIntChangeAffectScore(int x, double speed = 1.0) : AtomicInt(x) { - public IAddable score = new AtomicInt(0); - public IAddable Score + public IIntAddable score = new AtomicInt(0); + public IIntAddable Score { get { @@ -260,7 +260,7 @@ public int CompareExROriNotAddScore(int newV, int compareTo) } } - public class AtomicLong(long x) : Atomic, IAddable, IAddable + public class AtomicLong(long x) : Atomic, IIntAddable, IAddable { protected long v = x; diff --git a/logic/Preparation/Utility/Value/SafeValue/LockedValue/InTheRange.cs b/logic/Preparation/Utility/Value/SafeValue/LockedValue/InTheRange.cs index 7db41b1e..00949cb3 100644 --- a/logic/Preparation/Utility/Value/SafeValue/LockedValue/InTheRange.cs +++ b/logic/Preparation/Utility/Value/SafeValue/LockedValue/InTheRange.cs @@ -1,47 +1,46 @@ using System; +using System.Numerics; namespace Preparation.Utility { //其对应属性不应当有set访问器,避免不安全的=赋值 - public abstract class InTheVariableRange : LockedValue - { - } - /// - /// 一个保证在[0,maxValue]的可变int,支持可变的maxValue(请确保大于0) + /// 一个保证在[0,maxValue]的可变值,支持可变的maxValue(请确保大于0) /// - public class IntInTheVariableRange : InTheVariableRange + public class InVariableRange : LockedValue, IIntAddable, IAddable + where T : IConvertible, IComparable, INumber { - protected int v; - protected int maxV; + protected T v; + protected T maxV; #region 构造与读取 - public IntInTheVariableRange(int value, int maxValue) : base() + public InVariableRange(T value, T maxValue) : base() { - if (maxValue < 0) + if (value < T.Zero) + { + Debugger.Output("Warning:Try to set IntInTheVariableRange to " + value.ToString() + "."); + value = T.Zero; + } + if (maxValue < T.Zero) { Debugger.Output("Warning:Try to set IntInTheVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; + maxValue = T.Zero; } - v = value < maxValue ? value : maxValue; + v = value.CompareTo(maxValue) < 0 ? value : maxValue; this.maxV = maxValue; } /// /// 默认使Value=maxValue /// - public IntInTheVariableRange(int maxValue) : base() + public InVariableRange(T maxValue) : base() { - if (maxValue < 0) + if (maxValue < T.Zero) { Debugger.Output("Warning:Try to set IntInTheVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; + maxValue = T.Zero; } v = this.maxV = maxValue; } - public IntInTheVariableRange() : base() - { - v = this.maxV = int.MaxValue; - } public override string ToString() { @@ -50,22 +49,22 @@ public override string ToString() return "value:" + v.ToString() + " , maxValue:" + maxV.ToString(); } } - public int GetValue() { lock (vLock) return v; } - public static implicit operator int(IntInTheVariableRange aint) => aint.GetValue(); - public int GetMaxV() { lock (vLock) return maxV; } - public (int, int) GetValueAndMaxV() { lock (vLock) return (v, maxV); } + public T GetValue() { lock (vLock) return v; } + public static implicit operator T(InVariableRange aint) => aint.GetValue(); + public T GetMaxV() { lock (vLock) return maxV; } + public (T, T) GetValueAndMaxV() { lock (vLock) return (v, maxV); } public bool IsMaxV() { lock (vLock) return v == maxV; } #endregion #region 内嵌读取(在锁的情况下读取内容同时读取其他更基本的外部数据) - public (int, long) GetValue(StartTime startTime) + public (T, long) GetValue(StartTime startTime) { lock (vLock) { return (v, startTime.Get()); } } - public (int, int, long) GetValueAndMaxValue(StartTime startTime) + public (T, T, long) GetValueAndMaxValue(StartTime startTime) { lock (vLock) { @@ -78,13 +77,13 @@ public override string ToString() /// /// 若maxValue<=0则maxValue设为0并返回False /// - public bool SetMaxV(int maxValue) + public bool SetMaxV(T maxValue) { - if (maxValue <= 0) + if (maxValue.CompareTo(0) <= 0) { lock (vLock) { - v = maxV = 0; + v = maxV = T.Zero; return false; } } @@ -98,7 +97,7 @@ public bool SetMaxV(int maxValue) /// /// 应当保证该maxValue>=0 /// - public void SetPositiveMaxV(int maxValue) + public void SetPositiveMaxV(T maxValue) { lock (vLock) { @@ -107,13 +106,13 @@ public void SetPositiveMaxV(int maxValue) } } - public int SetV(int value) + public T SetRNow(T value) { - if (value <= 0) + if (value.CompareTo(0) <= 0) { lock (vLock) { - return v = 0; + return v = T.Zero; } } lock (vLock) @@ -124,7 +123,7 @@ public int SetV(int value) /// /// 应当保证该value>=0 /// - public int SetPositiveV(int value) + public T SetPositiveVRNow(T value) { lock (vLock) { @@ -137,7 +136,7 @@ public int SetPositiveV(int value) /// /// 如果当前值大于maxValue,则更新maxValue失败 /// - public bool TrySetMaxV(int maxValue) + public bool TrySetMaxV(T maxValue) { lock (vLock) { @@ -157,16 +156,16 @@ public void SetVToMaxV(double ratio) { lock (vLock) { - v = (int)(maxV * ratio); + v = T.CreateChecked(maxV.ToDouble(null) * ratio); } } public bool Set0IfNotMaxor0() { lock (vLock) { - if (v < maxV && v > 0) + if (v < maxV && v.CompareTo(0) > 0) { - v = 0; + v = T.Zero; return true; } } @@ -178,7 +177,7 @@ public bool Set0IfMax() { if (v == maxV) { - v = 0; + v = T.Zero; return true; } } @@ -187,373 +186,67 @@ public bool Set0IfMax() #endregion #region 普通运算 - /// 返回实际改变量 - public int AddV(int addV) + public void Add(T 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) - { - if (v > maxV / mulV) v = maxV; //避免溢出 - else v *= mulV; - } - } - public void MulV(double mulV) - { - if (mulV <= 0) - { - lock (vLock) v = 0; - return; - } - lock (vLock) - { - if (v > maxV / mulV) v = maxV; //避免溢出 - else v = (int)(v * mulV); - } - } - /// - /// 应当保证乘数大于0 - /// - public void MulPositiveV(int mulPositiveV) - { - lock (vLock) - { - if (v > maxV / mulPositiveV) v = maxV; //避免溢出 - else v *= mulPositiveV; - } - } - /// - /// 应当保证乘数大于0 - /// - public void MulPositiveV(double mulPositiveV) - { - lock (vLock) - { - if (v > maxV / mulPositiveV) v = maxV; //避免溢出 - else v = (int)(v * mulPositiveV); - } - } - /// 返回实际改变量 - public int SubV(int subV) - { - lock (vLock) - { - int previousV = v; - v -= subV; - if (v < 0) v = 0; + if (v < T.Zero) v = T.Zero; if (v > maxV) v = maxV; - return v - previousV; - } - } - /// - /// 应当保证该减少值大于0 - /// - /// 返回实际改变量 - public int SubPositiveV(int subPositiveV) - { - lock (vLock) - { - subPositiveV = Math.Min(subPositiveV, v); - v -= subPositiveV; - } - return subPositiveV; - } - #endregion - - #region 特殊条件的运算 - /// - /// 试图加到满,如果无法加到maxValue则不加并返回-1 - /// - /// 返回实际改变量 - public int TryAddToMaxV(int addV) - { - lock (vLock) - { - if (maxV - v <= addV) - { - addV = maxV - v; - v = maxV; - return addV; - } - return -1; } } - - /// - /// ratio可以为负 - /// - /// 返回实际改变量 - public int VAddPartMaxV(double ratio) + public void Add(int addV) { lock (vLock) { - int preV = v; - v += (int)(ratio * maxV); - if (v < 0) v = 0; + v += T.CreateChecked(addV); + if (v < T.Zero) v = T.Zero; if (v > maxV) v = maxV; - return v - preV; } } - #endregion - #region 与InTheVariableRange类的运算,运算会影响该对象的值 - public int AddV(IntInTheVariableRange a) - { - return EnterOtherLock(a, () => - { - int previousV = v; - v += a.GetValue(); - if (v > maxV) v = maxV; - a.SubPositiveV(v - previousV); - return v - previousV; - }); - } - public int SubV(IntInTheVariableRange a) - { - return EnterOtherLock(a, () => - { - int previousV = v; - v -= a.GetValue(); - if (v < 0) v = 0; - a.SubPositiveV(previousV - v); - return previousV - v; - }); - } - #endregion - - #region 与StartTime类的特殊条件的运算,运算会影响StartTime类的值 - /// - /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue - /// 如果无法加到maxValue则不加 - /// - /// 返回试图加到的值与最大值 - public (int, int, long) TryAddToMaxV(StartTime startTime, double speed = 1.0) - { - lock (vLock) - { - long addV = (long)(startTime.StopIfPassing(maxV - v) * speed); - if (addV < 0) return (v, maxV, startTime.Get()); - if (maxV - v < addV) return (v = maxV, maxV, startTime.Get()); - return ((int)(v + addV), maxV, startTime.Get()); - } - } - /// - /// 增加量为时间差*速度,并将startTime变为long.MaxValue - /// /// 返回实际改变量 - public int AddV(StartTime startTime, double speed = 1.0) + public T AddRChange(T addV) { lock (vLock) { - int previousV = v; - int addV = (int)((Environment.TickCount64 - startTime.Stop()) * speed); - if (addV <= 0) return 0; - else v += addV; + T previousV = v; + v += addV; + if (v < T.Zero) v = T.Zero; if (v > maxV) v = maxV; return v - previousV; } } - - /// - /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue - /// 如果无法加到maxValue则清零 - /// - /// 返回是否清零 - public bool Set0IfNotAddToMaxV(StartTime startTime, double speed = 1.0) - { - lock (vLock) - { - if (v == maxV) return false; - int addV = (int)(startTime.StopIfPassing(maxV - v) * speed); - if (addV < 0) - { - v = 0; - return true; - } - if (maxV - v < addV) - { - v = maxV; - return false; - } - v = 0; - return false; - } - } - #endregion - } - - /// - /// 一个保证在[0,maxValue]的可变long,支持可变的maxValue(请确保大于0) - /// - public class LongInTheVariableRange : InTheVariableRange - { - protected long v; - protected long maxV; - #region 构造与读取 - public LongInTheVariableRange(long value, long maxValue) : base() - { - if (maxValue < 0) - { - Debugger.Output("Warning:Try to set SafaValues.LongInTheVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; - } - v = value < maxValue ? value : maxValue; - this.maxV = maxValue; - } - /// - /// 默认使Value=maxValue - /// - public LongInTheVariableRange(long maxValue) : base() - { - if (maxValue < 0) - { - Debugger.Output("Warning:Try to set SafaValues.LongInTheVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; - } - v = this.maxV = maxValue; - } - public LongInTheVariableRange() : base() - { - 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(LongInTheVariableRange aint) => aint.GetValue(); - public long GetMaxV() { lock (vLock) return maxV; } - public (long, long) GetValueAndMaxV() { lock (vLock) return (v, maxV); } - public bool IsMaxV() - { - lock (vLock) - { - return v == maxV; - } - } - #endregion - - #region 普通设置MaxV与Value的值的方法 - /// - /// 若maxValue<=0则maxValue设为0并返回False - /// - public bool SetMaxV(long 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(long maxValue) - { - lock (vLock) - { - maxV = maxValue; - if (v > maxValue) v = maxValue; - } - } - - public long SetV(long value) - { - if (value <= 0) - { - lock (vLock) - { - return v = 0; - } - } - lock (vLock) - { - return v = (value > maxV) ? maxV : value; - } - } /// - /// 应当保证该value>=0 + /// 应当保证增加值大于0 /// - public long SetPositiveV(long value) - { - lock (vLock) - { - return v = (value > maxV) ? maxV : value; - } - } - #endregion - - #region 普通运算 /// 返回实际改变量 - public long AddV(long addV) + public T AddPositiveVRChange(T addPositiveV) { lock (vLock) { - long previousV = v; - v += addV; - if (v < 0) v = 0; - if (v > maxV) v = maxV; - return v - previousV; + addPositiveV = (addPositiveV < maxV - v) ? addPositiveV : maxV - v; + v += addPositiveV; } + return addPositiveV; } /// /// 应当保证增加值大于0 /// - /// 返回实际改变量 - public long AddPositiveV(long addPositiveV) + public void AddPositiveV(T addPositiveV) { lock (vLock) { - addPositiveV = Math.Min(addPositiveV, maxV - v); v += addPositiveV; + if (v > maxV) v = maxV; } - return addPositiveV; } - public void MulV(long mulV) + + public void Mul(T mulV) { - if (mulV <= 0) + if (mulV <= T.Zero) { - lock (vLock) v = 0; + lock (vLock) v = T.Zero; return; } lock (vLock) @@ -562,23 +255,24 @@ public void MulV(long mulV) else v *= mulV; } } - public void MulV(double mulV) + public void Mul(TA mulV) where TA : IConvertible, INumber { - if (mulV <= 0) + if (mulV < TA.Zero) { - lock (vLock) v = 0; + lock (vLock) v = T.Zero; return; } lock (vLock) { - if (v > maxV / mulV) v = maxV; //避免溢出 - else v = (long)(v * mulV); + if (v > T.CreateChecked(maxV.ToDouble(null) / mulV.ToDouble(null))) v = maxV; //避免溢出 + else + v = T.CreateChecked(v.ToDouble(null) * mulV.ToDouble(null)); } } /// /// 应当保证乘数大于0 /// - public void MulPositiveV(long mulPositiveV) + public void MulPositiveV(T mulPositiveV) { lock (vLock) { @@ -589,22 +283,23 @@ public void MulPositiveV(long mulPositiveV) /// /// 应当保证乘数大于0 /// - public void MulPositiveV(double mulPositiveV) + public void MulPositiveV(TA mulV) where TA : IConvertible, INumber { lock (vLock) { - if (v > maxV / mulPositiveV) v = maxV; //避免溢出 - else v = (long)(v * mulPositiveV); + if (v > T.CreateChecked(maxV.ToDouble(null) / mulV.ToDouble(null))) v = maxV; //避免溢出 + else + v = T.CreateChecked(v.ToDouble(null) * mulV.ToDouble(null)); } } /// 返回实际改变量 - public long SubV(long subV) + public T SubRChange(T subV) { lock (vLock) { - long previousV = v; + T previousV = v; v -= subV; - if (v < 0) v = 0; + if (v < T.Zero) v = T.Zero; if (v > maxV) v = maxV; return v - previousV; } @@ -613,67 +308,24 @@ public long SubV(long subV) /// 应当保证该减少值大于0 /// /// 返回实际改变量 - public long SubPositiveV(long subPositiveV) + public T SubPositiveVRChange(T subPositiveV) { lock (vLock) { - subPositiveV = Math.Min(subPositiveV, v); + subPositiveV = (subPositiveV < v) ? subPositiveV : v; v -= subPositiveV; } return subPositiveV; } - #endregion - - #region 特殊条件的设置MaxV与Value的值的方法 /// - /// 如果当前值大于maxValue,则更新maxValue失败 + /// 应当保证该减少值大于0 /// - public bool TrySetMaxV(long maxValue) - { - lock (vLock) - { - if (v > maxValue) return false; - maxV = maxValue; - return true; - } - } - public void SetVToMaxV() - { - lock (vLock) - { - v = maxV; - } - } - public void SetVToMaxV(double ratio) - { - lock (vLock) - { - v = (long)(maxV * ratio); - } - } - public bool Set0IfNotMax() - { - lock (vLock) - { - if (v < maxV) - { - v = 0; - return true; - } - } - return false; - } - public bool Set0IfMax() + public void SubPositiveV(T subPositiveV) { lock (vLock) { - if (v == maxV) - { - v = 0; - return true; - } + v = (subPositiveV < v) ? v - subPositiveV : T.Zero; } - return false; } #endregion @@ -682,7 +334,7 @@ public bool Set0IfMax() /// 试图加到满,如果无法加到maxValue则不加并返回-1 /// /// 返回实际改变量 - public long TryAddToMaxV(long addV) + public T TryAddToMaxVRChange(T addV) { lock (vLock) { @@ -692,293 +344,111 @@ public long TryAddToMaxV(long addV) v = maxV; return addV; } - return -1; + return -T.One; } } - #endregion - #region 与StartTime类的特殊条件的运算,运算会影响StartTime类的值 - /// - /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue - /// 如果无法加到maxValue则不加 - /// - /// 返回试图加到的值与最大值 - public (long, long, long) TryAddToMaxV(StartTime startTime, double speed = 1.0) - { - lock (vLock) - { - long addV = (long)(startTime.StopIfPassing(maxV - v) * speed); - if (addV < 0) return (v, maxV, startTime.Get()); - if (maxV - v < addV) return (v = maxV, maxV, startTime.Get()); - return (v + addV, maxV, startTime.Get()); - } - } - - #endregion - } - - /// - /// 一个保证在[0,maxValue]的可变double,支持可变的maxValue(请确保大于0) - /// - public class DoubleInTheVariableRange : InTheVariableRange - { - protected double v; - protected double maxV; - #region 构造与读取 - public DoubleInTheVariableRange(double value, double maxValue) : base() - { - if (maxValue < 0) - { - Debugger.Output("Warning:Try to set DoubleInTheVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; - } - v = value < maxValue ? value : maxValue; - this.maxV = maxValue; - } /// - /// 默认使Value=maxValue + /// ratio可以为负 /// - public DoubleInTheVariableRange(double maxValue) : base() - { - if (maxValue < 0) - { - Debugger.Output("Warning:Try to set DoubleInTheVariableRange.maxValue to " + maxValue.ToString() + "."); - maxValue = 0; - } - v = this.maxV = maxValue; - } - public DoubleInTheVariableRange() : base() - { - v = this.maxV = double.MaxValue; - } - - public override string ToString() - { - lock (vLock) - { - return "value:" + v.ToString() + " , maxValue:" + maxV.ToString(); - } - } - public double GetValue() { lock (vLock) return v; } - public static implicit operator double(DoubleInTheVariableRange adouble) => adouble.GetValue(); - public double GetMaxV() { lock (vLock) return maxV; } - public (double, double) GetValueAndMaxV() { lock (vLock) return (v, maxV); } - public bool IsMaxV() + /// 返回实际改变量 + public T VAddPartMaxVRChange(double ratio) { lock (vLock) { - return v == maxV; + T preV = v; + v += T.CreateChecked(ratio * maxV.ToDouble(null)); + if (v < T.Zero) v = T.Zero; + if (v > maxV) v = maxV; + return v - preV; } } #endregion - #region 普通设置MaxV与Value的值的方法 - /// - /// 若maxValue<=0则maxValue设为0并返回False - /// - public bool SetMaxV(double 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(double maxValue) - { - lock (vLock) - { - maxV = maxValue; - if (v > maxValue) v = maxValue; - } - } - - public double SetV(double value) + #region 与InVariableRange类的运算,运算会影响该对象的值 + public T AddRChange(InVariableRange a) where TA : IConvertible, IComparable, INumber { - if (value <= 0) - { - lock (vLock) - { - return v = 0; - } - } - lock (vLock) + return EnterOtherLock(a, () => { - return v = (value > maxV) ? maxV : value; - } + T previousV = v; + v += T.CreateChecked(a.GetValue()); + if (v > maxV) v = maxV; + a.SubPositiveVRChange(TA.CreateChecked(v - previousV)); + return v - previousV; + })!; } - /// - /// 应当保证该value>=0 - /// - public double SetPositiveV(double value) + public T SubRChange(InVariableRange a) where TA : IConvertible, IComparable, IComparable, INumber { - lock (vLock) + return EnterOtherLock(a, () => { - return v = (value > maxV) ? maxV : value; - } + T previousV = v; + v -= T.CreateChecked(a.GetValue()); + if (v < T.Zero) v = T.Zero; + a.SubPositiveVRChange(TA.CreateChecked(previousV - v)); + return v - previousV; + })!; } #endregion - #region 普通运算 - /// 返回实际改变量 - public double AddV(double addV) - { - lock (vLock) - { - double previousV = v; - v += addV; - if (v < 0) v = 0; - if (v > maxV) v = maxV; - return v - previousV; - } - } + #region 与StartTime类的特殊条件的运算,运算会影响StartTime类的值 /// - /// 应当保证增加值大于0 + /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue + /// 如果无法加到maxValue则不加 /// - /// 返回实际改变量 - public double AddPositiveV(double addPositiveV) - { - lock (vLock) - { - addPositiveV = Math.Min(addPositiveV, maxV - v); - v += addPositiveV; - } - return addPositiveV; - } - public void MulV(double mulV) + /// 返回试图加到的值与最大值 + public (T, T, long) TryAddToMaxV(StartTime startTime, double speed = 1.0) { - if (mulV <= 0) - { - lock (vLock) v = 0; - return; - } lock (vLock) { - if (v > maxV / mulV) v = maxV; //避免溢出 - else v *= mulV; + long addV = (long)(startTime.StopIfPassing((maxV - v).ToInt64(null)) * speed); + if (addV < 0) return (v, maxV, startTime.Get()); + if (maxV - v < T.CreateChecked(addV)) return (v = maxV, maxV, startTime.Get()); + return (v, maxV, startTime.Get()); } } /// - /// 应当保证乘数大于0 + /// 增加量为时间差*速度,并将startTime变为long.MaxValue /// - public void MulPositiveV(double mulPositiveV) - { - lock (vLock) - { - if (v > maxV / mulPositiveV) v = maxV; //避免溢出 - else v *= mulPositiveV; - } - } /// 返回实际改变量 - public double SubV(double subV) + public T AddRChange(StartTime startTime, double speed = 1.0) { lock (vLock) { - double previousV = v; - v -= subV; - if (v < 0) v = 0; + T previousV = v; + T addV = T.CreateChecked((Environment.TickCount64 - startTime.Stop()) * speed); + if (addV <= T.Zero) return T.Zero; + else v += addV; if (v > maxV) v = maxV; return v - previousV; } } - /// - /// 应当保证该减少值大于0 - /// - /// 返回实际改变量 - public double SubPositiveV(double subPositiveV) - { - lock (vLock) - { - subPositiveV = Math.Min(subPositiveV, v); - v -= subPositiveV; - } - return subPositiveV; - } - #endregion - #region 特殊条件的设置MaxV与Value的值的方法 /// - /// 如果当前值大于maxValue,则更新maxValue失败 + /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue + /// 如果无法加到maxValue则清零 /// - public bool TrySetMaxV(double maxValue) - { - lock (vLock) - { - if (v > maxValue) return false; - maxV = maxValue; - return true; - } - } - public void SetVToMaxV() - { - lock (vLock) - { - v = maxV; - } - } - public void SetVToMaxV(double ratio) - { - lock (vLock) - { - v = (double)(maxV * ratio); - } - } - public bool Set0IfNotMax() - { - lock (vLock) - { - if (v < maxV) - { - v = 0; - return true; - } - } - return false; - } - public bool Set0IfMax() + /// 返回是否清零 + public bool Set0IfNotAddToMaxV(StartTime startTime, double speed = 1.0) { lock (vLock) { - if (v == maxV) + if (v == maxV) return false; + T addV = T.CreateChecked(startTime.StopIfPassing((maxV - v).ToInt64(null)) * speed); + if (addV < T.Zero) { - v = 0; + v = T.Zero; return true; } - } - return false; - } - #endregion - - #region 特殊条件的运算 - /// - /// 试图加到满,如果无法加到maxValue则不加并返回-1 - /// - /// 返回实际改变量 - public double TryAddToMaxV(double addV) - { - lock (vLock) - { - if (maxV - v <= addV) + if (maxV - v < addV) { - addV = maxV - v; v = maxV; - return addV; + return false; } - return -1; + v = T.Zero; + return true; } } #endregion } + } \ No newline at end of file diff --git a/logic/Preparation/Utility/Value/SafeValue/LockedValue/PositiveV.cs b/logic/Preparation/Utility/Value/SafeValue/LockedValue/PositiveV.cs index 7b391e2b..c0bf13ab 100644 --- a/logic/Preparation/Utility/Value/SafeValue/LockedValue/PositiveV.cs +++ b/logic/Preparation/Utility/Value/SafeValue/LockedValue/PositiveV.cs @@ -6,16 +6,17 @@ namespace Preparation.Utility { /// /// 一个保证大于0的可变值 + /// 建议使用类似[0,int.MaxValue]的InVariableRange /// 其对应属性不应当有set访问器,避免不安全的=赋值 - /// - public class PositiveValue : LockedValue - where T : IConvertible, IComparable, IComparable, INumber + /// + public class PositiveValue : LockedValue, IIntAddable, IAddable + where T : IConvertible, IComparable, INumber { protected T v; #region 构造与读取 public PositiveValue(T value) : base() { - if (value.CompareTo(0) < 0) + if (value < T.Zero) { Debugger.Output("Warning:Try to set PositiveValue to " + value.ToString() + "."); value = T.Zero; @@ -52,7 +53,7 @@ public override string ToString() #region 普通设置与计算 public T SetRNow(T value) { - if (value.CompareTo(0) < 0) + if (value < T.Zero) { lock (vLock) { @@ -80,9 +81,28 @@ public void Add(T addV) lock (vLock) { v += addV; - if (v.CompareTo(0) < 0) v = T.Zero; + if (v < T.Zero) v = T.Zero; } } + + public void Add(int addV) + { + lock (vLock) + { + v += T.CreateChecked(addV); + if (v < T.Zero) v = T.Zero; + } + } + + public void Add(TA addV) where TA : IConvertible, INumber + { + lock (vLock) + { + v += T.CreateChecked(addV); + if (v < T.Zero) v = T.Zero; + } + } + /// 返回实际改变量 public T AddRChange(T addV) { @@ -90,7 +110,7 @@ public T AddRChange(T addV) { T previousV = v; v += addV; - if (v.CompareTo(0) < 0) v = T.Zero; + if (v < T.Zero) v = T.Zero; return v - previousV; } } @@ -106,7 +126,7 @@ public T AddPositiveVRChange(T addPositiveV) } return addPositiveV; } - public void MulV(T mulV) + public void Mul(T mulV) { if (mulV.CompareTo(0) <= 0) { @@ -118,9 +138,9 @@ public void MulV(T mulV) v *= mulV; } } - public void MulV(TA mulV) where TA : IConvertible, INumber + public void Mul(TA mulV) where TA : IConvertible, INumber { - if (mulV.CompareTo(0) < 0) + if (mulV < TA.Zero) { lock (vLock) v = T.Zero; return; @@ -169,25 +189,25 @@ public bool Set0IfNot0() #endregion #region 与LockedValue类的运算,运算会影响该对象的值 - public T AddRChange(IntInTheVariableRange a) + public T AddRChange(InVariableRange a) where TA : IConvertible, IComparable, INumber { return EnterOtherLock(a, () => { T previousV = v; v += T.CreateChecked(a.GetValue()); - a.SubPositiveV((v - previousV).ToInt32(null)); + a.SubPositiveVRChange(TA.CreateChecked(v - previousV)); return v - previousV; })!; } - public T SubV(IntInTheVariableRange a) + public T SubRChange(InVariableRange a) where TA : IConvertible, IComparable, INumber { return EnterOtherLock(a, () => { T previousV = v; v -= T.CreateChecked(a.GetValue()); - if (v.CompareTo(0) < 0) v = T.Zero; - a.SubPositiveV((previousV - v).ToInt32(null)); - return previousV - v; + if (v < T.Zero) v = T.Zero; + a.SubPositiveVRChange(TA.CreateChecked(previousV - v)); + return v - previousV; })!; } #endregion diff --git a/logic/Preparation/Utility/Value/ObjPool.cs b/logic/Preparation/Utility/Value/SafeValue/ObjPool.cs similarity index 100% rename from logic/Preparation/Utility/Value/ObjPool.cs rename to logic/Preparation/Utility/Value/SafeValue/ObjPool.cs diff --git a/logic/Preparation/Utility/Value/SafeValue/TimeBased.cs b/logic/Preparation/Utility/Value/SafeValue/TimeBased.cs index 544762ae..ea274d90 100644 --- a/logic/Preparation/Utility/Value/SafeValue/TimeBased.cs +++ b/logic/Preparation/Utility/Value/SafeValue/TimeBased.cs @@ -35,7 +35,7 @@ public long StopIfPassing(long passedTime) } } - public class LongInTheVariableRangeWithStartTime : LongInTheVariableRange + public class LongInTheVariableRangeWithStartTime : InVariableRange { public StartTime startTime = new(); public LongInTheVariableRangeWithStartTime(long value, long maxValue) : base(value, maxValue) { } @@ -43,7 +43,6 @@ public LongInTheVariableRangeWithStartTime(long value, long maxValue) : base(val /// 默认使Value=maxValue /// public LongInTheVariableRangeWithStartTime(long maxValue) : base(maxValue) { } - public LongInTheVariableRangeWithStartTime() : base() { } #region 读取 public (long, long) GetValueWithStartTime()