Add judge action fields on_hit
and on_miss
.
This commit is contained in:
@@ -20,6 +20,11 @@ namespace Cryville.Crtr {
|
||||
public JudgeDefinition Definition { get; set; }
|
||||
public NoteHandler Handler { get; set; }
|
||||
}
|
||||
public interface IJudge {
|
||||
bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth);
|
||||
void UpdateScore(ScoreOperation op, PdtExpression exp);
|
||||
}
|
||||
public class Judge : IJudge {
|
||||
#region Data
|
||||
readonly ChartPlayer _sys;
|
||||
internal readonly PdtEvaluator _etor;
|
||||
@@ -193,8 +198,7 @@ namespace Cryville.Crtr {
|
||||
_numbuf2 = (float)hitEvent.EndTime; _numsrc2.Invalidate(); _etor.ContextCascadeUpdate(_var_tn, _numsrc2);
|
||||
var def = hitEvent.Definition;
|
||||
if (def == _judgePause) _sys.TogglePause();
|
||||
if (def.scores != null) UpdateScore(def.scores);
|
||||
if (def.pass != null) Pass(hitEvent, (ft + tt) / 2, def.pass);
|
||||
if (def.on_hit != null) Execute(hitEvent, (ft + tt) / 2, def.on_hit);
|
||||
if (def.persist != null) _etor.Evaluate(_flagop, def.persist);
|
||||
else _flag = false;
|
||||
if (!_flag) {
|
||||
@@ -209,21 +213,6 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
}
|
||||
}
|
||||
bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth = 0) {
|
||||
if (depth >= 16) throw new JudgePropagationException();
|
||||
foreach (var i in ids) {
|
||||
var def = _rs.judges.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(ev, time, def.pass, depth + 1);
|
||||
ev.Handler.ReportJudge(ev, time, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public void Cleanup(Identifier target, float tt) {
|
||||
lock (_etor) {
|
||||
Forward(target, tt);
|
||||
@@ -232,7 +221,7 @@ namespace Cryville.Crtr {
|
||||
JudgeEvent ev = actlist[i];
|
||||
if (tt > ev.EndClip) {
|
||||
actlist.RemoveAt(i);
|
||||
if (ev.Definition.miss != null) Pass(ev, tt, ev.Definition.miss);
|
||||
if (ev.Definition.on_miss != null) Execute(ev, tt, ev.Definition.on_miss);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,18 +237,34 @@ namespace Cryville.Crtr {
|
||||
actlist.Insert(index, ev);
|
||||
}
|
||||
}
|
||||
void UpdateScore(PairList<ScoreOperation, PdtExpression> scoreops) {
|
||||
foreach (var scoreop in scoreops) {
|
||||
var key = scoreop.Key;
|
||||
_etor.ContextSelfValue = scoreSrcs[key.name.Key];
|
||||
_etor.Evaluate(scoreOps[key.name.Key], scoreop.Value);
|
||||
InvalidateScore(key.name.Key);
|
||||
foreach (var s in _rs.scores) {
|
||||
if (s.Value.value != null) {
|
||||
_etor.ContextSelfValue = scoreSrcs[s.Key.Key];
|
||||
_etor.Evaluate(scoreOps[s.Key.Key], s.Value.value);
|
||||
InvalidateScore(s.Key.Key);
|
||||
}
|
||||
void Execute(JudgeEvent ev, float time, PairList<JudgeAction, PdtExpression> actions, int depth = 0) {
|
||||
foreach (var a in actions) {
|
||||
if (a.Key.Execute(this, ev, time, a.Value, depth)) break;
|
||||
}
|
||||
}
|
||||
bool IJudge.Pass(JudgeEvent ev, float time, Identifier[] ids, int depth) {
|
||||
if (depth >= 16) throw new JudgePropagationException();
|
||||
foreach (var i in ids) {
|
||||
var def = _rs.judges.Judges[i];
|
||||
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
|
||||
else _flag = true;
|
||||
if (_flag) {
|
||||
if (def.on_hit != null) Execute(ev, time, def.on_hit, depth + 1);
|
||||
ev.Handler.ReportJudge(ev, time, i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void IJudge.UpdateScore(ScoreOperation op, PdtExpression exp) {
|
||||
_etor.ContextSelfValue = scoreSrcs[op.name.Key];
|
||||
_etor.Evaluate(scoreOps[op.name.Key], exp);
|
||||
InvalidateScore(op.name.Key);
|
||||
foreach (var s in _rs.scores) {
|
||||
if (s.Value.value != null) {
|
||||
_etor.ContextSelfValue = scoreSrcs[s.Key.Key];
|
||||
_etor.Evaluate(scoreOps[s.Key.Key], s.Value.value);
|
||||
InvalidateScore(s.Key.Key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
52
Assets/Cryville/Crtr/JudgeAction.cs
Normal file
52
Assets/Cryville/Crtr/JudgeAction.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using Cryville.Common;
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public abstract class JudgeAction {
|
||||
public static JudgeAction Construct(HashSet<string> a, string k) {
|
||||
if (a.Remove("pass")) {
|
||||
return new Pass(a, from i in k.Split(',') select new Identifier(i.Trim()));
|
||||
}
|
||||
else if (a.Remove("score")) {
|
||||
return new Score(a, k);
|
||||
}
|
||||
throw new FormatException("Invalid judge action format.");
|
||||
}
|
||||
public readonly HashSet<string> annotations;
|
||||
public JudgeAction(IEnumerable<string> a) {
|
||||
annotations = a.ToHashSet();
|
||||
}
|
||||
public virtual void Optimize(PdtEvaluatorBase etor, PdtExpression value) { etor.Optimize(value); }
|
||||
public abstract bool Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, int depth);
|
||||
public class Pass : JudgeAction {
|
||||
readonly Identifier[] _targets;
|
||||
public Pass(IEnumerable<string> a, IEnumerable<Identifier> k) : base(a) {
|
||||
_targets = k.ToArray();
|
||||
}
|
||||
public override bool Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, int depth) {
|
||||
return judge.Pass(ev, time, _targets, depth);
|
||||
}
|
||||
}
|
||||
public class Score : JudgeAction {
|
||||
readonly ScoreOperation _op;
|
||||
public Score(IEnumerable<string> a, string k) : base(a) {
|
||||
_op = new ScoreOperation(k);
|
||||
}
|
||||
public Score(ScoreOperation op) : base(Enumerable.Empty<string>()) {
|
||||
_op = op;
|
||||
}
|
||||
public override void Optimize(PdtEvaluatorBase etor, PdtExpression value) {
|
||||
base.Optimize(etor, value);
|
||||
if (_op.op != default(Identifier)) PdtExpression.PatchCompound(_op.name.Key, _op.op.Key, value);
|
||||
}
|
||||
public override bool Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, int depth) {
|
||||
judge.UpdateScore(_op, exp);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
Assets/Cryville/Crtr/JudgeAction.cs.meta
Normal file
11
Assets/Cryville/Crtr/JudgeAction.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f7e5a4fc83d8c4a4db15856783b8a145
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@@ -6,7 +6,9 @@ using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class Ruleset : MetaInfo {
|
||||
@@ -44,13 +46,8 @@ namespace Cryville.Crtr {
|
||||
foreach (var j in judges.Judges) {
|
||||
var judge = j.Value;
|
||||
if (judge.hit != null) etor.Optimize(judge.hit);
|
||||
if (judge.scores != null) {
|
||||
foreach (var s in judge.scores) {
|
||||
if (s.Key.op != default(Identifier))
|
||||
PdtExpression.PatchCompound(s.Key.name.Key, s.Key.op.Key, s.Value);
|
||||
etor.Optimize(s.Value);
|
||||
}
|
||||
}
|
||||
if (judge.on_hit != null) OptimizeJudgeActions(judge.on_hit, etor);
|
||||
if (judge.on_miss != null) OptimizeJudgeActions(judge.on_miss, etor);
|
||||
}
|
||||
foreach (var a in judges.Areas) {
|
||||
etor.Optimize(a.Value);
|
||||
@@ -61,6 +58,9 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
constraints.Optimize(etor);
|
||||
}
|
||||
void OptimizeJudgeActions(PairList<JudgeAction, PdtExpression> actions, PdtEvaluatorBase etor) {
|
||||
foreach (var a in actions) a.Key.Optimize(etor, a.Value);
|
||||
}
|
||||
public void PrePatch(Chart chart) {
|
||||
constraints.PrePatch(chart);
|
||||
}
|
||||
@@ -83,10 +83,32 @@ namespace Cryville.Crtr {
|
||||
public PdtExpression clip;
|
||||
public PdtExpression input;
|
||||
public PdtExpression hit;
|
||||
public PdtExpression persist; // TODO Compat
|
||||
public Identifier[] pass; // TODO Compat
|
||||
public Identifier[] miss; // TODO Compat
|
||||
public PairList<ScoreOperation, PdtExpression> scores; // TODO Compat
|
||||
public PdtExpression persist;
|
||||
public PairList<JudgeAction, PdtExpression> on_hit;
|
||||
public PairList<JudgeAction, PdtExpression> on_miss;
|
||||
#pragma warning disable IDE1006
|
||||
public PairList<ScoreOperation, PdtExpression> scores {
|
||||
set {
|
||||
if (on_hit == null) on_hit = new PairList<JudgeAction, PdtExpression>();
|
||||
int i = 0;
|
||||
foreach (var s in value) {
|
||||
on_hit.Insert(i++, new JudgeAction.Score(s.Key), s.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
public Identifier[] pass {
|
||||
set {
|
||||
if (on_hit == null) on_hit = new PairList<JudgeAction, PdtExpression>();
|
||||
on_hit.Add(new JudgeAction.Pass(Enumerable.Empty<string>(), value), PdtExpression.Empty);
|
||||
}
|
||||
}
|
||||
public Identifier[] miss {
|
||||
set {
|
||||
if (on_miss == null) on_miss = new PairList<JudgeAction, PdtExpression>();
|
||||
on_miss.Add(new JudgeAction.Pass(Enumerable.Empty<string>(), value), PdtExpression.Empty);
|
||||
}
|
||||
}
|
||||
#pragma warning restore IDE1006
|
||||
}
|
||||
public class ScoreOperation {
|
||||
public Identifier name;
|
||||
|
@@ -1,3 +1,4 @@
|
||||
using Cryville.Common.Collections.Generic;
|
||||
using Cryville.Common.Pdt;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@@ -10,11 +11,29 @@ namespace Cryville.Crtr {
|
||||
readonly List<RulesetSelector> s = new List<RulesetSelector>();
|
||||
readonly HashSet<string> a = new HashSet<string>();
|
||||
protected override object InterpretKey(Type type) {
|
||||
if (type == typeof(Constraint))
|
||||
if (PairCollection<JudgeAction, PdtExpression>.IsPairCollection(type))
|
||||
return InterpretJudgeAction();
|
||||
else if (type == typeof(Constraint))
|
||||
return InterpretConstraintKey();
|
||||
else
|
||||
return base.InterpretKey(type);
|
||||
}
|
||||
object InterpretJudgeAction() {
|
||||
a.Clear();
|
||||
while (true) {
|
||||
int pp = Position;
|
||||
switch (cc) {
|
||||
case '@':
|
||||
GetChar();
|
||||
a.Add(GetIdentifier());
|
||||
break;
|
||||
default:
|
||||
return JudgeAction.Construct(a, (string)base.InterpretKey(null));
|
||||
}
|
||||
ws();
|
||||
if (Position == pp) throw new FormatException("Invalid judge action format.");
|
||||
}
|
||||
}
|
||||
object InterpretConstraintKey() {
|
||||
s.Clear(); a.Clear();
|
||||
string key = "";
|
||||
|
Reference in New Issue
Block a user