From 70604b56f80100e43e22bbd61f29120725774fea Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sat, 4 Nov 2023 23:34:36 +0800
Subject: [PATCH 1/3] feat: :sparkles: Add the progress
TimeBasedProgressAtVariableSpeed
---
.../GameClass/GameObj/Character/Character.cs | 2 +-
logic/GameClass/GameObj/Map/Doorway.cs | 58 +---
logic/Gaming/ActionManager.cs | 7 +-
logic/Preparation/Interface/IDoorway.cs | 5 +-
.../Utility/SafeValue/InTheRange.cs | 109 ++++---
.../Utility/SafeValue/TimeBased.cs | 270 +++++++++++++-----
logic/Server/CopyInfo.cs | 3 +-
7 files changed, 254 insertions(+), 200 deletions(-)
diff --git a/logic/GameClass/GameObj/Character/Character.cs b/logic/GameClass/GameObj/Character/Character.cs
index 2b6a9e18..6c07855b 100644
--- a/logic/GameClass/GameObj/Character/Character.cs
+++ b/logic/GameClass/GameObj/Character/Character.cs
@@ -327,7 +327,7 @@ public long SetPlayerState(RunningStateType runningState, PlayerStateType value
case PlayerStateType.OpeningTheDoorway:
if (value == PlayerStateType.Rescued) return -1;
Doorway doorway = (Doorway)lastObj!;
- doorway.StopOpenning();
+ doorway.ProgressOfDoorway.TryStop();
return ChangePlayerState(runningState, value, gameObj);
case PlayerStateType.OpeningTheDoor:
if (value == PlayerStateType.Rescued) return -1;
diff --git a/logic/GameClass/GameObj/Map/Doorway.cs b/logic/GameClass/GameObj/Map/Doorway.cs
index 82ac6bea..a0835627 100644
--- a/logic/GameClass/GameObj/Map/Doorway.cs
+++ b/logic/GameClass/GameObj/Map/Doorway.cs
@@ -17,70 +17,18 @@ public Doorway(XY initPos) :
public override ShapeType Shape => ShapeType.Square;
public override bool IgnoreCollideExecutor(IGameObj targetObj)
{
- if (!IsOpen()) return false;
+ if (!ProgressOfDoorway.IsFinished()) return false;
if (targetObj.Type != GameObjType.Character)
return true; // 非玩家不碰撞
return false;
}
public AtomicBool PowerSupply { get; } = new(false);
-
- private long openStartTime = 0;
- public long OpenStartTime
- {
- get
- {
- lock (gameObjLock)
- return openStartTime;
- }
- }
+ public TimeBasedProgressAtVariableSpeed ProgressOfDoorway { get; } = new(GameData.degreeOfOpenedDoorway, 1);
public bool TryToOpen()
{
if (!PowerSupply) return false;
- lock (gameObjLock)
- {
- if (openStartTime > 0) return false;
- openStartTime = Environment.TickCount64;
- return true;
- }
+ return ProgressOfDoorway.Start();
}
-
- public bool StopOpenning()
- {
- lock (gameObjLock)
- {
- if (Environment.TickCount64 - openStartTime + openDegree >= GameData.degreeOfOpenedDoorway)
- {
- openDegree = GameData.degreeOfOpenedDoorway;
- return true;
- }
- else
- {
- openDegree = (int)(Environment.TickCount64 - openStartTime) + openDegree;
- openStartTime = 0;
- return false;
- }
- }
- }
-
- public void FinishOpenning()
- {
- lock (gameObjLock)
- {
- openDegree = GameData.degreeOfOpenedDoorway;
- }
- }
-
- private int openDegree = 0;
- public int OpenDegree
- {
- get
- {
- lock (gameObjLock)
- return openDegree;
- }
- }
-
- public bool IsOpen() => (OpenDegree == GameData.degreeOfOpenedDoorway);
}
}
diff --git a/logic/Gaming/ActionManager.cs b/logic/Gaming/ActionManager.cs
index bfb78d27..645f7ea9 100644
--- a/logic/Gaming/ActionManager.cs
+++ b/logic/Gaming/ActionManager.cs
@@ -2,6 +2,7 @@
using System.Threading;
using GameClass.GameObj;
using GameEngine;
+using Preparation.Interface;
using Preparation.Utility;
using Timothy.FrameRateTask;
@@ -148,11 +149,11 @@ public bool OpenDoorway(Student player)
player.ThreadNum.Release();
return;
}
- Thread.Sleep(GameData.degreeOfOpenedDoorway - doorwayToOpen.OpenDegree);
+ Thread.Sleep(GameData.degreeOfOpenedDoorway - (int)doorwayToOpen.ProgressOfDoorway.GetProgressNow());
if (player.ResetPlayerState(stateNum))
{
- doorwayToOpen.FinishOpenning();
+ doorwayToOpen.ProgressOfDoorway.Finish();
player.ThreadNum.Release();
}
}
@@ -168,7 +169,7 @@ public bool Escape(Student player)
return false;
Doorway? doorwayForEscape = (Doorway?)gameMap.OneForInteract(player.Position, GameObjType.Doorway);
- if (doorwayForEscape != null && doorwayForEscape.IsOpen())
+ if (doorwayForEscape != null && doorwayForEscape.ProgressOfDoorway.IsProgressing())
{
if (!player.TryToRemoveFromGame(PlayerStateType.Escaped)) return false;
player.AddScore(GameData.StudentScoreEscape);
diff --git a/logic/Preparation/Interface/IDoorway.cs b/logic/Preparation/Interface/IDoorway.cs
index b48be758..942f1032 100644
--- a/logic/Preparation/Interface/IDoorway.cs
+++ b/logic/Preparation/Interface/IDoorway.cs
@@ -4,9 +4,6 @@ namespace Preparation.Interface
{
public interface IDoorway : IGameObj
{
- public long OpenStartTime { get; }
- public int OpenDegree { get; }
- public bool StopOpenning();
- public bool TryToOpen();
+ public TimeBasedProgressAtVariableSpeed ProgressOfDoorway { get; }
}
}
\ No newline at end of file
diff --git a/logic/Preparation/Utility/SafeValue/InTheRange.cs b/logic/Preparation/Utility/SafeValue/InTheRange.cs
index 3c8a9cae..f08f2e04 100644
--- a/logic/Preparation/Utility/SafeValue/InTheRange.cs
+++ b/logic/Preparation/Utility/SafeValue/InTheRange.cs
@@ -24,8 +24,8 @@ public InTheVariableRange()
///
public class IntInTheVariableRange : InTheVariableRange
{
- private int v;
- private int maxV;
+ protected int v;
+ protected int maxV;
#region 构造与读取
public IntInTheVariableRange(int value, int maxValue) : base()
{
@@ -157,6 +157,13 @@ public bool TrySetMaxV(int maxValue)
return true;
}
}
+ public void SetVToMaxV()
+ {
+ lock (vLock)
+ {
+ v = maxV;
+ }
+ }
public bool Set0IfNotMaxor0()
{
lock (vLock)
@@ -397,6 +404,32 @@ public int AddV(StartTime startTime, double speed = 1.0)
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
}
@@ -405,8 +438,8 @@ public int AddV(StartTime startTime, double speed = 1.0)
///
public class LongInTheVariableRange : InTheVariableRange
{
- private long v;
- private long maxV;
+ protected long v;
+ protected long maxV;
#region 构造与读取
public LongInTheVariableRange(long value, long maxValue) : base()
{
@@ -455,23 +488,6 @@ public bool IsMaxV()
}
#endregion
- #region 内嵌读取(在锁的情况下读取内容同时读取其他更基本的外部数据)
- public (long, long) GetValue(StartTime startTime)
- {
- lock (vLock)
- {
- return (v, startTime.Get());
- }
- }
- public (long, long, long) GetValueAndMaxV(StartTime startTime)
- {
- lock (vLock)
- {
- return (v, maxV, startTime.Get());
- }
- }
- #endregion
-
#region 普通设置MaxV与Value的值的方法
///
/// 若maxValue<=0则maxValue设为0并返回False
@@ -645,6 +661,13 @@ public bool TrySetMaxV(long maxValue)
return true;
}
}
+ public void SetVToMaxV()
+ {
+ lock (vLock)
+ {
+ v = maxV;
+ }
+ }
public bool Set0IfNotMax()
{
@@ -709,22 +732,6 @@ public long TryAddToMaxV(long addV)
}
}
- ///
- /// 增加量为时间差*速度,并将startTime变为long.MaxValue
- ///
- /// 返回实际改变量
- public long AddV(StartTime startTime, double speed = 1.0)
- {
- lock (vLock)
- {
- long previousV = v;
- long addV = (Environment.TickCount64 - startTime.Stop());
- if (addV < 0) v += (long)(addV * speed);
- else return 0;
- if (v > maxV) v = maxV;
- return v - previousV;
- }
- }
#endregion
}
@@ -733,8 +740,8 @@ public long AddV(StartTime startTime, double speed = 1.0)
///
public class DoubleInTheVariableRange : InTheVariableRange
{
- private double v;
- private double maxV;
+ protected double v;
+ protected double maxV;
#region 构造与读取
public DoubleInTheVariableRange(double value, double maxValue) : base()
{
@@ -783,23 +790,6 @@ public bool IsMaxV()
}
#endregion
- #region 内嵌读取(在锁的情况下读取内容同时读取其他更基本的外部数据)
- public (double, long) GetValue(StartTime startTime)
- {
- lock (vLock)
- {
- return (v, startTime.Get());
- }
- }
- public (double, double, long) GetValueAndMaxValue(StartTime startTime)
- {
- lock (vLock)
- {
- return (v, maxV, startTime.Get());
- }
- }
- #endregion
-
#region 普通设置MaxV与Value的值的方法
///
/// 若maxValue<=0则maxValue设为0并返回False
@@ -949,6 +939,13 @@ public bool TrySetMaxV(double maxValue)
return true;
}
}
+ public void SetVToMaxV()
+ {
+ lock (vLock)
+ {
+ v = maxV;
+ }
+ }
public bool Set0IfNotMax()
{
diff --git a/logic/Preparation/Utility/SafeValue/TimeBased.cs b/logic/Preparation/Utility/SafeValue/TimeBased.cs
index 6ed57435..402595a1 100644
--- a/logic/Preparation/Utility/SafeValue/TimeBased.cs
+++ b/logic/Preparation/Utility/SafeValue/TimeBased.cs
@@ -35,6 +35,197 @@ public long StopIfPassing(long passedTime)
}
}
+ public class LongInTheVariableRangeWithStartTime : LongInTheVariableRange
+ {
+ public StartTime startTime = new();
+ public LongInTheVariableRangeWithStartTime(long value, long maxValue) : base(value, maxValue) { }
+ ///
+ /// 默认使Value=maxValue
+ ///
+ public LongInTheVariableRangeWithStartTime(long maxValue) : base(maxValue) { }
+ public LongInTheVariableRangeWithStartTime() : base() { }
+
+ #region 读取
+ public (long, long) GetValueWithStartTime()
+ {
+ lock (vLock)
+ {
+ return (v, startTime.Get());
+ }
+ }
+ public (long, long, long) GetValueAndMaxVWithStartTime()
+ {
+ lock (vLock)
+ {
+ return (v, maxV, startTime.Get());
+ }
+ }
+ #endregion
+
+ ///
+ /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue
+ /// 如果无法加到maxValue则不加
+ ///
+ /// 返回试图加到的值与最大值
+ public (long, long, long) AddStartTimeToMaxV(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());
+ }
+ }
+
+ ///
+ /// 增加量为时间差*速度,并将startTime变为long.MaxValue
+ ///
+ /// 返回实际改变量
+ public long AddStartTime(double speed = 1.0)
+ {
+ lock (vLock)
+ {
+ long previousV = v;
+ long addV = (Environment.TickCount64 - startTime.Stop());
+ if (addV < 0) v += (long)(addV * speed);
+ else return 0;
+ if (v > maxV) v = maxV;
+ return v - previousV;
+ }
+ }
+
+ ///
+ /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上
+ /// 如果无法加到maxValue则清零
+ /// 无论如何startTime变为long.MaxValue
+ ///
+ /// 返回是否清零
+ public bool Set0IfNotAddStartTimeToMaxV(double speed = 1.0)
+ {
+ lock (vLock)
+ {
+ if (v == maxV) return false;
+ long addV = (long)(startTime.Stop() * speed);
+ if (addV < 0)
+ {
+ v = 0;
+ return true;
+ }
+ if (maxV - v < addV)
+ {
+ v = maxV;
+ return false;
+ }
+ v = 0;
+ return false;
+ }
+ }
+
+ public void SetAndStop(long value = 0)
+ {
+ lock (vLock)
+ {
+ this.v = value;
+ startTime.Stop();
+ }
+ }
+ }
+
+ public class TimeBasedProgressAtVariableSpeed
+ {
+ private LongInTheVariableRangeWithStartTime progress;
+ public AtomicDouble speed;
+
+ #region 构造
+ public TimeBasedProgressAtVariableSpeed(long needProgress, double speed = 1.0)
+ {
+ progress = new LongInTheVariableRangeWithStartTime(0, needProgress);
+ if (needProgress <= 0) Debugger.Output("Bug:TimeBasedProgressAtVariableSpeed.needProgress (" + needProgress.ToString() + ") is less than 0.");
+ this.speed = new(speed);
+ }
+ public TimeBasedProgressAtVariableSpeed()
+ {
+ progress = new LongInTheVariableRangeWithStartTime(0, 0);
+ this.speed = new(1.0);
+ }
+ #endregion
+
+ #region 读取
+ public override string ToString()
+ {
+ long progressStored, lastStartTime;
+ (progressStored, lastStartTime) = progress.GetValueWithStartTime();
+ return "ProgressStored: " + progressStored.ToString()
+ + " ; LastStartTime: " + lastStartTime.ToString() + "ms"
+ + " ; Speed: " + speed.ToString();
+ }
+ public long GetProgressNow() => progress.AddStartTimeToMaxV((double)speed).Item1;
+ public (long, long, long) GetProgressNowAndNeedTimeAndLastStartTime() => progress.AddStartTimeToMaxV((double)speed);
+ public long GetProgressStored() => progress.GetValue();
+ public (long, long) GetProgressStoredAndNeedTime() => progress.GetValueAndMaxV();
+ public (long, long, long) GetProgressStoredAndNeedTimeAndLastStartTime() => progress.GetValueAndMaxVWithStartTime();
+
+ public bool IsFinished()
+ {
+ long progressNow, needTime;
+ (progressNow, needTime, _) = progress.AddStartTimeToMaxV((double)speed);
+ return progressNow == needTime;
+ }
+ public bool IsProgressing()
+ {
+ long progressNow, needTime, startT;
+ (progressNow, needTime, startT) = progress.AddStartTimeToMaxV((double)speed);
+ return (startT != long.MaxValue && progressNow != needTime);
+ }
+ #endregion
+
+ public bool Start(long needTime)
+ {
+ if (needTime <= 2)
+ {
+ Debugger.Output("Warning:Start TimeBasedProgressAtVariableSpeed with the needProgress (" + needTime.ToString() + ") which is less than 0.");
+ return false;
+ }
+ if (progress.startTime.Start() != long.MaxValue) return false;
+ progress.SetMaxV(needTime);
+ return true;
+ }
+ public bool Start()
+ {
+ return progress.startTime.Start() == long.MaxValue;
+ }
+ ///
+ /// 使进度条强制终止清零
+ ///
+ public void Set0()
+ {
+ progress.SetAndStop();
+ }
+ ///
+ /// 如果进度条加上时间差不能为满,使进度条强制终止清零
+ ///
+ public void TryStop()
+ {
+ progress.Set0IfNotAddStartTimeToMaxV(speed);
+ }
+ ///
+ /// 使进度条暂停
+ ///
+ public bool Pause()
+ {
+ return progress.AddStartTime((double)speed) != 0;
+ }
+ ///
+ /// 使进度条进度为满
+ ///
+ public void Finish()
+ {
+ progress.SetVToMaxV();
+ progress.startTime.Stop();
+ }
+ }
+
///
/// 根据时间推算Start后完成多少进度的进度条(long)。
/// 只允许Start(清零状态的进度条才可以Start)时修改needTime(请确保大于0);
@@ -158,85 +349,6 @@ public bool InterruptToSet0()
//增加其他新的写操作可能导致不安全
}
- public class TimeBasedProgressAtVariableSpeed
- {
- public LongInTheVariableRange progress;
- public StartTime startTime = new();
- public AtomicDouble speed;
-
- #region 构造
- public TimeBasedProgressAtVariableSpeed(long needProgress, double speed)
- {
- if (needProgress <= 0) Debugger.Output("Bug:TimeBasedProgressAtVariableSpeed.needProgress (" + needProgress.ToString() + ") is less than 0.");
- this.progress = new(0, needProgress);
- this.speed = new(speed);
- }
- public TimeBasedProgressAtVariableSpeed()
- {
- this.progress = new(0, 0);
- this.speed = new(1.0);
- }
- #endregion
-
- #region 读取
- public override string ToString()
- {
- return "ProgressStored: " + progress.ToString()
- + " ; LastStartTime: " + startTime.ToString() + "ms"
- + " ; Speed: " + speed.ToString();
- }
- public long GetProgressNow() => progress.TryAddToMaxV(startTime, (double)speed).Item1;
- public (long, long, long) GetProgressNowAndNeedTimeAndLastStartTime() => progress.TryAddToMaxV(startTime, (double)speed);
- public long GetProgressStored() => progress.GetValue();
- public (long, long) GetProgressStoredAndNeedTime() => progress.GetValueAndMaxV();
- public (long, long, long) GetProgressStoredAndNeedTimeAndLastStartTime() => progress.GetValueAndMaxV(startTime);
-
- public bool IsFinished()
- {
- long progressNow, needTime;
- (progressNow, needTime, _) = progress.TryAddToMaxV(startTime);
- return progressNow == needTime;
- }
- public bool IsProgressing()
- {
- long progressNow, needTime, startT;
- (progressNow, needTime, startT) = progress.TryAddToMaxV(startTime);
- return (startT != long.MaxValue && progressNow != needTime);
- }
- #endregion
-
- public bool Start(long needTime)
- {
- if (needTime <= 2)
- {
- Debugger.Output("Warning:Start TimeBasedProgressAtVariableSpeed with the needProgress (" + needTime.ToString() + ") which is less than 0.");
- return false;
- }
- if (startTime.Start() != long.MaxValue) return false;
- progress.SetMaxV(needTime);
- return true;
- }
- public bool Start()
- {
- return startTime.Start() == long.MaxValue;
- }
- ///
- /// 使进度条强制终止清零
- ///
- public void Set0()
- {
- startTime.Stop();
- progress.SetPositiveV(0);
- }
- ///
- /// 使进度条暂停
- ///
- public bool Pause()
- {
- return progress.AddV(startTime, (double)speed) != 0;
- }
- }
-
///
/// 冷却时间为可变的CDms的bool,不支持查看当前进度,初始为True
///
diff --git a/logic/Server/CopyInfo.cs b/logic/Server/CopyInfo.cs
index 57863dc7..a18d58a2 100644
--- a/logic/Server/CopyInfo.cs
+++ b/logic/Server/CopyInfo.cs
@@ -232,8 +232,7 @@ private static MessageOfObj Gate(Doorway doorway, long time)
Y = doorway.Position.y
}
};
- int progress = ((doorway.OpenStartTime > 0) ? ((int)(time - doorway.OpenStartTime)) : 0) + doorway.OpenDegree;
- msg.GateMessage.Progress = (progress > GameData.degreeOfOpenedDoorway) ? GameData.degreeOfOpenedDoorway : progress;
+ msg.GateMessage.Progress = (int)doorway.ProgressOfDoorway.GetProgressNow();
return msg;
}
private static MessageOfObj HiddenGate(EmergencyExit Exit)
From 801d1aea30db9d3df03f20f8d95249d9a4f37fdc Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sun, 5 Nov 2023 00:41:51 +0800
Subject: [PATCH 2/3] feat(SafeValue): :sparkles: Add the AtomicIntOnlyAddScore
---
logic/GameClass/GameObj/Map/Map.cs | 2 +-
logic/Preparation/Utility/SafeValue/Atomic.cs | 173 ++++++++++++++++--
2 files changed, 158 insertions(+), 17 deletions(-)
diff --git a/logic/GameClass/GameObj/Map/Map.cs b/logic/GameClass/GameObj/Map/Map.cs
index 75dea6b8..dd7e6bbb 100644
--- a/logic/GameClass/GameObj/Map/Map.cs
+++ b/logic/GameClass/GameObj/Map/Map.cs
@@ -24,7 +24,7 @@ public void AddNumOfRepairedGenerators()
GameObjLockDict[GameObjType.EmergencyExit].EnterReadLock();
try
{
- Random r = new Random(Environment.TickCount);
+ Random r = new(Environment.TickCount);
EmergencyExit emergencyExit = (EmergencyExit)(GameObjDict[GameObjType.EmergencyExit][r.Next(0, GameObjDict[GameObjType.EmergencyExit].Count)]);
emergencyExit.CanOpen.SetReturnOri(true);
Preparation.Utility.Debugger.Output(emergencyExit, emergencyExit.Position.ToString());
diff --git a/logic/Preparation/Utility/SafeValue/Atomic.cs b/logic/Preparation/Utility/SafeValue/Atomic.cs
index da6ebaa7..0eee2f5f 100644
--- a/logic/Preparation/Utility/SafeValue/Atomic.cs
+++ b/logic/Preparation/Utility/SafeValue/Atomic.cs
@@ -1,4 +1,5 @@
-using System;
+using Google.Protobuf.WellKnownTypes;
+using System;
using System.Threading;
namespace Preparation.Utility
@@ -10,7 +11,7 @@ public abstract class Atomic
public class AtomicInt : Atomic
{
- private int v;
+ protected int v;
public AtomicInt(int x)
{
v = x;
@@ -19,33 +20,173 @@ public AtomicInt(int x)
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 virtual int SetReturnOri(int value) => Interlocked.Exchange(ref v, value);
+ public virtual int Add(int x) => Interlocked.Add(ref v, x);
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public virtual int AddPositive(int x) => Interlocked.Add(ref v, x);
+ public virtual int Sub(int x) => Interlocked.Add(ref v, -x);
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public virtual int SubPositive(int x) => Interlocked.Add(ref v, -x);
+ public virtual 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 virtual int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
+ }
+
+ ///
+ /// 参数要求倍率speed(默认1)以及AtomicInt类的Score,
+ /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。
+ /// 注意:AtomicIntOnlyAddScore本身为AtomicInt,提供的Score可能构成环而死锁。
+ ///
+ public class AtomicIntOnlyAddScore : AtomicInt
+ {
+ public AtomicInt Score { get; set; };
+ public AtomicDouble speed;
+ public AtomicIntOnlyAddScore(int x, AtomicInt Score, double speed = 1.0) : base(x)
+ {
+ this.Score = Score;
+ this.speed = new(speed);
+ }
+ /// 返回操作前的值
+ public override int SetReturnOri(int value)
+ {
+ int previousV = Interlocked.Exchange(ref v, value);
+ if (value - previousV > 0)
+ Score.AddPositive((int)(speed * (value - previousV)));
+ return previousV;
+ }
+ public override int Add(int x)
+ {
+ if (x > 0) Score.AddPositive((int)(speed * x));
+ return Interlocked.Add(ref v, x);
+ }
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public override int AddPositive(int x)
+ {
+ Score.AddPositive((int)(speed * x));
+ return Interlocked.Add(ref v, x);
+ }
+ public override int Sub(int x)
+ {
+ if (x < 0) Score.AddPositive((int)(speed * -x));
+ return Interlocked.Add(ref v, -x);
+ }
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public override int SubPositive(int x)
+ {
+ return Interlocked.Add(ref v, -x);
+ }
+ public override int Inc()
+ {
+ Score.AddPositive((int)(speed));
+ return Interlocked.Increment(ref v);
+ }
+ /// 返回操作前的值
+ public override int CompareExReturnOri(int newV, int compareTo)
+ {
+ int previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
+ if (newV - previousV > 0)
+ Score.AddPositive((int)(speed * (newV - previousV)));
+ return previousV;
+ }
}
public class AtomicLong : Atomic
{
- private long v;
+ protected 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 along) => Interlocked.Read(ref along.v);
+ public override string ToString() => Interlocked.CompareExchange(ref v, -1, -1).ToString();
+ public long Get() => Interlocked.CompareExchange(ref v, -1, -1);
+ public static implicit operator long(AtomicLong along) => Interlocked.CompareExchange(ref along.v, -1, -1);
/// 返回操作前的值
- 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 virtual long SetReturnOri(long value) => Interlocked.Exchange(ref v, value);
+ public virtual long Add(long x) => Interlocked.Add(ref v, x);
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public virtual long AddPositive(long x) => Interlocked.Add(ref v, x);
+ public virtual long Sub(long x) => Interlocked.Add(ref v, -x);
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public virtual long SubPositive(long x) => Interlocked.Add(ref v, -x);
+ public virtual 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 virtual long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
+ }
+
+ ///
+ /// 参数要求倍率speed(默认1)以及AtomicLong类的Score,
+ /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。
+ /// 注意:AtomicLongOnlyAddScore本身为AtomicLong,提供的Score可能构成环而死锁。
+ ///
+ public class AtomicLongOnlyAddScore : AtomicLong
+ {
+ public AtomicInt Score { get; set; };
+ public AtomicDouble speed;
+ public AtomicLongOnlyAddScore(long x, AtomicLong Score, double speed = 1.0) : base(x)
+ {
+ this.Score = Score;
+ this.speed = new(speed);
+ }
+ /// 返回操作前的值
+ public override long SetReturnOri(long value)
+ {
+ long previousV = Interlocked.Exchange(ref v, value);
+ if (value - previousV > 0)
+ Score.AddPositive((long)(speed * (value - previousV)));
+ return previousV;
+ }
+ public override long Add(long x)
+ {
+ if (x > 0) Score.AddPositive((long)(speed * x));
+ return Interlocked.Add(ref v, x);
+ }
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public override long AddPositive(long x)
+ {
+ Score.AddPositive((long)(speed * x));
+ return Interlocked.Add(ref v, x);
+ }
+ public override long Sub(long x)
+ {
+ if (x < 0) Score.AddPositive((long)(speed * -x));
+ return Interlocked.Add(ref v, -x);
+ }
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public override long SubPositive(long x)
+ {
+ return Interlocked.Add(ref v, -x);
+ }
+ public override long Inc()
+ {
+ Score.AddPositive((long)(speed));
+ return Interlocked.Increment(ref v);
+ }
+ /// 返回操作前的值
+ public override long CompareExReturnOri(long newV, long compareTo)
+ {
+ long previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
+ if (newV - previousV > 0)
+ Score.AddPositive((long)(speed * (newV - previousV)));
+ return previousV;
+ }
}
public class AtomicDouble : Atomic
From f8d0f838c1983ce4b4bd888f95abd4471ba776a5 Mon Sep 17 00:00:00 2001
From: shangfengh <3495281661@qq.com>
Date: Sun, 5 Nov 2023 01:27:02 +0800
Subject: [PATCH 3/3] feat(SafeValue): :sparkles: Add
AtomicIntChangeAffectScore
---
logic/Preparation/Utility/SafeValue/Atomic.cs | 82 +++++++++++++++++--
1 file changed, 74 insertions(+), 8 deletions(-)
diff --git a/logic/Preparation/Utility/SafeValue/Atomic.cs b/logic/Preparation/Utility/SafeValue/Atomic.cs
index 0eee2f5f..dc9c570e 100644
--- a/logic/Preparation/Utility/SafeValue/Atomic.cs
+++ b/logic/Preparation/Utility/SafeValue/Atomic.cs
@@ -32,19 +32,19 @@ public AtomicInt(int x)
///
public virtual int SubPositive(int x) => Interlocked.Add(ref v, -x);
public virtual int Inc() => Interlocked.Increment(ref v);
- public int Dec() => Interlocked.Decrement(ref v);
+ public virtual int Dec() => Interlocked.Decrement(ref v);
/// 返回操作前的值
public virtual int CompareExReturnOri(int newV, int compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
}
///
/// 参数要求倍率speed(默认1)以及AtomicInt类的Score,
- /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。
+ /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed取整。
/// 注意:AtomicIntOnlyAddScore本身为AtomicInt,提供的Score可能构成环而死锁。
///
public class AtomicIntOnlyAddScore : AtomicInt
{
- public AtomicInt Score { get; set; };
+ public AtomicInt Score { get; set; }
public AtomicDouble speed;
public AtomicIntOnlyAddScore(int x, AtomicInt Score, double speed = 1.0) : base(x)
{
@@ -99,6 +99,72 @@ public override int CompareExReturnOri(int newV, int compareTo)
}
}
+ ///
+ /// 参数要求倍率speed(默认1)以及AtomicInt类的Score,
+ /// 在发生变化时,自动给Score加上变化的差乘以speed取整。
+ /// 注意:AtomicIntChangeAffectScore本身为AtomicInt,提供的Score可能构成环而死锁。
+ ///
+ public class AtomicIntChangeAffectScore : AtomicInt
+ {
+ public AtomicInt Score { get; set; }
+ public AtomicDouble speed;
+ public AtomicIntChangeAffectScore(int x, AtomicInt Score, double speed = 1.0) : base(x)
+ {
+ this.Score = Score;
+ this.speed = new(speed);
+ }
+ /// 返回操作前的值
+ public override int SetReturnOri(int value)
+ {
+ int previousV = Interlocked.Exchange(ref v, value);
+ Score.Add((int)(speed * (value - previousV)));
+ return previousV;
+ }
+ public override int Add(int x)
+ {
+ Score.Add((int)(speed * x));
+ return Interlocked.Add(ref v, x);
+ }
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public override int AddPositive(int x)
+ {
+ Score.AddPositive((int)(speed * x));
+ return Interlocked.Add(ref v, x);
+ }
+ public override int Sub(int x)
+ {
+ Score.Sub((int)(speed * x));
+ return Interlocked.Add(ref v, -x);
+ }
+ ///
+ /// 注意:确保参数为非负数
+ ///
+ public override int SubPositive(int x)
+ {
+ Score.SubPositive((int)(speed * x));
+ return Interlocked.Add(ref v, -x);
+ }
+ public override int Inc()
+ {
+ Score.AddPositive((int)(speed));
+ return Interlocked.Increment(ref v);
+ }
+ public override int Dec()
+ {
+ Score.SubPositive((int)(speed));
+ return Interlocked.Decrement(ref v);
+ }
+ /// 返回操作前的值
+ public override int CompareExReturnOri(int newV, int compareTo)
+ {
+ int previousV = Interlocked.CompareExchange(ref v, newV, compareTo);
+ Score.Add((int)(speed * (newV - previousV)));
+ return previousV;
+ }
+ }
+
public class AtomicLong : Atomic
{
protected long v;
@@ -122,23 +188,23 @@ public AtomicLong(long x)
///
public virtual long SubPositive(long x) => Interlocked.Add(ref v, -x);
public virtual long Inc() => Interlocked.Increment(ref v);
- public long Dec() => Interlocked.Decrement(ref v);
+ public virtual long Dec() => Interlocked.Decrement(ref v);
/// 返回操作前的值
public virtual long CompareExReturnOri(long newV, long compareTo) => Interlocked.CompareExchange(ref v, newV, compareTo);
}
///
/// 参数要求倍率speed(默认1)以及AtomicLong类的Score,
- /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed。
+ /// 在发生正向的变化时,自动给Score加上正向变化的差乘以speed取整。
/// 注意:AtomicLongOnlyAddScore本身为AtomicLong,提供的Score可能构成环而死锁。
///
public class AtomicLongOnlyAddScore : AtomicLong
{
- public AtomicInt Score { get; set; };
+ public AtomicLong Score { get; set; }
public AtomicDouble speed;
- public AtomicLongOnlyAddScore(long x, AtomicLong Score, double speed = 1.0) : base(x)
+ public AtomicLongOnlyAddScore(long x, AtomicLong score, double speed = 1.0) : base(x)
{
- this.Score = Score;
+ this.Score = score;
this.speed = new(speed);
}
/// 返回操作前的值