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