Implement judge report.

This commit is contained in:
2023-01-01 19:00:19 +08:00
parent ca72f7adb5
commit e8f74399f2
2 changed files with 51 additions and 7 deletions

View File

@@ -16,11 +16,12 @@ namespace Cryville.Crtr {
= new Dictionary<Identifier, List<JudgeEvent>>();
readonly Dictionary<Identifier, List<JudgeEvent>> activeEvs
= new Dictionary<Identifier, List<JudgeEvent>>();
struct JudgeEvent {
public struct JudgeEvent {
public double StartTime { get; set; }
public double EndTime { get; set; }
public double StartClip { get; set; }
public double EndClip { get; set; }
public Identifier JudgeId { get; set; }
public JudgeDefinition Definition { get; set; }
public NoteHandler Handler { get; set; }
}
@@ -33,20 +34,23 @@ namespace Cryville.Crtr {
public Judge(PdtRuleset rs) {
_etor = ChartPlayer.etor;
_rs = rs;
InitJudges();
InitScores();
}
public void Prepare(double st, double et, Identifier input, JudgeDefinition def, NoteHandler handler) {
public void Prepare(double st, double et, Identifier input, Identifier judge, NoteHandler handler) {
List<JudgeEvent> list;
if (!evs.TryGetValue(input, out list)) {
ct.Add(input, 0);
evs.Add(input, list = new List<JudgeEvent>());
activeEvs.Add(input, new List<JudgeEvent>());
}
var def = _rs.judges[judge];
var ev = new JudgeEvent {
StartTime = st,
EndTime = et,
StartClip = st + def.clip[0],
EndClip = et + def.clip[1],
JudgeId = judge,
Definition = def,
Handler = handler,
};
@@ -56,6 +60,14 @@ namespace Cryville.Crtr {
}
#endregion
#region Judge
internal readonly Dictionary<int, int> jtabsMap = new Dictionary<int, int>();
internal readonly Dictionary<int, int> jtrelMap = new Dictionary<int, int>();
void InitJudges() {
foreach (var i in _rs.judges.Keys) {
jtabsMap.Add(i.Key, IdentifierManager.SharedInstance.Request("jtabs_" + i.Name));
jtrelMap.Add(i.Key, IdentifierManager.SharedInstance.Request("jtrel_" + i.Name));
}
}
static bool _flag;
static readonly PropOp.Boolean _flagop = new PropOp.Boolean(v => _flag = v);
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
@@ -114,7 +126,7 @@ namespace Cryville.Crtr {
else _flag = true;
if (_flag) {
if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(def.pass);
if (def.pass != null) Pass(ev, (ft + tt) / 2, def.pass);
actlist.RemoveAt(index);
if (def.prop != 0 && actlist.Count > 0) {
index = BinarySearchFirst(actlist, (float)ev.StartClip, def.stack - def.prop);
@@ -126,14 +138,15 @@ namespace Cryville.Crtr {
}
}
}
bool Pass(Identifier[] ids) {
bool Pass(JudgeEvent ev, float time, Identifier[] ids) {
foreach (var i in ids) {
var def = _rs.judges[i];
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
else _flag = true;
if (_flag) {
if (def.scores != null) UpdateScore(def.scores);
if (def.pass != null) Pass(def.pass);
if (def.pass != null) Pass(ev, time, def.pass);
ev.Handler.ReportJudge(ev, time, i);
return true;
}
}
@@ -146,7 +159,7 @@ namespace Cryville.Crtr {
JudgeEvent ev = actlist[i];
if (tt > ev.EndClip) {
actlist.RemoveAt(i);
if (ev.Definition.miss != null) Pass(ev.Definition.miss);
if (ev.Definition.miss != null) Pass(ev, tt, ev.Definition.miss);
}
}
}

View File

@@ -24,7 +24,32 @@ namespace Cryville.Crtr {
}
SectionalGameObject[] sgos;
readonly Dictionary<Identifier, JudgeState> judges = new Dictionary<Identifier, JudgeState>();
class JudgeState {
public int AbsoluteAnchorName { get; set; }
public int RelativeAnchorName { get; set; }
public bool Judged { get; private set; }
public float AbsoluteTime { get; private set; }
public float RelativeTime { get; private set; }
public JudgeState(NoteHandler handler, int name) {
handler.RegisterAnchor(AbsoluteAnchorName = handler.judge.jtabsMap[name]);
handler.RegisterAnchor(RelativeAnchorName = handler.judge.jtrelMap[name]);
}
public void MarkJudged(float abs, float rel) {
Judged = true;
AbsoluteTime = abs;
RelativeTime = rel;
}
}
public override void PreInit() {
base.PreInit();
foreach (var j in Event.judges) {
if (!judges.ContainsKey(j.Id)) {
judges.Add(j.Id, new JudgeState(this, j.Id.Key));
}
}
}
public override void Init() {
base.Init();
sgos = gogroup.GetComponentsInChildren<SectionalGameObject>();
@@ -90,7 +115,7 @@ namespace Cryville.Crtr {
ChartPlayer.etor.ContextEvent = tev;
ChartPlayer.etor.ContextState = s;
ChartPlayer.etor.Evaluate(new PropOp.Identifier(v => name = new Identifier(v)), ruleset.judges[tev.Id].input);
judge.Prepare(ev.Time, ev.Time + ev.Duration, name, ruleset.judges[tev.Id], this);
judge.Prepare(ev.Time, ev.Time + ev.Duration, name, tev.Id, this);
ChartPlayer.etor.ContextState = null;
ChartPlayer.etor.ContextEvent = null;
}
@@ -166,5 +191,11 @@ namespace Cryville.Crtr {
}
}
}
public void ReportJudge(Judge.JudgeEvent ev, float time, Identifier result) {
JudgeState state;
if (!judges.TryGetValue(ev.JudgeId, out state)) return;
state.MarkJudged(time, (float)(time - cs.Time));
}
}
}