Optimize GC for input proxy.
This commit is contained in:
@@ -5,7 +5,7 @@ using Cryville.Crtr.Config;
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
using UnityEngine;
|
using RVector3 = UnityEngine.Vector3;
|
||||||
|
|
||||||
namespace Cryville.Crtr {
|
namespace Cryville.Crtr {
|
||||||
public class InputProxy : IDisposable {
|
public class InputProxy : IDisposable {
|
||||||
@@ -13,12 +13,11 @@ namespace Cryville.Crtr {
|
|||||||
readonly PdtRuleset _ruleset;
|
readonly PdtRuleset _ruleset;
|
||||||
readonly Judge _judge;
|
readonly Judge _judge;
|
||||||
public InputProxy(PdtRuleset ruleset, Judge judge) {
|
public InputProxy(PdtRuleset ruleset, Judge judge) {
|
||||||
unsafe {
|
for (int i = 0; i <= MAX_DEPTH; i++) {
|
||||||
fixed (byte* ptr = _vecbuf) {
|
var vecsrc = new InputVectorSrc();
|
||||||
*(int*)(ptr + 3 * sizeof(float)) = PdtInternalType.Number;
|
_vecsrcs[i] = vecsrc;
|
||||||
}
|
_vecops[i] = new InputVectorOp(vecsrc);
|
||||||
}
|
}
|
||||||
_vecsrc = new PropSrc.Arbitrary(PdtInternalType.Vector, _vecbuf);
|
|
||||||
_etor = ChartPlayer.etor;
|
_etor = ChartPlayer.etor;
|
||||||
_ruleset = ruleset;
|
_ruleset = ruleset;
|
||||||
_judge = judge;
|
_judge = judge;
|
||||||
@@ -175,9 +174,54 @@ namespace Cryville.Crtr {
|
|||||||
|
|
||||||
readonly object _lock = new object();
|
readonly object _lock = new object();
|
||||||
static readonly int _var_value = IdentifierManager.SharedInstance.Request("value");
|
static readonly int _var_value = IdentifierManager.SharedInstance.Request("value");
|
||||||
static readonly PropOp.Arbitrary _arbop = new PropOp.Arbitrary();
|
const int MAX_DEPTH = 15;
|
||||||
readonly byte[] _vecbuf = new byte[3 * sizeof(float) + sizeof(int)];
|
const int MAX_DIMENSION = 3;
|
||||||
readonly PropSrc.Arbitrary _vecsrc;
|
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<InputHandler, double> _timeOrigins = new Dictionary<InputHandler, double>();
|
||||||
readonly Dictionary<InputSource, int> _activeCounts = new Dictionary<InputSource, int>();
|
readonly Dictionary<InputSource, int> _activeCounts = new Dictionary<InputSource, int>();
|
||||||
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
readonly Dictionary<InputIdentifier, float> _vect = new Dictionary<InputIdentifier, float>();
|
||||||
@@ -195,11 +239,8 @@ namespace Cryville.Crtr {
|
|||||||
OnInput(id, proxy.Target, ft, tt, true);
|
OnInput(id, proxy.Target, ft, tt, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fixed (byte* ptr = _vecbuf) {
|
_vecsrcs[0].Set(vec.Vector);
|
||||||
*(Vector3*)ptr = vec.Vector;
|
_etor.ContextCascadeUpdate(_var_value, _vecsrcs[0]);
|
||||||
}
|
|
||||||
_vecsrc.Invalidate();
|
|
||||||
_etor.ContextCascadeUpdate(_var_value, _vecsrc);
|
|
||||||
OnInput(id, proxy.Target, ft, tt, false);
|
OnInput(id, proxy.Target, ft, tt, false);
|
||||||
}
|
}
|
||||||
_vect[id] = tt;
|
_vect[id] = tt;
|
||||||
@@ -210,14 +251,19 @@ namespace Cryville.Crtr {
|
|||||||
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
|
static readonly int _var_fv = IdentifierManager.SharedInstance.Request("fv");
|
||||||
static readonly int _var_tv = IdentifierManager.SharedInstance.Request("tv");
|
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) {
|
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];
|
var def = _ruleset.inputs[target];
|
||||||
if (def.pass != null) {
|
if (def.pass != null) {
|
||||||
foreach (var p in def.pass) {
|
foreach (var p in def.pass) {
|
||||||
_etor.ContextCascadeInsert();
|
_etor.ContextCascadeInsert();
|
||||||
_arbop.Name = _var_value;
|
bool newNullFlag = nullflag;
|
||||||
if (!nullflag) _etor.Evaluate(_arbop, p.Value);
|
if (!newNullFlag) {
|
||||||
OnInput(id, p.Key, ft, tt, nullflag, depth + 1);
|
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();
|
_etor.ContextCascadeDiscard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user