diff --git a/logic/GameClass/GameObj/GameObj.cs b/logic/GameClass/GameObj/GameObj.cs index 0e070e2..f63b2c2 100644 --- a/logic/GameClass/GameObj/GameObj.cs +++ b/logic/GameClass/GameObj/GameObj.cs @@ -32,17 +32,10 @@ namespace GameClass.GameObj public abstract ShapeType Shape { get; } - protected int isRemoved = 0; - public bool IsRemoved - { - get - { - return (Interlocked.CompareExchange(ref isRemoved, 0, 0) == 1); - } - } + public AtomicBool IsRemoved { get; } = new AtomicBool(false); public virtual bool TryToRemove() { - return Interlocked.Exchange(ref isRemoved, 1) == 0; + return IsRemoved.TrySet(true); } public int Radius { get; } diff --git a/logic/Gaming/AttackManager.cs b/logic/Gaming/AttackManager.cs index cbaba0c..930e3b1 100644 --- a/logic/Gaming/AttackManager.cs +++ b/logic/Gaming/AttackManager.cs @@ -67,7 +67,7 @@ namespace Gaming break; case GameObjType.Generator: if (bullet.CanBeBombed(GameObjType.Generator)) - ((Generator)objBeingShot).Repair(-bullet.AP.Get() * GameData.factorDamageGenerator, (Character)bullet.Parent!); + ((Generator)objBeingShot).Repair(-bullet.AP * GameData.factorDamageGenerator, (Character)bullet.Parent!); break; case GameObjType.Door: if (bullet.CanBeBombed(GameObjType.Door)) diff --git a/logic/Gaming/CharacterManager.cs b/logic/Gaming/CharacterManager.cs index 7fb9337..1db03b5 100644 --- a/logic/Gaming/CharacterManager.cs +++ b/logic/Gaming/CharacterManager.cs @@ -326,7 +326,7 @@ namespace Gaming { if (bullet.HasSpear) { - long subHp = student.SubHp(bullet.AP.Get()); + long subHp = student.SubHp(bullet.AP); #if DEBUG Debugger.Output(this, "is being shot! Now his hp is" + student.HP.ToString()); #endif @@ -340,14 +340,14 @@ namespace Gaming long subHp; if (bullet.HasSpear) { - subHp = student.SubHp(bullet.AP.Get() + GameData.ApSpearAdd); + subHp = student.SubHp(bullet.AP + GameData.ApSpearAdd); #if DEBUG Debugger.Output(this, "is being shot with Spear! Now his hp is" + student.HP.ToString()); #endif } else { - subHp = student.SubHp(bullet.AP.Get()); + subHp = student.SubHp(bullet.AP); #if DEBUG Debugger.Output(this, "is being shot! Now his hp is" + student.HP.ToString()); #endif diff --git a/logic/Preparation/Interface/IGameObj.cs b/logic/Preparation/Interface/IGameObj.cs index 74699e5..6e33027 100644 --- a/logic/Preparation/Interface/IGameObj.cs +++ b/logic/Preparation/Interface/IGameObj.cs @@ -8,6 +8,7 @@ namespace Preparation.Interface public long ID { get; } public XY Position { get; } // if Square, Pos equals the center public bool IsRigid { get; } + public AtomicBool IsRemoved { get; } public ShapeType Shape { get; } public bool CanMove { get; } public int Radius { get; } // if Square, Radius equals half length of one side diff --git a/logic/Preparation/Interface/IMoveable.cs b/logic/Preparation/Interface/IMoveable.cs index 6854d15..98dc5d2 100644 --- a/logic/Preparation/Interface/IMoveable.cs +++ b/logic/Preparation/Interface/IMoveable.cs @@ -10,7 +10,6 @@ namespace Preparation.Interface object ActionLock { get; } public int MoveSpeed { get; } public bool IsMoving { get; set; } - public bool IsRemoved { get; } public bool IsAvailableForMove { get; } public long StateNum { get; } public Semaphore ThreadNum { get; } diff --git a/logic/Preparation/Utility/LockedValue.cs b/logic/Preparation/Utility/LockedValue.cs index 540b93b..7d6cc2b 100644 --- a/logic/Preparation/Utility/LockedValue.cs +++ b/logic/Preparation/Utility/LockedValue.cs @@ -2,6 +2,7 @@ namespace Preparation.Utility { + //理论上结构体最好不可变,这里采用了可变结构。 public struct AtomicInt { private int v; @@ -11,6 +12,7 @@ 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 Add(int x) => Interlocked.Add(ref v, x); @@ -18,6 +20,32 @@ namespace Preparation.Utility public int Inc() => Interlocked.Increment(ref v); public int Dec() => Interlocked.Decrement(ref v); - public int CompareExchange(int b, int c) => Interlocked.CompareExchange(ref v, b, c); + public void CompareExchange(int b, int c) => Interlocked.CompareExchange(ref v, b, c); + /// 返回操作前的值 + public int CompareExReturnOri(int b, int c) => Interlocked.CompareExchange(ref v, b, c); + } + public struct AtomicBool + { + private int v;//v==0为false,v!=0(v==1或v==-1)为true + public AtomicBool(bool x) + { + v = x ? 1 : 0; + } + public override string ToString() => (Interlocked.CompareExchange(ref v, -1, -1) == 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 TrySet(bool value) + { + int ori = Interlocked.CompareExchange(ref v, value ? 1 : 0, value ? 1 : 0); + return value ? (ori == 0) : (ori != 0); + } + + public bool Invert() => Interlocked.Add(ref v, -1) != 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; } } diff --git a/logic/Preparation/Utility/XY.cs b/logic/Preparation/Utility/XY.cs index 4ae8702..ddf2761 100644 --- a/logic/Preparation/Utility/XY.cs +++ b/logic/Preparation/Utility/XY.cs @@ -2,7 +2,6 @@ namespace Preparation.Utility { - public struct XY { public int x;