Make hit expression comparable.
This commit is contained in:
@@ -8,6 +8,7 @@ using System.Collections.Generic;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using System.Text.Formatting;
|
using System.Text.Formatting;
|
||||||
|
using UnsafeIL;
|
||||||
|
|
||||||
namespace Cryville.Crtr {
|
namespace Cryville.Crtr {
|
||||||
public class Judge {
|
public class Judge {
|
||||||
@@ -47,7 +48,7 @@ namespace Cryville.Crtr {
|
|||||||
_numsrc2 = new PropSrc.Float(() => _numbuf2);
|
_numsrc2 = new PropSrc.Float(() => _numbuf2);
|
||||||
_numsrc3 = new PropSrc.Float(() => _numbuf3);
|
_numsrc3 = new PropSrc.Float(() => _numbuf3);
|
||||||
_numsrc4 = new PropSrc.Float(() => _numbuf4);
|
_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) {
|
foreach (var i in rs.inputs) {
|
||||||
var id = i.Key;
|
var id = i.Key;
|
||||||
var l = new List<JudgeEvent>();
|
var l = new List<JudgeEvent>();
|
||||||
@@ -98,6 +99,33 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
static bool _flag;
|
static bool _flag;
|
||||||
static readonly PropOp.Boolean _flagop = new PropOp.Boolean(v => _flag = v);
|
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_fn = IdentifierManager.Shared.Request("judge_clip_from");
|
||||||
static readonly int _var_tn = IdentifierManager.Shared.Request("judge_clip_to");
|
static readonly int _var_tn = IdentifierManager.Shared.Request("judge_clip_to");
|
||||||
static readonly int _var_ft = IdentifierManager.Shared.Request("input_time_from");
|
static readonly int _var_ft = IdentifierManager.Shared.Request("input_time_from");
|
||||||
@@ -121,14 +149,13 @@ namespace Cryville.Crtr {
|
|||||||
}
|
}
|
||||||
return ~num;
|
return ~num;
|
||||||
}
|
}
|
||||||
int BinarySearchFirst(List<JudgeEvent> list, float time, int stack) {
|
int BinarySearchFirst(List<JudgeEvent> list, int stack) {
|
||||||
if (list[0].Definition.stack == stack && list[0].StartClip == time) return 0;
|
if (list[0].Definition.stack == stack) return 0;
|
||||||
int num = 0;
|
int num = 0;
|
||||||
int num2 = list.Count - 1;
|
int num2 = list.Count - 1;
|
||||||
while (num <= num2) {
|
while (num <= num2) {
|
||||||
int num3 = num + (num2 - num >> 1);
|
int num3 = num + (num2 - num >> 1);
|
||||||
int num4 = -list[num3].Definition.stack.CompareTo(stack);
|
int num4 = -list[num3].Definition.stack.CompareTo(stack);
|
||||||
if (num4 == 0) num4 = list[num3].StartClip.CompareTo(time);
|
|
||||||
if (num4 > 0) num2 = num3 - 1;
|
if (num4 > 0) num2 = num3 - 1;
|
||||||
else if (num4 < 0) num = num3 + 1;
|
else if (num4 < 0) num = num3 + 1;
|
||||||
else if (num != num3) num2 = num3;
|
else if (num != num3) num2 = num3;
|
||||||
@@ -143,28 +170,43 @@ namespace Cryville.Crtr {
|
|||||||
_numbuf3 = ft; _numsrc3.Invalidate(); _etor.ContextCascadeUpdate(_var_ft, _numsrc3);
|
_numbuf3 = ft; _numsrc3.Invalidate(); _etor.ContextCascadeUpdate(_var_ft, _numsrc3);
|
||||||
_numbuf4 = tt; _numsrc4.Invalidate(); _etor.ContextCascadeUpdate(_var_tt, _numsrc4);
|
_numbuf4 = tt; _numsrc4.Invalidate(); _etor.ContextCascadeUpdate(_var_tt, _numsrc4);
|
||||||
int index = 0, iter = 0;
|
int index = 0, iter = 0;
|
||||||
while (index >= 0 && index < actlist.Count) {
|
while (index < actlist.Count) {
|
||||||
var ev = actlist[index];
|
if (iter++ >= 16) throw new JudgePropagationException();
|
||||||
_numbuf1 = (float)ev.StartTime; _numsrc1.Invalidate(); _etor.ContextCascadeUpdate(_var_fn, _numsrc1);
|
_hitop.Clear();
|
||||||
_numbuf2 = (float)ev.EndTime; _numsrc2.Invalidate(); _etor.ContextCascadeUpdate(_var_tn, _numsrc2);
|
int cstack = actlist[index].Definition.stack;
|
||||||
var def = ev.Definition;
|
int hitIndex = -1;
|
||||||
if (def.hit != null) _etor.Evaluate(_flagop, def.hit);
|
while (index >= 0 && index < actlist.Count) {
|
||||||
else _flag = true;
|
var ev = actlist[index];
|
||||||
if (_flag) {
|
if (ev.Definition.stack != cstack) break;
|
||||||
if (ev.Definition == _judgePause) _sys.TogglePause();
|
_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.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);
|
if (def.persist != null) _etor.Evaluate(_flagop, def.persist);
|
||||||
else _flag = false;
|
else _flag = false;
|
||||||
if (!_flag) actlist.RemoveAt(index);
|
if (!_flag) {
|
||||||
|
actlist.RemoveAt(hitIndex);
|
||||||
|
--index;
|
||||||
|
}
|
||||||
if (def.prop != 0 && actlist.Count > 0) {
|
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;
|
if (index < 0) index = ~index;
|
||||||
}
|
}
|
||||||
else index++;
|
|
||||||
if (iter++ >= 16) throw new JudgePropagationException();
|
|
||||||
}
|
}
|
||||||
else index++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user