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