Make the output type of a property source read-only.

This commit is contained in:
2023-01-16 20:53:45 +08:00
parent 9d6bdd968f
commit 5b9149cb34
8 changed files with 76 additions and 56 deletions

View File

@@ -6,11 +6,11 @@ namespace Cryville.Crtr {
public int Name { get; private set; }
public Transform Transform { get; private set; }
public SkinContext SkinContext { get; private set; }
public Dictionary<int, PropSrc.Arbitrary> PropSrcs { get; private set; }
public Dictionary<int, PropSrc> PropSrcs { get; private set; }
public Anchor(int name, Transform transform, bool hasProps = false) {
Name = name;
Transform = transform;
if (hasProps) PropSrcs = new Dictionary<int, PropSrc.Arbitrary>();
if (hasProps) PropSrcs = new Dictionary<int, PropSrc>();
SkinContext = new SkinContext(transform, PropSrcs);
}
}

View File

@@ -301,6 +301,8 @@ namespace Cryville.Crtr {
#pragma warning restore IDE1006
private void LoadFromString(string s) {
if (RelativeNode != null || AbsoluteValue != null)
throw new InvalidOperationException("The motion property can only be set at initialization");
Match m = Regex.Match(s, @"^(.+?)(#(\d+))?(@(.+?))?(\^(.+?))?(\*(.+?))?(:(.+))?$");
if (!m.Success) throw new ArgumentException("Invalid motion string format");
name = new Identifier(m.Groups[1].Value);
@@ -322,6 +324,10 @@ namespace Cryville.Crtr {
else {
AbsoluteValue = Vector.Construct(registry.Type, m.Groups[11].Value);
}
SubmitPropSrc("value", VectorSrc.Construct(() => {
if (RelativeNode != null) return RelativeNode.Value;
else return AbsoluteValue;
}));
}
public override string ToString() {
@@ -373,10 +379,6 @@ namespace Cryville.Crtr {
}
public Motion() {
SubmitPropSrc("value", new VectorSrc(() => {
if (RelativeNode != null) return RelativeNode.Value;
else return AbsoluteValue;
}));
SubmitPropOp("motion", new PropOp.String(v => motion = v));
SubmitPropOp("name", new PropOp.Identifier(v => {
var n = new Identifier(v);

View File

@@ -173,7 +173,7 @@ namespace Cryville.Crtr {
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>();
readonly Dictionary<ProxiedInputIdentifier, PropSrc.Arbitrary> _vecs = new Dictionary<ProxiedInputIdentifier, PropSrc.Arbitrary>();
readonly Dictionary<ProxiedInputIdentifier, PropSrc> _vecs = new Dictionary<ProxiedInputIdentifier, PropSrc>();
static readonly PropSrc.Arbitrary _nullsrc = new PropSrc.Arbitrary(PdtInternalType.Null, new byte[0]);
unsafe void OnInput(InputIdentifier id, InputVector vec) {
lock (_lock) {
@@ -214,7 +214,7 @@ namespace Cryville.Crtr {
}
else {
var pid = new ProxiedInputIdentifier { Source = id, Target = target };
PropSrc.Arbitrary fv, tv = _etor.ContextCascadeLookup(_var_value);
PropSrc fv, tv = _etor.ContextCascadeLookup(_var_value);
if (!_vecs.TryGetValue(pid, out fv)) fv = _nullsrc;
if (fv.Type != PdtInternalType.Null || tv.Type != PdtInternalType.Null) {
if (fv.Type == PdtInternalType.Null) _activeCounts[id.Source]++;

View File

@@ -252,7 +252,8 @@ namespace Cryville.Crtr {
readonly Func<string> _cb;
readonly ArrayPool<byte> _pool;
byte[] _buf;
public ScoreStringSrc(ArrayPool<byte> pool, Func<string> cb) {
public ScoreStringSrc(ArrayPool<byte> pool, Func<string> cb)
: base(PdtInternalType.String) {
_pool = pool;
_cb = cb;
}
@@ -263,7 +264,7 @@ namespace Cryville.Crtr {
_buf = null;
}
}
protected override unsafe int InternalGet() {
protected override unsafe void InternalGet() {
var src = _cb();
int strlen = src.Length;
buf = _pool.Rent(sizeof(int) + strlen * sizeof(char));
@@ -273,7 +274,6 @@ namespace Cryville.Crtr {
int i = 0;
foreach (var c in src) ptr[i++] = c;
}
return PdtInternalType.String;
}
}
#endregion

View File

@@ -351,6 +351,8 @@ namespace Cryville.Crtr {
public abstract class Vector : IComparable<Vector> {
public Vector() { }
public abstract byte Dimension { get; }
public abstract int CompareTo(Vector other);
public abstract void ApplyFrom(Vector parent);
@@ -392,6 +394,8 @@ namespace Cryville.Crtr {
Value = i;
}
public override byte Dimension { get { return 1; } }
public override int CompareTo(Vector other) {
return CompareTo((Vec1)other);
}
@@ -457,6 +461,8 @@ namespace Cryville.Crtr {
Value = i;
}
public override byte Dimension { get { return 1; } }
public override int CompareTo(Vector other) {
throw new NotImplementedException();
}
@@ -517,6 +523,8 @@ namespace Cryville.Crtr {
Value = i;
}
public override byte Dimension { get { return 1; } }
public override int CompareTo(Vector other) {
throw new NotImplementedException();
}
@@ -578,6 +586,8 @@ namespace Cryville.Crtr {
this.h = h;
}
public override byte Dimension { get { return 2; } }
public static void Parse(string s, out float? w, out float? h) {
string[] c = s.Split('+');
float rw = 0, rh = 0;
@@ -697,6 +707,8 @@ namespace Cryville.Crtr {
this.x = x; this.y = y; this.z = z;
}
public override byte Dimension { get { return 3; } }
public override int CompareTo(Vector other) {
throw new NotImplementedException();
}
@@ -773,6 +785,8 @@ namespace Cryville.Crtr {
this.xw = xw; this.xh = xh; this.yw = yw; this.yh = yh;
}
public override byte Dimension { get { return 4; } }
public override int CompareTo(Vector other) {
throw new NotImplementedException();
}
@@ -852,6 +866,8 @@ namespace Cryville.Crtr {
this.xw = xw; this.xh = xh; this.yw = yw; this.yh = yh; this.z = z;
}
public override byte Dimension { get { return 5; } }
public override int CompareTo(Vector other) {
throw new NotImplementedException();
}
@@ -925,19 +941,27 @@ namespace Cryville.Crtr {
}
}
public class VectorSrc : PropSrc {
readonly Func<Vector> _cb;
public VectorSrc(Func<Vector> cb) { _cb = cb; }
protected override unsafe int InternalGet() {
var arr = _cb().ToArray();
if (arr.Length == 1) {
public abstract class VectorSrc : PropSrc {
protected readonly Func<Vector> _cb;
public VectorSrc(Func<Vector> cb, int type) : base(type) { _cb = cb; }
public static VectorSrc Construct(Func<Vector> cb) {
if (cb().Dimension == 1) return new INumber(cb);
else return new IVector(cb);
}
class INumber : VectorSrc {
public INumber(Func<Vector> cb) : base(cb, PdtInternalType.Number) { }
protected override unsafe void InternalGet() {
var arr = _cb().ToArray();
buf = new byte[sizeof(float)];
fixed (byte* ptr = buf) {
*(float*)ptr = arr[0];
}
return PdtInternalType.Number;
}
else {
}
class IVector : VectorSrc {
public IVector(Func<Vector> cb) : base(cb, PdtInternalType.Vector) { }
protected override unsafe void InternalGet() {
var arr = _cb().ToArray();
buf = new byte[sizeof(float) * arr.Length + sizeof(int)];
fixed (byte* rptr = buf) {
var ptr = (float*)rptr;
@@ -946,7 +970,6 @@ namespace Cryville.Crtr {
}
*(int*)ptr = PdtInternalType.Number;
}
return PdtInternalType.Vector;
}
}
}

View File

@@ -32,7 +32,7 @@ namespace Cryville.Crtr {
}
else if (ContextState != null && ChartPlayer.motionRegistry.ContainsKey(id)) {
var vec = ContextState.GetRawValue(id);
new VectorSrc(() => vec).Get(out type, out value);
VectorSrc.Construct(() => vec).Get(out type, out value);
}
else if (ContextJudge != null && ContextJudge.TryGetScoreSrc(name, out prop)) {
prop.Get(out type, out value);
@@ -43,7 +43,7 @@ namespace Cryville.Crtr {
RevokePotentialConstant();
}
else {
PropSrc.Arbitrary result = ContextCascadeLookup(name);
PropSrc result = ContextCascadeLookup(name);
if (result != null) {
result.Get(out type, out value);
}
@@ -103,22 +103,22 @@ namespace Cryville.Crtr {
public Judge ContextJudge { private get; set; }
public PropSrc ContextSelfValue { private get; set; }
readonly Dictionary<int, PropSrc.Arbitrary>[] ContextCascade = new Dictionary<int, PropSrc.Arbitrary>[256];
readonly Dictionary<int, PropSrc>[] ContextCascade = new Dictionary<int, PropSrc>[256];
int _cascadeHeight;
public void ContextCascadeInsert() {
ContextCascade[_cascadeHeight++].Clear();
}
public void ContextCascadeInsert(Dictionary<int, PropSrc.Arbitrary> srcs) {
public void ContextCascadeInsert(Dictionary<int, PropSrc> srcs) {
ContextCascadeInsert();
foreach (var src in srcs) ContextCascadeUpdate(src.Key, src.Value);
}
public void ContextCascadeUpdate(int key, PropSrc.Arbitrary value) {
public void ContextCascadeUpdate(int key, PropSrc value) {
ContextCascade[_cascadeHeight - 1][key] = value;
}
public PropSrc.Arbitrary ContextCascadeLookup(int name) {
PropSrc.Arbitrary result;
public PropSrc ContextCascadeLookup(int name) {
PropSrc result;
for (int i = _cascadeHeight - 1; i >= 0; i--) {
Dictionary<int, PropSrc.Arbitrary> cas = ContextCascade[i];
Dictionary<int, PropSrc> cas = ContextCascade[i];
if (cas.TryGetValue(name, out result)) {
return result;
}
@@ -130,7 +130,7 @@ namespace Cryville.Crtr {
}
public PdtEvaluator() {
for (int i = 0; i < ContextCascade.Length; i++) ContextCascade[i] = new Dictionary<int, PropSrc.Arbitrary>();
for (int i = 0; i < ContextCascade.Length; i++) ContextCascade[i] = new Dictionary<int, PropSrc>();
_ctxops.Add(IdentifierManager.SharedInstance.Request("screen_edge"), new func_screen_edge(() => ContextTransform));
_ctxops.Add(IdentifierManager.SharedInstance.Request("int"), new func_int(() => ContextSelfValue));

View File

@@ -4,26 +4,26 @@ using RBeatTime = Cryville.Crtr.BeatTime;
namespace Cryville.Crtr {
public abstract class PropSrc {
int _type;
public int Type { get; private set; }
public PropSrc(int type) {
Type = type;
}
protected byte[] buf = null;
protected virtual bool Invalidated { get { return buf == null; } }
public virtual void Invalidate() { buf = null; }
public void Get(out int type, out byte[] value) {
if (Invalidated) _type = InternalGet();
type = _type;
if (Invalidated) InternalGet();
type = Type;
value = buf;
}
protected abstract int InternalGet();
protected abstract void InternalGet();
public class Arbitrary : PropSrc {
public int Type { get; private set; }
readonly byte[] _value;
public Arbitrary(int type, byte[] value) {
Type = type;
public Arbitrary(int type, byte[] value) : base(type) {
_value = value;
}
protected override int InternalGet() {
protected override void InternalGet() {
buf = _value;
return Type;
}
}
public class Boolean : PropSrc {
@@ -31,11 +31,10 @@ namespace Cryville.Crtr {
bool m_invalidated = true;
protected override bool Invalidated { get { return m_invalidated; } }
public override void Invalidate() { m_invalidated = true; }
public Boolean(Func<bool> cb) { _cb = cb; buf = new byte[4]; }
protected override int InternalGet() {
public Boolean(Func<bool> cb) : base(PdtInternalType.Number) { _cb = cb; buf = new byte[4]; }
protected override void InternalGet() {
m_invalidated = false;
buf[0] = _cb() ? (byte)1 : (byte)0;
return PdtInternalType.Number;
}
}
public class Float : PropSrc {
@@ -43,19 +42,18 @@ namespace Cryville.Crtr {
bool m_invalidated = true;
protected override bool Invalidated { get { return m_invalidated; } }
public override void Invalidate() { m_invalidated = true; }
public Float(Func<float> cb) { _cb = cb; buf = new byte[4]; }
protected override unsafe int InternalGet() {
public Float(Func<float> cb) : base(PdtInternalType.Number) { _cb = cb; buf = new byte[4]; }
protected override unsafe void InternalGet() {
m_invalidated = false;
fixed (byte* _ptr = buf) {
*(float*)_ptr = _cb();
}
return PdtInternalType.Number;
}
}
public class String : PropSrc {
readonly Func<string> _cb;
public String(Func<string> cb) { _cb = cb; }
protected override unsafe int InternalGet() {
public String(Func<string> cb) : base(PdtInternalType.String) { _cb = cb; }
protected override unsafe void InternalGet() {
var v = _cb();
int strlen = v.Length;
buf = new byte[strlen * sizeof(char) + sizeof(int)];
@@ -65,21 +63,19 @@ namespace Cryville.Crtr {
int i = 0;
foreach (var c in v) ptr[i++] = c;
}
return PdtInternalType.String;
}
}
public class Identifier : PropSrc {
readonly Func<int> _cb;
public Identifier(Func<int> cb) { _cb = cb; }
protected override int InternalGet() {
public Identifier(Func<int> cb) : base(PdtInternalType.Undefined) { _cb = cb; }
protected override void InternalGet() {
buf = BitConverter.GetBytes(_cb());
return PdtInternalType.Undefined;
}
}
public class BeatTime : PropSrc {
readonly Func<RBeatTime> _cb;
public BeatTime(Func<RBeatTime> cb) { _cb = cb; }
protected override unsafe int InternalGet() {
public BeatTime(Func<RBeatTime> cb) : base(PdtInternalType.Vector) { _cb = cb; }
protected override unsafe void InternalGet() {
var bt = _cb();
buf = new byte[4 * sizeof(int)];
fixed (byte* _ptr = buf) {
@@ -89,7 +85,6 @@ namespace Cryville.Crtr {
*ptr++ = bt.d;
*ptr++ = PdtInternalType.Number;
}
return PdtInternalType.Vector;
}
}
}

View File

@@ -133,8 +133,8 @@ namespace Cryville.Crtr {
}
public class SkinContext {
public Transform Transform { get; private set; }
public Dictionary<int, PropSrc.Arbitrary> PropSrcs { get; private set; }
public SkinContext(Transform transform, Dictionary<int, PropSrc.Arbitrary> propSrcs = null) {
public Dictionary<int, PropSrc> PropSrcs { get; private set; }
public SkinContext(Transform transform, Dictionary<int, PropSrc> propSrcs = null) {
Transform = transform;
PropSrcs = propSrcs;
}
@@ -160,7 +160,7 @@ namespace Cryville.Crtr {
WriteTransform = newctx.Transform;
}
else {
ReadContext = newctx;
ReadContext = newctx;
WriteTransform = newctx.Transform;
}
}