diff --git a/logic/Client/MainWindow.xaml.cs b/logic/Client/MainWindow.xaml.cs index 1ac24a7..3874f30 100644 --- a/logic/Client/MainWindow.xaml.cs +++ b/logic/Client/MainWindow.xaml.cs @@ -844,7 +844,7 @@ namespace Client } foreach (var obj in listOfButcher) { - if (!isDataFixed[obj.PlayerId]) + if (obj.PlayerId < GameData.numOfStudent && !isDataFixed[obj.PlayerId]) { IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType)); int j = 0; diff --git a/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs index 072a993..4ddd23e 100644 --- a/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs +++ b/logic/GameClass/GameObj/Bullet/Bullet.Ghost.cs @@ -8,7 +8,7 @@ namespace GameClass.GameObj public CommonAttackOfGhost(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { - AP.Set(GameData.basicApOfGhost); + AP.SetReturnOri(GameData.basicApOfGhost); } public override double BulletBombRange => 0; public override double AttackDistance => GameData.basicAttackShortRange; @@ -45,7 +45,7 @@ namespace GameClass.GameObj public Strike(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { - AP.Set(GameData.basicApOfGhost * 16 / 15); + AP.SetReturnOri(GameData.basicApOfGhost * 16 / 15); } public override double BulletBombRange => 0; public override double AttackDistance => GameData.basicAttackShortRange * 20 / 22; @@ -83,7 +83,7 @@ namespace GameClass.GameObj public FlyingKnife(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { - AP.Set(GameData.basicApOfGhost * 4 / 5); + AP.SetReturnOri(GameData.basicApOfGhost * 4 / 5); } public override double BulletBombRange => 0; public override double AttackDistance => GameData.basicRemoteAttackRange * 13; @@ -123,7 +123,7 @@ namespace GameClass.GameObj { public BombBomb(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { - AP.Set((int)(GameData.basicApOfGhost * 6.0 / 5)); + AP.SetReturnOri((int)(GameData.basicApOfGhost * 6.0 / 5)); } public override double BulletBombRange => GameData.basicBulletBombRange; public override double AttackDistance => GameData.basicAttackShortRange; @@ -163,7 +163,7 @@ namespace GameClass.GameObj { public JumpyDumpty(Character player, XY pos, int radius = GameData.bulletRadius) : base(player, radius, pos) { - AP.Set((int)(GameData.basicApOfGhost * 0.6)); + AP.SetReturnOri((int)(GameData.basicApOfGhost * 0.6)); } public override double BulletBombRange => GameData.basicBulletBombRange / 2; public override double AttackDistance => GameData.basicAttackShortRange * 18 / 22; diff --git a/logic/GameClass/GameObj/Bullet/Bullet.cs b/logic/GameClass/GameObj/Bullet/Bullet.cs index c47f746..2895429 100644 --- a/logic/GameClass/GameObj/Bullet/Bullet.cs +++ b/logic/GameClass/GameObj/Bullet/Bullet.cs @@ -11,7 +11,8 @@ namespace GameClass.GameObj /// public abstract double BulletBombRange { get; } public abstract double AttackDistance { get; } - public AtomicInt AP { get; } + private AtomicInt ap = new(0); + public AtomicInt AP { get => ap; } public abstract int Speed { get; } public abstract bool IsRemoteAttack { get; } public abstract int CastTime { get; } @@ -43,8 +44,8 @@ namespace GameClass.GameObj public Bullet(Character player, int radius, XY Position) : base(Position, radius, GameObjType.Bullet) { - this.CanMove.Set(true); - this.MoveSpeed.Set(this.Speed); + this.CanMove.SetReturnOri(true); + this.MoveSpeed.SetReturnOri(this.Speed); this.hasSpear = player.TryUseSpear(); this.Parent = player; } diff --git a/logic/GameClass/GameObj/Character/Character.Skill.cs b/logic/GameClass/GameObj/Character/Character.Skill.cs index 69c487a..21f4a48 100644 --- a/logic/GameClass/GameObj/Character/Character.Skill.cs +++ b/logic/GameClass/GameObj/Character/Character.Skill.cs @@ -31,12 +31,12 @@ namespace GameClass.GameObj protected Character(XY initPos, int initRadius, CharacterType characterType) : base(initPos, initRadius, GameObjType.Character) { - this.CanMove.Set(true); + this.CanMove.SetReturnOri(true); this.score = 0; this.buffManager = new BuffManager(); this.occupation = OccupationFactory.FindIOccupation(characterType); this.HP = new(Occupation.MaxHp); - this.MoveSpeed.Set(this.orgMoveSpeed = Occupation.MoveSpeed); + this.MoveSpeed.SetReturnOri(this.orgMoveSpeed = Occupation.MoveSpeed); this.BulletOfPlayer = this.OriBulletOfPlayer = Occupation.InitBullet; this.concealment = Occupation.Concealment; this.alertnessRadius = Occupation.AlertnessRadius; diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs index 14e0595..1461b7a 100644 --- a/logic/GameClass/GameObj/Character/Character.cs +++ b/logic/GameClass/GameObj/Character/Character.cs @@ -459,7 +459,7 @@ namespace GameClass.GameObj { if (SetPlayerState(RunningStateType.RunningForcibly, playerStateType) == -1) return false; TryToRemove(); - CanMove.Set(false); + CanMove.SetReturnOri(false); position = GameData.PosWhoDie; } return true; @@ -604,7 +604,7 @@ namespace GameClass.GameObj } public void AddMoveSpeed(int buffTime, double add = 1.0) => buffManager.AddMoveSpeed(add, buffTime, newVal => - { MoveSpeed.Set(newVal < GameData.characterMaxSpeed ? newVal : GameData.characterMaxSpeed); }, + { MoveSpeed.SetReturnOri(newVal < GameData.characterMaxSpeed ? newVal : GameData.characterMaxSpeed); }, OrgMoveSpeed); public bool HasFasterSpeed => buffManager.HasFasterSpeed; diff --git a/logic/GameClass/GameObj/GameObj.cs b/logic/GameClass/GameObj/GameObj.cs index 1934d64..3933b7a 100644 --- a/logic/GameClass/GameObj/GameObj.cs +++ b/logic/GameClass/GameObj/GameObj.cs @@ -30,7 +30,8 @@ namespace GameClass.GameObj public abstract ShapeType Shape { get; } - public AtomicBool IsRemoved { get; } = new AtomicBool(false); + private AtomicBool isRemoved = new(false); + public AtomicBool IsRemoved { get => isRemoved; } public virtual bool TryToRemove() { return IsRemoved.TrySet(true); diff --git a/logic/GameClass/GameObj/Map/Chest.cs b/logic/GameClass/GameObj/Map/Chest.cs index ff589da..8e450e5 100644 --- a/logic/GameClass/GameObj/Map/Chest.cs +++ b/logic/GameClass/GameObj/Map/Chest.cs @@ -19,6 +19,7 @@ namespace GameClass.GameObj private readonly Gadget[] propInChest = new Gadget[GameData.maxNumOfPropInChest] { new NullProp(), new NullProp() }; public Gadget[] PropInChest => propInChest; - public LongProgressContinuously OpenProgress { get; } = new LongProgressContinuously(); + private LongProgressByTime openProgress = new LongProgressByTime(); + public LongProgressByTime OpenProgress { get => openProgress; } } } diff --git a/logic/GameClass/GameObj/Map/Door.cs b/logic/GameClass/GameObj/Map/Door.cs index 80b6645..ca6ba5f 100644 --- a/logic/GameClass/GameObj/Map/Door.cs +++ b/logic/GameClass/GameObj/Map/Door.cs @@ -46,7 +46,8 @@ namespace GameClass.GameObj } } - public AtomicInt LockDegree { get; } = new AtomicInt(0); + private AtomicInt lockDegree = new AtomicInt(0); + public AtomicInt LockDegree { get => lockDegree; } private long openStartTime = 0; public long OpenStartTime @@ -97,7 +98,7 @@ namespace GameClass.GameObj { if (!isOpen) return false; if (whoLockOrOpen != null) return false; - LockDegree.Set(0); + LockDegree.SetReturnOri(0); whoLockOrOpen = character; return true; } diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs index af3d9b1..75dea6b 100644 --- a/logic/GameClass/GameObj/Map/Map.cs +++ b/logic/GameClass/GameObj/Map/Map.cs @@ -26,7 +26,7 @@ namespace GameClass.GameObj { Random r = new Random(Environment.TickCount); EmergencyExit emergencyExit = (EmergencyExit)(GameObjDict[GameObjType.EmergencyExit][r.Next(0, GameObjDict[GameObjType.EmergencyExit].Count)]); - emergencyExit.CanOpen.Set(true); + emergencyExit.CanOpen.SetReturnOri(true); Preparation.Utility.Debugger.Output(emergencyExit, emergencyExit.Position.ToString()); } finally @@ -41,7 +41,7 @@ namespace GameClass.GameObj try { foreach (Doorway doorway in GameObjDict[GameObjType.Doorway]) - doorway.PowerSupply.Set(true); + doorway.PowerSupply.SetReturnOri(true); } finally { @@ -228,7 +228,6 @@ namespace GameClass.GameObj { if (person.CharacterType == CharacterType.TechOtaku) { - Debugger.Output(person, person.PlayerID.ToString()); foreach (Character character in gameObjDict[GameObjType.Character]) { if (((UseRobot)person.FindActiveSkill(ActiveSkillType.UseRobot)).NowPlayerID == character.PlayerID) diff --git a/logic/GameClass/GameObj/Moveable.cs b/logic/GameClass/GameObj/Moveable.cs index 1ff26f7..093f17a 100644 --- a/logic/GameClass/GameObj/Moveable.cs +++ b/logic/GameClass/GameObj/Moveable.cs @@ -94,14 +94,16 @@ namespace GameClass.GameObj } } - public AtomicBool CanMove { get; } + private AtomicBool canMove = new(false); + public AtomicBool CanMove { get => canMove; } public bool IsAvailableForMove => !IsMoving && CanMove && !IsRemoved; // 是否能接收移动指令 /// /// 移动速度 /// - public AtomicInt MoveSpeed { get; } + private AtomicInt moveSpeed = new(0); + public AtomicInt MoveSpeed { get => moveSpeed; } /// /// 原初移动速度 /// diff --git a/logic/GameClass/GameObj/Prop/Gadget.cs b/logic/GameClass/GameObj/Prop/Gadget.cs index 85565cc..74f545c 100644 --- a/logic/GameClass/GameObj/Prop/Gadget.cs +++ b/logic/GameClass/GameObj/Prop/Gadget.cs @@ -24,8 +24,8 @@ namespace GameClass.GameObj public Gadget(XY initPos, int radius = GameData.propRadius) : base(initPos, radius, GameObjType.Gadget) { - this.CanMove.Set(false); - this.MoveSpeed.Set(GameData.propMoveSpeed); + this.CanMove.SetReturnOri(false); + this.MoveSpeed.SetReturnOri(GameData.propMoveSpeed); } } public abstract class Tool : Gadget diff --git a/logic/GameClass/GameObj/Prop/Item.cs b/logic/GameClass/GameObj/Prop/Item.cs index 2b83cea..881e38f 100644 --- a/logic/GameClass/GameObj/Prop/Item.cs +++ b/logic/GameClass/GameObj/Prop/Item.cs @@ -17,8 +17,8 @@ namespace GameClass.GameObj public Item(XY initPos, int radius = GameData.propRadius) : base(initPos, radius, GameObjType.Item) { - this.CanMove.Set(false); - this.MoveSpeed.Set(0); + this.CanMove.SetReturnOri(false); + this.MoveSpeed.SetReturnOri(0); } } diff --git a/logic/GameEngine/MoveEngine.cs b/logic/GameEngine/MoveEngine.cs index a2236b7..d4c76f7 100644 --- a/logic/GameEngine/MoveEngine.cs +++ b/logic/GameEngine/MoveEngine.cs @@ -102,7 +102,7 @@ namespace GameEngine lock (obj.ActionLock) { if (!obj.IsAvailableForMove) { EndMove(obj); return; } - obj.IsMoving.Set(true); + obj.IsMoving.SetReturnOri(true); } new Thread @@ -139,7 +139,7 @@ namespace GameEngine if (isEnded) { - obj.IsMoving.Set(false); + obj.IsMoving.SetReturnOri(false); EndMove(obj); return; } @@ -184,7 +184,7 @@ namespace GameEngine } if (isEnded) { - obj.IsMoving.Set(false); + obj.IsMoving.SetReturnOri(false); EndMove(obj); return; } @@ -224,7 +224,7 @@ namespace GameEngine } } while (flag); } - obj.IsMoving.Set(false); // 结束移动 + obj.IsMoving.SetReturnOri(false); // 结束移动 EndMove(obj); } } diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs index 5fd1cc3..6d83ff1 100644 --- a/logic/Gaming/ActionManager.cs +++ b/logic/Gaming/ActionManager.cs @@ -450,12 +450,12 @@ namespace Gaming player.ReSetPos(windowToPlayer + windowForClimb.Position); } - player.MoveSpeed.Set(player.SpeedOfClimbingThroughWindows); + player.MoveSpeed.SetReturnOri(player.SpeedOfClimbingThroughWindows); moveEngine.MoveObj(player, (int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2), (-1 * windowToPlayer).Angle(), stateNum); Thread.Sleep((int)(GameData.numOfPosGridPerCell * 3 * 1000 / player.MoveSpeed / 2)); - player.MoveSpeed.Set(player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed)); + player.MoveSpeed.SetReturnOri(player.ReCalculateBuff(BuffType.AddSpeed, player.OrgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed)); lock (player.ActionLock) { diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index 2204cf6..70d6155 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -33,7 +33,7 @@ namespace Gaming Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); if (obj.CanMove && ((Bullet)obj).TypeOfBullet != BulletType.JumpyDumpty) BulletBomb((Bullet)obj, null); - obj.CanMove.Set(false); + obj.CanMove.SetReturnOri(false); } ); this.characterManager = characterManager; @@ -89,7 +89,7 @@ namespace Gaming { if (gameMap.Remove(bullet)) { - bullet.CanMove.Set(false); + bullet.CanMove.SetReturnOri(false); if (bullet.BulletBombRange > 0) { BombedBullet bombedBullet = new(bullet); diff --git a/logic/Gaming/CharacterManager.cs b/logic/Gaming/CharacterManager.cs index 6fdeedb..71c403f 100644 --- a/logic/Gaming/CharacterManager.cs +++ b/logic/Gaming/CharacterManager.cs @@ -57,41 +57,8 @@ namespace Gaming } gameMap.Add(newPlayer); - newPlayer.TeamID.Set(teamID); - newPlayer.PlayerID.Set(playerID); - /* #region 人物装弹 - new Thread - ( - () => - { - while (!gameMap.Timer.IsGaming) - Thread.Sleep(Math.Max(newPlayer.CD, GameData.checkInterval)); - long lastTime = Environment.TickCount64; - new FrameRateTaskExecutor( - loopCondition: () => gameMap.Timer.IsGaming && !newPlayer.IsRemoved, - loopToDo: () => - { - long nowTime = Environment.TickCount64; - if (newPlayer.BulletNum == newPlayer.MaxBulletNum) - lastTime = nowTime; - else if (nowTime - lastTime >= newPlayer.CD) - { - _ = newPlayer.TryAddBulletNum(); - lastTime = nowTime; - } - }, - timeInterval: GameData.checkInterval, - finallyReturn: () => 0 - ) - { - AllowTimeExceed = true, - } - .Start(); - } - ) - { IsBackground = true }.Start(); - #endregion - */ + newPlayer.TeamID.SetReturnOri(teamID); + newPlayer.PlayerID.SetReturnOri(playerID); #region BGM,牵制得分更新 new Thread ( @@ -311,7 +278,7 @@ namespace Gaming if (student.CharacterType == CharacterType.StraightAStudent) { - ((WriteAnswers)student.FindActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation.Set(0); + ((WriteAnswers)student.FindActiveSkill(ActiveSkillType.WriteAnswers)).DegreeOfMeditation.SetReturnOri(0); } student.SetDegreeOfTreatment0(); diff --git a/logic/Gaming/Game.cs b/logic/Gaming/Game.cs index 96db675..02d783c 100644 --- a/logic/Gaming/Game.cs +++ b/logic/Gaming/Game.cs @@ -84,7 +84,7 @@ namespace Gaming else { #if DEBUG - Console.WriteLine($"PlayerID:{playerID} player does not exists!"); + Console.WriteLine($"playerID:{playerID} player does not exists!"); #endif return false; @@ -326,7 +326,7 @@ namespace Gaming { foreach (Character player in gameMap.GameObjDict[GameObjType.Character]) { - player.CanMove.Set(false); + player.CanMove.SetReturnOri(false); } } gameMap.GameObjDict[keyValuePair.Key].Clear(); diff --git a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs index 74ce47a..88398ae 100644 --- a/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs @@ -196,7 +196,7 @@ namespace Gaming } if (homingMissile != null) { - homingMissile.CanMove.Set(true); + homingMissile.CanMove.SetReturnOri(true); attackManager.moveEngine.MoveObj(homingMissile, GameData.checkIntervalWhenSparksNSplash - 1, (whoAttacked.Position - homingMissile.Position).Angle(), ++homingMissile.StateNum); } }, @@ -227,7 +227,7 @@ namespace Gaming if (generator.Repair(((WriteAnswers)activeSkill).DegreeOfMeditation, player)) gameMap.AddNumOfRepairedGenerators(); Debugger.Output(player, "uses WriteAnswers in" + generator.ToString() + "with " + (((WriteAnswers)activeSkill).DegreeOfMeditation).ToString()); - ((WriteAnswers)activeSkill).DegreeOfMeditation.Set(0); + ((WriteAnswers)activeSkill).DegreeOfMeditation.SetReturnOri(0); } }, () => diff --git a/logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs b/logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs index b22254e..3cc89c7 100644 --- a/logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs +++ b/logic/Gaming/SkillManager/SkillManager.PassiveSkill.cs @@ -26,7 +26,7 @@ namespace Gaming // 被动技能开局时就释放,持续到游戏结束 () => { if (player.Commandable() && player.PlayerState != PlayerStateType.Fixing) activeSkill.DegreeOfMeditation.Add(learningDegree * GameData.frameDuration); - else activeSkill.DegreeOfMeditation.Set(0); + else activeSkill.DegreeOfMeditation.SetReturnOri(0); //Debugger.Output(player, "with " + (((WriteAnswers)activeSkill).DegreeOfMeditation).ToString()); }, timeInterval: GameData.frameDuration, diff --git a/logic/Preparation/Interface/ISkill.cs b/logic/Preparation/Interface/ISkill.cs index bc3f2d6..65b6270 100644 --- a/logic/Preparation/Interface/ISkill.cs +++ b/logic/Preparation/Interface/ISkill.cs @@ -174,7 +174,8 @@ namespace Preparation.Interface public override int SkillCD => GameData.commonSkillCD; public override int DurationTime => 0; - public AtomicInt DegreeOfMeditation { get; } = new(0); + private AtomicInt degreeOfMeditation = new(0); + public AtomicInt DegreeOfMeditation { get => degreeOfMeditation; } } public class SummonGolem : ActiveSkill diff --git a/logic/Preparation/Utility/SafeValue.cs b/logic/Preparation/Utility/SafeValue.cs index 45a4b66..dcbf502 100644 --- a/logic/Preparation/Utility/SafeValue.cs +++ b/logic/Preparation/Utility/SafeValue.cs @@ -5,7 +5,7 @@ namespace Preparation.Utility { //理论上结构体最好不可变,这里采用了可变结构。 //其对应属性不应当有set访问器,避免不安全的=赋值 - public struct AtomicInt + public class AtomicInt { private int v; public AtomicInt(int x) @@ -15,18 +15,17 @@ namespace Preparation.Utility 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 Set(int value) => Interlocked.Exchange(ref v, value); - + /// 返回操作前的值 + 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 void CompareExchange(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); /// 返回操作前的值 public int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); } - public struct AtomicLong + + public class AtomicLong { private long v; public AtomicLong(long x) @@ -36,18 +35,17 @@ namespace Preparation.Utility 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 Set(long value) => Interlocked.Exchange(ref v, value); - + /// 返回操作前的值 + 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 void CompareExchange(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); /// 返回操作前的值 public long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo); } - public struct AtomicBool + + public class AtomicBool { private int v;//v==0为false,v==1为true public AtomicBool(bool x) @@ -57,36 +55,34 @@ namespace Preparation.Utility 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 Set(bool value) => (Interlocked.Exchange(ref v, value ? 1 : 0) != 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后完成多少进度的进度条(long)。 /// 只允许Start时修改needTime(请确保大于0); /// 支持TrySet0使未完成的进度条终止清零;支持Set0使进度条强制终止清零; - /// 不支持暂停 + /// 通过原子操作实现。 /// - public struct LongProgressContinuously + public class LongProgressByTime { private long endT = long.MaxValue; private long needT; - public LongProgressContinuously(long needTime) + public LongProgressByTime(long needTime) { - if (needTime <= 0) Debugger.Output("Bug:LongProgressContinuously.needTime (" + needTime.ToString() + ") is less than 0."); + if (needTime <= 0) Debugger.Output("Bug:LongProgressByTime.needTime (" + needTime.ToString() + ") is less than 0."); this.needT = needTime; } - public LongProgressContinuously() + public LongProgressByTime() { this.needT = long.MaxValue; } @@ -118,7 +114,7 @@ namespace Preparation.Utility /// /// <0则表明未开始 /// - public static implicit operator long(LongProgressContinuously pLong) => pLong.GetProgress(); + public static implicit operator long(LongProgressByTime pLong) => pLong.GetProgress(); /// /// GetProgressDouble<0则表明未开始 @@ -134,13 +130,13 @@ namespace Preparation.Utility { if (needTime <= 0) { - Debugger.Output("Warning:Start LongProgressContinuously with the needTime (" + needTime.ToString() + ") which is less than 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 LongProgressContinuously is " + needTime.ToString() + ",which is too small."); - Interlocked.Exchange(ref this.needT, needTime); + 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() @@ -149,7 +145,13 @@ namespace Preparation.Utility 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)) @@ -162,10 +164,34 @@ namespace Preparation.Utility //增加其他新的写操作可能导致不安全 } + /* + /// + /// 记录(不是根据时间)完成多少进度的进度条(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 struct IntWithVariableRange + public class IntWithVariableRange { private int v; private int maxV; @@ -310,7 +336,7 @@ namespace Preparation.Utility /// /// 一个保证在[0,maxValue]的可变long,支持可变的maxValue(请确保大于0) /// - public struct LongWithVariableRange + public class LongWithVariableRange { private long v; private long maxV; @@ -319,7 +345,7 @@ namespace Preparation.Utility { if (maxValue < 0) { - Debugger.Output("Warning:Try to set LongWithVariableRange.maxValue to " + maxValue.ToString() + "."); + Debugger.Output("Warning:Try to set SafaValues.LongWithVariableRange.maxValue to " + maxValue.ToString() + "."); maxValue = 0; } v = value < maxValue ? value : maxValue; @@ -332,7 +358,7 @@ namespace Preparation.Utility { if (maxValue < 0) { - Debugger.Output("Warning:Try to set LongWithVariableRange.maxValue to " + maxValue.ToString() + "."); + Debugger.Output("Warning:Try to set SafaValues.LongWithVariableRange.maxValue to " + maxValue.ToString() + "."); maxValue = 0; } v = this.maxV = maxValue; @@ -455,7 +481,7 @@ namespace Preparation.Utility /// /// 一个保证在[0,maxNum],每CDms自动更新的可变int,支持可变的CD、maxNum(请确保大于0) /// - public struct IntNumUpdateByCD + public class IntNumUpdateByCD { private int num; private int maxNum; @@ -623,9 +649,9 @@ namespace Preparation.Utility { lock (numLock) { - if (cd <= 0) Debugger.Output("Bug:Set IntNumUpdateByCD.cd to " + cd.ToString() + "."); + if (cd <= 0) Debugger.Output("Bug:SetReturnOri IntNumUpdateByCD.cd to " + cd.ToString() + "."); this.cd = cd; } } } -} +} \ No newline at end of file