Optimize GC for input proxy.
This commit is contained in:
@@ -5,7 +5,7 @@ using Cryville.Crtr.Config;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using UnityEngine;
|
||||
using RVector3 = UnityEngine.Vector3;
|
||||
|
||||
namespace Cryville.Crtr {
|
||||
public class InputProxy : IDisposable {
|
||||
@@ -13,12 +13,11 @@ namespace Cryville.Crtr {
|
||||
readonly PdtRuleset _ruleset;
|
||||
readonly Judge _judge;
|
||||
public InputProxy(PdtRuleset ruleset, Judge judge) {
|
||||
unsafe {
|
||||
fixed (byte* ptr = _vecbuf) {
|
||||
*(int*)(ptr + 3 * sizeof(float)) = PdtInternalType.Number;
|
||||
}
|
||||
for (int i = 0; i <= MAX_DEPTH; i++) {
|
||||
var vecsrc = new InputVectorSrc();
|
||||
_vecsrcs[i] = vecsrc;
|
||||
_vecops[i] = new InputVectorOp(vecsrc);
|
||||
}
|
||||
_vecsrc = new PropSrc.Arbitrary(PdtInternalType.Vector, _vecbuf);
|
||||
_etor = ChartPlayer.etor;
|
||||
_ruleset = ruleset;
|
||||
_judge = judge;
|
||||
@@ -175,9 +174,54 @@ namespace Cryville.Crtr {
|
||||
|
||||
readonly object _lock = new object();
|
||||
static readonly int _var_value = IdentifierManager.SharedInstance.Request("value");
|
||||
static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary();
|
||||
readonly byte[] _vecbuf = new byte[3 * sizeof(float) + sizeof(int)];
|
||||
readonly PropSrc.Arbitrary _vecsrc;
|
||||
const int MAX_DEPTH = 15;
|
||||
const int MAX_DIMENSION = 3;
|
||||
readonly InputVectorSrc[] _vecsrcs = new InputVectorSrc[MAX_DEPTH + 1];
|
||||
readonly InputVectorOp[] _vecops = new InputVectorOp[MAX_DEPTH + 1];
|
||||
unsafe class InputVectorSrc : PropSrc.FixedBuffer {
|
||||
public InputVectorSrc() : base(PdtInternalType.Vector, MAX_DIMENSION * sizeof(float) + sizeof(int)) {
|
||||
fixed (byte* ptr = buf) {
|
||||
*(int*)(ptr + MAX_DIMENSION * sizeof(float)) = PdtInternalType.Number;
|
||||
}
|
||||
}
|
||||
public bool IsNull { get; set; }
|
||||
public void Set(RVector3 vec) {
|
||||
fixed (byte* _ptr = buf) {
|
||||
*(RVector3*)_ptr = vec;
|
||||
}
|
||||
Invalidate();
|
||||
}
|
||||
}
|
||||
class InputVectorOp : PropOp {
|
||||
readonly InputVectorSrc _src;
|
||||
public InputVectorOp(InputVectorSrc src) {
|
||||
_src = src;
|
||||
}
|
||||
protected override void Execute() {
|
||||
var op = GetOperand(0);
|
||||
if (op.Type == PdtInternalType.Null) {
|
||||
_src.IsNull = true;
|
||||
}
|
||||
else {
|
||||
var vec = new RVector3();
|
||||
int dim;
|
||||
if (op.Type == PdtInternalType.Number) dim = 1;
|
||||
else if (op.Type == PdtInternalType.Vector) {
|
||||
int arrtype, _;
|
||||
op.GetArraySuffix(out arrtype, out _);
|
||||
if (arrtype != PdtInternalType.Number)
|
||||
throw new InvalidCastException("Not a vector of numbers");
|
||||
dim = Math.Min(3, (op.Length - sizeof(int)) / sizeof(float));
|
||||
}
|
||||
else throw new InvalidCastException("Invalid vector");
|
||||
for (int i = 0; i < dim; i++) {
|
||||
vec[i] = op.AsNumber(i * sizeof(float));
|
||||
}
|
||||
_src.IsNull = false;
|
||||
_src.Set(vec);
|
||||
}
|
||||
}
|
||||
}
|
||||
readonly Dictionary<InputHandler, double> _timeOrigins = new Dictionary<InputHandler, double>();
|
||||
readonly Dictionary<InputSource, int> _activeCounts = new Dictionary<InputSource, int>();
|
||||
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
||||
@@ -195,11 +239,8 @@ namespace Cryville.Crtr {
|
||||
OnInput(id, proxy.Target, ft, tt, true);
|
||||
}
|
||||
else {
|
||||
fixed (byte* ptr = _vecbuf) {
|
||||
*(Vector3*)ptr = vec.Vector;
|
||||
}
|
||||
_vecsrc.Invalidate();
|
||||
_etor.ContextCascadeUpdate(_var_value, _vecsrc);
|
||||
_vecsrcs[0].Set(vec.Vector);
|
||||
_etor.ContextCascadeUpdate(_var_value, _vecsrcs[0]);
|
||||
OnInput(id, proxy.Target, ft, tt, false);
|
||||
}
|
||||
_vect[id] = tt;
|
||||
@@ -210,14 +251,19 @@ namespace Cryville.Crtr {
|
||||
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
|
||||
static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv");
|
||||
unsafe void OnInput(InputIdentifier id, Identifier target, float ft, float tt, bool nullflag, int depth = 0) {
|
||||
if (depth >= 16) throw new InputProxyException("Input propagation limit reached\nThe ruleset has invalid input definitions");
|
||||
if (depth >= MAX_DEPTH) throw new InputProxyException("Input propagation limit reached\nThe ruleset has invalid input definitions");
|
||||
var def = _ruleset.inputs[target];
|
||||
if (def.pass != null) {
|
||||
foreach (var p in def.pass) {
|
||||
_etor.ContextCascadeInsert();
|
||||
_arbop.Name = _var_value;
|
||||
if (!nullflag) _etor.Evaluate(_arbop, p.Value);
|
||||
OnInput(id, p.Key, ft, tt, nullflag, depth + 1);
|
||||
bool newNullFlag = nullflag;
|
||||
if (!newNullFlag) {
|
||||
ChartPlayer.etor.Evaluate(_vecops[depth + 1], p.Value);
|
||||
newNullFlag = _vecsrcs[depth + 1].IsNull;
|
||||
if (newNullFlag) ChartPlayer.etor.ContextCascadeUpdate(_var_value, PropSrc.Null);
|
||||
else ChartPlayer.etor.ContextCascadeUpdate(_var_value, _vecsrcs[depth + 1]);
|
||||
}
|
||||
OnInput(id, p.Key, ft, tt, newNullFlag, depth + 1);
|
||||
_etor.ContextCascadeDiscard();
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user