Make hit expression comparable.
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text.Formatting;
|
||||
using UnsafeIL;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class Judge {
|
||||
@@ -47,7 +48,7 @@ namespace Cryville.Crtr {
|
||||
_numsrc2 = new PropSrc.Float(() => _numbuf2);
|
||||
_numsrc3 = new PropSrc.Float(() => _numbuf3);
|
||||
_numsrc4 = new PropSrc.Float(() => _numbuf4);
|
||||
_rs.judges.TryGetValue(new Identifier(_var_pause), out _judgePause);
|
||||
_rs.judges.Judges.TryGetValue(new Identifier(_var_pause), out _judgePause);
|
||||
foreach (var i in rs.inputs) {
|
||||
var id = i.Key;
|
||||
var l = new List<JudgeEvent>();
|
||||
@@ -98,6 +99,33 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
static bool _flag;
|
||||
static readonly PropOp.Boolean _flagop = new PropOp.Boolean(v => _flag = v);
|
||||
static readonly HitOp _hitop = new HitOp();
|
||||
class HitOp : PdtOperator {
|
||||
const int MAX_SORTS = 16;
|
||||
readonly float[] _buf = new float[MAX_SORTS];
|
||||
readonly float[] _sorts = new float[MAX_SORTS];
|
||||
public bool LastHit { get; private set; }
|
||||
|
||||
public HitOp() : base(MAX_SORTS) { }
|
||||
|
||||
protected unsafe override void Execute() {
|
||||
LastHit = false;
|
||||
for (int i = 0; i < LoadedOperandCount; i++) {
|
||||
var sort = GetOperand(i).AsNumber();
|
||||
if (sort <= 0) return;
|
||||
if (!LastHit && sort < _sorts[i]) return;
|
||||
if (sort > _sorts[i]) LastHit = true;
|
||||
_buf[i] = sort;
|
||||
}
|
||||
if (!LastHit) return;
|
||||
Array.Clear(_buf, LoadedOperandCount, MAX_SORTS - LoadedOperandCount);
|
||||
fixed (float* ptrsrc = _buf, ptrdest = _sorts) {
|
||||
Unsafe.CopyBlock(ptrdest, ptrsrc, MAX_SORTS * sizeof(float));
|
||||
}
|
||||
}
|
||||
|
||||
public void Clear() { Array.Clear(_sorts, 0, MAX_SORTS); }
|
||||
}
|
||||
static readonly int _var_fn = IdentifierManager.Shared.Request("judge_clip_from");
|
||||
static readonly int _var_tn = IdentifierManager.Shared.Request("judge_clip_to");
|
||||
static readonly int _var_ft = IdentifierManager.Shared.Request("input_time_from");
|
||||
@@ -121,14 +149,13 @@ namespace Cryville.Crtr {
|
||||
}
|
||||
return ~num;
|
||||
}
|
||||
int BinarySearchFirst(List<JudgeEvent> list, float time, int stack) {
|
||||
if (list[0].Definition.stack == stack && list[0].StartClip == time) return 0;
|
||||
int BinarySearchFirst(List<JudgeEvent> list, int stack) {
|
||||
if (list[0].Definition.stack == stack) return 0;
|
||||
int num = 0;
|
||||
int num2 = list.Count - 1;
|
||||
while (num <= num2) {
|
||||
int num3 = num + (num2 - num >> 1);
|
||||
int num4 = -list[num3].Definition.stack.CompareTo(stack);
|
||||
if (num4 == 0) num4 = list[num3].StartClip.CompareTo(time);
|
||||
if (num4 > 0) num2 = num3 - 1;
|
||||
else if (num4 < 0) num = num3 + 1;
|
||||
else if (num != num3) num2 = num3;
|
||||
@@ -143,28 +170,43 @@ namespace Cryville.Crtr {
|
||||
_numbuf3 = ft; _numsrc3.Invalidate(); _etor.ContextCascadeUpdate(_var_ft, _numsrc3);
|
||||
_numbuf4 = tt; _numsrc4.Invalidate(); _etor.ContextCascadeUpdate(_var_tt, _numsrc4);
|
||||
int index = 0, iter = 0;
|
||||
while (index >= 0 && index < actlist.Count) {
|
||||
var ev = actlist[index];
|
||||
_numbuf1 = (float)ev.StartTime; _numsrc1.Invalidate(); _etor.ContextCascadeUpdate(_var_fn, _numsrc1);
|
||||
_numbuf2 = (float)ev.EndTime; _numsrc2.Invalidate(); _etor.ContextCascadeUpdate(_var_tn, _numsrc2);
|
||||
var def = ev.Definition;
|
||||
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
|
||||
else _flag = true;
|
||||
if (_flag) {
|
||||
if (ev.Definition == _judgePause) _sys.TogglePause();
|
||||
while (index < actlist.Count) {
|
||||
if (iter++ >= 16) throw new JudgePropagationException();
|
||||
_hitop.Clear();
|
||||
int cstack = actlist[index].Definition.stack;
|
||||
int hitIndex = -1;
|
||||
while (index >= 0 && index < actlist.Count) {
|
||||
var ev = actlist[index];
|
||||
if (ev.Definition.stack != cstack) break;
|
||||
_numbuf1 = (float)ev.StartTime; _numsrc1.Invalidate(); _etor.ContextCascadeUpdate(_var_fn, _numsrc1);
|
||||
_numbuf2 = (float)ev.EndTime; _numsrc2.Invalidate(); _etor.ContextCascadeUpdate(_var_tn, _numsrc2);
|
||||
var def = ev.Definition;
|
||||
if (def.hit != null) {
|
||||
_etor.Evaluate(_hitop, def.hit);
|
||||
if (_hitop.LastHit) hitIndex = index;
|
||||
}
|
||||
else if (hitIndex == -1) hitIndex = index;
|
||||
index++;
|
||||
}
|
||||
if (hitIndex != -1) {
|
||||
var hitEvent = actlist[hitIndex];
|
||||
_numbuf1 = (float)hitEvent.StartTime; _numsrc1.Invalidate(); _etor.ContextCascadeUpdate(_var_fn, _numsrc1);
|
||||
_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(ev, (ft + tt) / 2, def.pass);
|
||||
if (def.pass != null) Pass(hitEvent, (ft + tt) / 2, def.pass);
|
||||
if (def.persist != null) _etor.Evaluate(_flagop, def.persist);
|
||||
else _flag = false;
|
||||
if (!_flag) actlist.RemoveAt(index);
|
||||
if (!_flag) {
|
||||
actlist.RemoveAt(hitIndex);
|
||||
--index;
|
||||
}
|
||||
if (def.prop != 0 && actlist.Count > 0) {
|
||||
index = BinarySearchFirst(actlist, (float)ev.StartClip, def.stack - def.prop);
|
||||
index = BinarySearchFirst(actlist, def.stack - def.prop);
|
||||
if (index < 0) index = ~index;
|
||||
}
|
||||
else index++;
|
||||
if (iter++ >= 16) throw new JudgePropagationException();
|
||||
}
|
||||
else index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user