Implement judge feed, pass, cleanup, and miss. Add update score stub.

This commit is contained in:
2022-11-14 13:57:02 +08:00
parent c31c16792c
commit 49431e888c

View File

@@ -55,6 +55,19 @@ namespace Cryville.Crtr {
if (index < 0) index = ~index;
list.Insert(index, ev);
}
static bool _flag;
static readonly PropOp.Boolean _flagop = new PropOp.Boolean(v => _flag = v);
static readonly int _var_fn = IdentifierManager.SharedInstance.Request("fn");
static readonly int _var_tn = IdentifierManager.SharedInstance.Request("tn");
static readonly int _var_ft = IdentifierManager.SharedInstance.Request("ft");
static readonly int _var_tt = IdentifierManager.SharedInstance.Request("tt");
readonly byte[] _numbuf1 = new byte[sizeof(float)];
readonly byte[] _numbuf2 = new byte[sizeof(float)];
readonly byte[] _numbuf3 = new byte[sizeof(float)];
readonly byte[] _numbuf4 = new byte[sizeof(float)];
unsafe void LoadNum(byte[] buffer, float value) {
fixed (byte* ptr = buffer) *(float*)ptr = value;
}
// Adopted from System.Collections.Generic.ArraySortHelper<T>.InternalBinarySearch(T[] array, int index, int length, T value, IComparer<T> comparer)
int BinarySearch(List<JudgeEvent> list, float time, int stack) {
int num = 0;
@@ -72,10 +85,42 @@ namespace Cryville.Crtr {
public void Feed(Identifier target, float ft, float tt) {
Forward(target, tt);
var actlist = activeEvs[target];
foreach (var ev in actlist) {
// TODO judge ev
if (actlist.Count > 0) {
LoadNum(_numbuf3, ft); _etor.ContextCascadeUpdate(_var_ft, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf3));
LoadNum(_numbuf4, tt); _etor.ContextCascadeUpdate(_var_tt, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf4));
var index = 0;
while (index >= 0 && index < actlist.Count) {
var ev = actlist[index];
LoadNum(_numbuf1, ev.StartTime); _etor.ContextCascadeUpdate(_var_fn, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf1));
LoadNum(_numbuf2, ev.EndTime); _etor.ContextCascadeUpdate(_var_tn, new PropSrc.Arbitrary(PdtInternalType.Number, _numbuf2));
var def = ev.Definition;
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);
actlist.RemoveAt(index);
index = BinarySearch(actlist, ev.StartClip, def.prop);
if (index < 0) index = ~index;
}
else index++;
}
}
}
bool Pass(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);
Logger.Log("main", 0, "Judge", "hit {0}", i);
return true;
}
}
return false;
}
public void Cleanup(Identifier target, float ft, float tt) {
Forward(target, tt);
var actlist = activeEvs[target];
@@ -83,7 +128,7 @@ namespace Cryville.Crtr {
JudgeEvent ev = actlist[i];
if (tt > ev.EndClip) {
actlist.RemoveAt(i);
// TODO miss ev
if (ev.Definition.miss != null) Pass(ev.Definition.miss);
}
}
}
@@ -96,7 +141,11 @@ namespace Cryville.Crtr {
var index = BinarySearch(actlist, ev.StartClip, ev.Definition.stack);
if (index < 0) index = ~index;
actlist.Insert(index, ev);
// TODO priority?
}
}
void UpdateScore(Dictionary<ScoreOperation, PdtExpression> scores) {
foreach (var score in scores) {
// TODO
}
}
public readonly Dictionary<int, ScoreDefinition> scoreDefs = new Dictionary<int, ScoreDefinition>();
@@ -132,7 +181,7 @@ namespace Cryville.Crtr {
public PdtExpression input;
public PdtExpression hit;
public Identifier[] pass;
public Identifier miss;
public Identifier[] miss;
public Dictionary<ScoreOperation, PdtExpression> scores;
public int stack;
public int prop = -1;