Add stub for "call" judge action.
This commit is contained in:
@@ -16,7 +16,7 @@ namespace Cryville.Crtr {
|
||||
public float? Time { get; set; }
|
||||
public Vector4 Vector { get; set; }
|
||||
}
|
||||
internal struct JudgeEvent {
|
||||
internal class JudgeEvent {
|
||||
public double StartTime { get; set; }
|
||||
public double EndTime { get; set; }
|
||||
public double StartClip { get; set; }
|
||||
@@ -25,8 +25,16 @@ namespace Cryville.Crtr {
|
||||
public JudgeDefinition Definition { get; set; }
|
||||
public NoteHandler Handler { get; set; }
|
||||
public JudgeResult JudgeResult { get; set; }
|
||||
public JudgeCallContext CallContext { get; set; }
|
||||
}
|
||||
internal struct JudgeCallContext {
|
||||
public bool CalledOnMiss { get; set; }
|
||||
public float CallTime { get; set; }
|
||||
public JudgeEvent ReturnEvent { get; set; }
|
||||
public int ReturnIndex { get; set; }
|
||||
}
|
||||
internal interface IJudge {
|
||||
void Call(JudgeEvent ev, float time, Identifier id, bool onMiss, int index);
|
||||
bool Pass(JudgeEvent ev, float time, Identifier[] ids, int depth);
|
||||
void UpdateScore(ScoreOperation op, PdtExpression exp);
|
||||
}
|
||||
@@ -85,7 +93,7 @@ namespace Cryville.Crtr {
|
||||
var tev = (Chart.Judge)sev.Unstamped;
|
||||
InsertEvent(tev, new Clip((float)sev.Time, (float)(sev.Time + sev.Duration)), tev.Id, handler);
|
||||
}
|
||||
void InsertEvent(Chart.Judge ev, Clip clip, Identifier id, NoteHandler handler) {
|
||||
void InsertEvent(Chart.Judge ev, Clip clip, Identifier id, NoteHandler handler, JudgeCallContext call = default(JudgeCallContext)) {
|
||||
if (id.Key == _var_pause) throw new InvalidOperationException("Cannot assign the special judge \"pause\" to notes");
|
||||
var def = _rs.judges[id];
|
||||
_etor.Evaluate(_identop, def.input);
|
||||
@@ -99,6 +107,7 @@ namespace Cryville.Crtr {
|
||||
BaseEvent = ev,
|
||||
Definition = def,
|
||||
Handler = handler,
|
||||
CallContext = call,
|
||||
};
|
||||
var index = list.BinarySearch(jev, _stcmp);
|
||||
if (index < 0) index = ~index;
|
||||
@@ -236,7 +245,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.on_hit != null) Execute(hitEvent, (ft + tt) / 2, def.on_hit);
|
||||
if (def.on_hit != null) Execute(hitEvent, (ft + tt) / 2, def.on_hit, false);
|
||||
if (def.persist != null) _etor.Evaluate(_flagop, def.persist);
|
||||
else _flag = false;
|
||||
if (!_flag) {
|
||||
@@ -259,7 +268,7 @@ namespace Cryville.Crtr {
|
||||
JudgeEvent ev = actlist[i];
|
||||
if (tt > ev.EndClip) {
|
||||
actlist.RemoveAt(i);
|
||||
if (ev.Definition.on_miss != null) Execute(ev, tt, ev.Definition.on_miss);
|
||||
Execute(ev, tt, ev.Definition.on_miss, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -275,14 +284,36 @@ namespace Cryville.Crtr {
|
||||
actlist.Insert(index, ev);
|
||||
}
|
||||
}
|
||||
void Execute(JudgeEvent ev, float time, PairList<JudgeAction, PdtExpression> actions, int depth = 0) {
|
||||
void Execute(JudgeEvent ev, float time, PairList<JudgeAction, PdtExpression> actions, bool onMiss, int depth = 0, int index = 0) {
|
||||
if (ev.JudgeResult.Time != null) {
|
||||
_jnumbuf = ev.JudgeResult.Time.Value; _jnumsrc.Invalidate(); _etor.ContextCascadeUpdate(_var_jt, _jnumsrc);
|
||||
_jvecbuf = ev.JudgeResult.Vector; _jvecsrc.Invalidate(); _etor.ContextCascadeUpdate(_var_jv, _jvecsrc);
|
||||
}
|
||||
foreach (var a in actions) {
|
||||
if (a.Key.Execute(this, ev, time, a.Value, depth)) break;
|
||||
if (actions != null) {
|
||||
// Ensure that all actions that modifies judge result sources break the execution
|
||||
for (int i = index; i < actions.Count; i++) {
|
||||
var a = actions[i];
|
||||
if (a.Key.Execute(this, ev, time, a.Value, onMiss, depth, i).BreakExecution) break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var call = ev.CallContext;
|
||||
if (call.ReturnEvent != null) {
|
||||
// TODO
|
||||
if (onMiss)
|
||||
Execute(call.ReturnEvent, time, call.ReturnEvent.Definition.on_miss, true, depth + 1, 0);
|
||||
else
|
||||
Execute(call.ReturnEvent, time, call.ReturnEvent.Definition.on_hit, false, depth + 1, call.ReturnIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
void IJudge.Call(JudgeEvent ev, float time, Identifier id, bool onMiss, int index) {
|
||||
InsertEvent(ev.BaseEvent, new Clip((float)ev.StartTime, (float)ev.EndTime), id, ev.Handler, new JudgeCallContext {
|
||||
CalledOnMiss = onMiss,
|
||||
CallTime = time,
|
||||
ReturnEvent = ev,
|
||||
ReturnIndex = index + 1,
|
||||
}); // TODO optimize GC
|
||||
}
|
||||
bool IJudge.Pass(JudgeEvent ev, float time, Identifier[] ids, int depth) {
|
||||
if (depth >= 16) throw new JudgePropagationException();
|
||||
@@ -296,7 +327,7 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
else hitFlag = true;
|
||||
if (hitFlag) {
|
||||
Execute(ev, time, def.on_hit, depth + 1);
|
||||
Execute(ev, time, def.on_hit, false, depth + 1);
|
||||
ev.Handler.ReportJudge(ev, time, i);
|
||||
return true;
|
||||
}
|
||||
|
@@ -5,11 +5,18 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
internal struct JudgeActionResult {
|
||||
public bool BreakExecution;
|
||||
public bool PreventRecycle;
|
||||
}
|
||||
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("call")) {
|
||||
return new Call(a, new Identifier(k));
|
||||
}
|
||||
else if (a.Remove("score")) {
|
||||
return new Score(a, k);
|
||||
}
|
||||
@@ -20,14 +27,24 @@ namespace Cryville.Crtr {
|
||||
annotations = a.ToHashSet();
|
||||
}
|
||||
public virtual void Optimize(PdtEvaluatorBase etor, PdtExpression value) { etor.Optimize(value); }
|
||||
internal abstract bool Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, int depth);
|
||||
internal abstract JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index);
|
||||
public class Call : JudgeAction {
|
||||
readonly Identifier _target;
|
||||
public Call(IEnumerable<string> a, Identifier k) : base(a) {
|
||||
_target = k;
|
||||
}
|
||||
internal override JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index) {
|
||||
judge.Call(ev, time, _target, onMiss, index);
|
||||
return new JudgeActionResult { BreakExecution = true, PreventRecycle = true };
|
||||
}
|
||||
}
|
||||
public class Pass : JudgeAction {
|
||||
readonly Identifier[] _targets;
|
||||
public Pass(IEnumerable<string> a, IEnumerable<Identifier> k) : base(a) {
|
||||
_targets = k.ToArray();
|
||||
}
|
||||
internal override bool Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, int depth) {
|
||||
return judge.Pass(ev, time, _targets, depth);
|
||||
internal override JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index) {
|
||||
return new JudgeActionResult { BreakExecution = judge.Pass(ev, time, _targets, depth) };
|
||||
}
|
||||
}
|
||||
public class Score : JudgeAction {
|
||||
@@ -42,9 +59,9 @@ namespace Cryville.Crtr {
|
||||
base.Optimize(etor, value);
|
||||
if (_op.op != default(Identifier)) PdtExpression.PatchCompound(_op.name.Key, _op.op.Key, value);
|
||||
}
|
||||
internal override bool Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, int depth) {
|
||||
internal override JudgeActionResult Execute(IJudge judge, JudgeEvent ev, float time, PdtExpression exp, bool onMiss, int depth, int index) {
|
||||
judge.UpdateScore(_op, exp);
|
||||
return false;
|
||||
return new JudgeActionResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user