diff --git a/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs b/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs index d73caf7..124ef1d 100644 --- a/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs +++ b/Assets/Cryville/Common/Pdt/PdtEvaluatorBase.cs @@ -41,8 +41,10 @@ namespace Cryville.Common.Pdt { public void Optimize(PdtExpression exp) { _framecount = 0; _goffset = 0; + List ct; + var cols = new Dictionary, List>(); var il = exp.Instructions; - for (_rip = il.First; _rip != null; _rip = _rip.Next) { + for (_rip = il.First; _rip != null; _rip = _rip == null ? il.First : _rip.Next) { var i = _rip.Value; if (i is PdtInstruction.Operate) { int fc0 = _framecount; @@ -63,6 +65,33 @@ namespace Cryville.Common.Pdt { for (var j = 0; j <= fc1; j++) il.Remove(_rip.Previous); } } + else if (i is PdtInstruction.Collapse) { + var t = (PdtInstruction.Collapse)i; + try { + var pins = _rip; + i.Execute(this); + if (_rip == pins) { + _rip = _rip.Next; + il.Remove(_rip.Previous); + il.Remove(_rip.Previous); + _rip = _rip.Previous; + } + else { + _rip = pins.Previous; + while (_rip.Next != t.Target) il.Remove(_rip.Next); + il.Remove(_rip.Next); + if (cols.TryGetValue(t.Target, out ct)) { + foreach (var u in ct) u.Target = _rip; + cols.Remove(t.Target); + cols.Add(_rip, ct); + } + } + } + catch (Exception) { + if (cols.TryGetValue(t.Target, out ct)) ct.Add(t); + else cols.Add(t.Target, new List { t }); + } + } else if (i is PdtInstruction.PushVariable) { i.Execute(this); var frame = _stack[_framecount - 1]; @@ -72,6 +101,15 @@ namespace Cryville.Common.Pdt { } } else i.Execute(this); + if (_rip != null && cols.TryGetValue(_rip, out ct)) { + unsafe { + fixed (StackFrame* frame = &_stack[_framecount - 1]) { + frame->Type = PdtInternalType.Error; + frame->Offset = -1; + frame->Length = 0; + } + } + } } exp.IsConstant = true; exp.IsPotentialConstant = true; @@ -118,7 +156,10 @@ namespace Cryville.Common.Pdt { /// The value of the variable. protected abstract void GetVariable(string name, out int type, out byte[] value); internal void Operate(ref string name, int pc) { - Operate(GetOperator(name, pc), pc); + PdtOperator op; + try { op = GetOperator(name, pc); } + catch (Exception) { _framecount -= pc; return; } + Operate(op, pc); } /// /// Gets an operator of the specified name and the suggested parameter count. diff --git a/Assets/Cryville/Common/Pdt/PdtExpression.cs b/Assets/Cryville/Common/Pdt/PdtExpression.cs index 2da3b79..2750e00 100644 --- a/Assets/Cryville/Common/Pdt/PdtExpression.cs +++ b/Assets/Cryville/Common/Pdt/PdtExpression.cs @@ -80,7 +80,7 @@ namespace Cryville.Common.Pdt { public class Collapse : PdtInstruction { private string m_name; public string Name { get { return m_name; } } - public LinkedListNode Target { get; private set; } + public LinkedListNode Target { get; internal set; } public Collapse(string name, LinkedListNode target) { m_name = name; Target = target; @@ -195,6 +195,9 @@ namespace Cryville.Common.Pdt { default: pc++; break; } } + else if (OP_TYPE[t2.Value[0]] == 1) { + colp = new Dictionary, string> { { ins.Last, t2.Value } }; + } t1 = t2; break; case 0x0400: diff --git a/Assets/Cryville/Crtr/Ruleset.cs b/Assets/Cryville/Crtr/Ruleset.cs index 83f4370..85b2379 100644 --- a/Assets/Cryville/Crtr/Ruleset.cs +++ b/Assets/Cryville/Crtr/Ruleset.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Globalization; using System.IO; using System.Text; +using System.Xml.Linq; namespace Cryville.Crtr { public class Ruleset { @@ -35,6 +36,24 @@ namespace Cryville.Crtr { public Dictionary judges; public Dictionary scores; public Constraint constraints; + public void Optimize(PdtEvaluatorBase etor) { + foreach (var i in inputs.Values) { + if (i.pass != null) foreach (var e in i.pass.Values) { + etor.Optimize(e); + } + } + foreach (var j in judges.Values) { + if (j.clip != null) etor.Optimize(j.clip); + if (j.hit != null) etor.Optimize(j.hit); + if (j.scores != null) foreach (var e in j.scores.Values) { + etor.Optimize(e); + } + } + foreach (var s in scores.Values) { + if (s.value != null) etor.Optimize(s.value); + } + constraints.Optimize(etor); + } public void PrePatch(Chart chart) { constraints.PrePatch(chart); } @@ -54,6 +73,15 @@ namespace Cryville.Crtr { public Dictionary Elements = new Dictionary(); [PropertyList] public Dictionary Properties = new Dictionary(); + public void Optimize(PdtEvaluatorBase etor) { + foreach (var e in Properties.Values) { + etor.Optimize(e); + } + foreach (var e in Elements) { + e.Key.Optimize(etor); + e.Value.Optimize(etor); + } + } public void PrePatch(ChartEvent ev) { var etor = ChartPlayer.etor; PropSrc src; diff --git a/Assets/Cryville/Crtr/RulesetSelectors.cs b/Assets/Cryville/Crtr/RulesetSelectors.cs index 1468036..7a5ac63 100644 --- a/Assets/Cryville/Crtr/RulesetSelectors.cs +++ b/Assets/Cryville/Crtr/RulesetSelectors.cs @@ -1,9 +1,7 @@ using Cryville.Common.Pdt; -using Cryville.Crtr.Components; using System; using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; namespace Cryville.Crtr { public class RulesetSelectors { @@ -11,6 +9,11 @@ namespace Cryville.Crtr { public RulesetSelectors(IEnumerable s) { selectors = s.ToArray(); } + public void Optimize(PdtEvaluatorBase etor) { + for (int i = 0; i < selectors.Length; i++) { + selectors[i].Optimize(etor); + } + } public IEnumerable Match(ChartEvent ev) { IEnumerable result = new ChartEvent[] { ev }; foreach (var sel in selectors) { @@ -36,6 +39,7 @@ namespace Cryville.Crtr { } public abstract class RulesetSelector { + public virtual void Optimize(PdtEvaluatorBase etor) { } public abstract IEnumerable Match(ChartEvent ev); public class CreateItem : RulesetSelector { public override string ToString() { @@ -82,6 +86,9 @@ namespace Cryville.Crtr { public override string ToString() { return string.Format("> {{{0}}}", _exp); } + public override void Optimize(PdtEvaluatorBase etor) { + etor.Optimize(_exp); + } public override IEnumerable Match(ChartEvent ev) { ChartPlayer.etor.ContextEvent = ev; ChartPlayer.etor.Evaluate(_op, _exp);