using Cryville.Common.Pdt; using System; using RBeatTime = Cryville.Crtr.BeatTime; namespace Cryville.Crtr { public abstract class PropSrc { int _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; value = buf; } protected abstract int InternalGet(); public class Arbitrary : PropSrc { public int Type { get; private set; } readonly byte[] _value; public Arbitrary(int type, byte[] value) { Type = type; _value = value; } protected override int InternalGet() { buf = _value; return Type; } } public class Boolean : PropSrc { readonly Func _cb; bool m_invalidated = true; protected override bool Invalidated { get { return m_invalidated; } } public override void Invalidate() { m_invalidated = true; } public Boolean(Func cb) { _cb = cb; buf = new byte[4]; } protected override int InternalGet() { m_invalidated = false; buf[0] = _cb() ? (byte)1 : (byte)0; return PdtInternalType.Number; } } public class Float : PropSrc { readonly Func _cb; bool m_invalidated = true; protected override bool Invalidated { get { return m_invalidated; } } public override void Invalidate() { m_invalidated = true; } public Float(Func cb) { _cb = cb; buf = new byte[4]; } protected override unsafe int InternalGet() { m_invalidated = false; fixed (byte* _ptr = buf) { *(float*)_ptr = _cb(); } return PdtInternalType.Number; } } public class String : PropSrc { readonly Func _cb; public String(Func cb) { _cb = cb; } protected override unsafe int InternalGet() { var v = _cb(); int strlen = v.Length; buf = new byte[strlen * sizeof(char) + sizeof(int)]; fixed (byte* _ptr = buf) { char* ptr = (char*)(_ptr + sizeof(int)); *(int*)_ptr = strlen; int i = 0; foreach (var c in v) ptr[i++] = c; } return PdtInternalType.String; } } public class Identifier : PropSrc { readonly Func _cb; public Identifier(Func cb) { _cb = cb; } protected override int InternalGet() { buf = BitConverter.GetBytes(_cb()); return PdtInternalType.Undefined; } } public class BeatTime : PropSrc { readonly Func _cb; public BeatTime(Func cb) { _cb = cb; } protected override unsafe int InternalGet() { var bt = _cb(); buf = new byte[4 * sizeof(int)]; fixed (byte* _ptr = buf) { int* ptr = (int*)_ptr; *ptr++ = bt.b; *ptr++ = bt.n; *ptr++ = bt.d; *ptr++ = PdtInternalType.Number; } return PdtInternalType.Vector; } } } }