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 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 : 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) : base(PdtInternalType.Number) { _cb = cb; buf = new byte[4]; } protected override void InternalGet() { m_invalidated = false; buf[0] = _cb() ? (byte)1 : (byte)0; } } 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) : base(PdtInternalType.Number) { _cb = cb; buf = new byte[4]; } protected override unsafe void InternalGet() { m_invalidated = false; fixed (byte* _ptr = buf) { *(float*)_ptr = _cb(); } } } 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 : PropSrc { readonly Func _cb; public Identifier(Func cb) : base(PdtInternalType.Undefined) { _cb = cb; } protected override void InternalGet() { buf = BitConverter.GetBytes(_cb()); } } public class BeatTime : PropSrc { readonly Func _cb; public BeatTime(Func cb) : base(PdtInternalType.Vector) { _cb = cb; } protected override unsafe void 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; } } } } }