Fix race condition for the shared evaluator when any active input handler is threaded.

This commit is contained in:
2023-04-22 21:16:17 +08:00
parent a1fd420493
commit 72a93721f9
4 changed files with 57 additions and 54 deletions

View File

@@ -13,7 +13,7 @@ namespace Cryville.Crtr {
public class Judge {
#region Data
readonly ChartPlayer _sys;
readonly PdtEvaluator _etor;
internal readonly PdtEvaluator _etor;
readonly PdtRuleset _rs;
readonly Dictionary<Identifier, List<JudgeEvent>> evs
= new Dictionary<Identifier, List<JudgeEvent>>();
@@ -38,7 +38,8 @@ namespace Cryville.Crtr {
}
public Judge(ChartPlayer sys, PdtRuleset rs) {
_sys = sys;
_etor = ChartPlayer.etor;
_etor = new PdtEvaluator();
_etor.ContextJudge = this;
_rs = rs;
_numsrc1 = new PropSrc.Float(() => _numbuf1);
_numsrc2 = new PropSrc.Float(() => _numbuf2);
@@ -67,8 +68,8 @@ namespace Cryville.Crtr {
Identifier input = default(Identifier);
Clip clip = default(Clip);
var def = _rs.judges[tev.Id];
ChartPlayer.etor.Evaluate(new PropOp.Identifier(v => input = new Identifier(v)), def.input);
ChartPlayer.etor.Evaluate(new PropOp.Clip(v => clip = v), def.clip);
_etor.Evaluate(new PropOp.Identifier(v => input = new Identifier(v)), def.input);
_etor.Evaluate(new PropOp.Clip(v => clip = v), def.clip);
double st = sev.Time, et = st + sev.Duration;
var list = evs[input];
var ev = new JudgeEvent {
@@ -181,13 +182,15 @@ namespace Cryville.Crtr {
return false;
}
public void Cleanup(Identifier target, float tt) {
Forward(target, tt);
var actlist = activeEvs[target];
for (int i = actlist.Count - 1; i >= 0; i--) {
JudgeEvent ev = actlist[i];
if (tt > ev.EndClip) {
actlist.RemoveAt(i);
if (ev.Definition.miss != null) Pass(ev, tt, ev.Definition.miss);
lock (_etor) {
Forward(target, tt);
var actlist = activeEvs[target];
for (int i = actlist.Count - 1; i >= 0; i--) {
JudgeEvent ev = actlist[i];
if (tt > ev.EndClip) {
actlist.RemoveAt(i);
if (ev.Definition.miss != null) Pass(ev, tt, ev.Definition.miss);
}
}
}
}
@@ -254,18 +257,20 @@ namespace Cryville.Crtr {
return scoreSrcs.TryGetValue(key, out value);
}
public TargetString GetFullFormattedScoreString() {
bool flag = false;
scoreFullBuf.Clear();
foreach (var s in scores) {
var id = s.Key;
scoreFullBuf.AppendFormat(flag ? "\n{0}: " : "{0}: ", (string)IdentifierManager.SharedInstance.Retrieve(id));
scoreFullBuf.AppendFormat(scoreFormatCache[id], scores[id]);
flag = true;
lock (_etor) {
bool flag = false;
scoreFullBuf.Clear();
foreach (var s in scores) {
var id = s.Key;
scoreFullBuf.AppendFormat(flag ? "\n{0}: " : "{0}: ", (string)IdentifierManager.SharedInstance.Retrieve(id));
scoreFullBuf.AppendFormat(scoreFormatCache[id], scores[id]);
flag = true;
}
scoreFullStr.Length = scoreFullBuf.Count;
var arr = scoreFullStr.TrustedAsArray();
scoreFullBuf.CopyTo(0, arr, 0, scoreFullBuf.Count);
return scoreFullStr;
}
scoreFullStr.Length = scoreFullBuf.Count;
var arr = scoreFullStr.TrustedAsArray();
scoreFullBuf.CopyTo(0, arr, 0, scoreFullBuf.Count);
return scoreFullStr;
}
class ScoreStringSrc : PropSrc {
readonly Func<float> _cb;