using Cryville.Common; using Cryville.Common.Pdt; using System; using System.Collections.Generic; using System.Reflection; using RBeatTime = Cryville.Crtr.BeatTime; namespace Cryville.Crtr { public abstract class PropOp : PdtOperator { internal PropOp() : base(1) { } public class Arbitrary : PropOp { public int Name { get; set; } protected override void Execute() { var op = GetOperand(0); var value = new byte[op.Length]; op.CopyTo(value, 0); ChartPlayer.etor.ContextCascadeUpdate(Name, new PropSrc.Arbitrary(op.Type, value)); } } public class Boolean : PropOp { readonly Action _cb; public Boolean(Action cb) { _cb = cb; } protected override void Execute() { _cb(GetOperand(0).AsNumber() > 0); } } public class Integer : PropOp { readonly Action _cb; public Integer(Action cb) { _cb = cb; } protected override void Execute() { _cb((int)GetOperand(0).AsNumber()); } } public class Float : PropOp { readonly Action _cb; public Float(Action cb) { _cb = cb; } protected override void Execute() { _cb(GetOperand(0).AsNumber()); } } public class String : PropOp { readonly Action _cb; public String(Action cb) { _cb = cb; } protected override void Execute() { _cb(GetOperand(0).AsString()); } } public class Identifier : PropOp { readonly Action _cb; public Identifier(Action cb) { _cb = cb; } protected override void Execute() { _cb(GetOperand(0).AsIdentifier()); } } public class Enum : PropOp { readonly static Dictionary _cache = new Dictionary(); readonly Action _cb; public Enum(Action cb) { if (!typeof(T).IsEnum) throw new ArgumentException("Type is not enum"); var names = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Static); for (int i = 0; i < names.Length; i++) _cache[IdentifierManager.SharedInstance.Request(names[i].Name)] = Convert.ToInt32(names[i].GetValue(null)); _cb = cb; } protected override void Execute() { int result = 0; for (int i = 0; i < LoadedOperandCount; i++) result |= _cache[GetOperand(0).AsIdentifier()]; _cb((T)(object)result); } } public class BeatTime : PropOp { readonly Action _cb; public BeatTime(Action cb) { _cb = cb; } protected override unsafe void Execute() { var o = GetOperand(0); _cb(*(RBeatTime*)o.TrustedAsOfLength(sizeof(RBeatTime))); } } public class Vector2 : PropOp { readonly Action _cb; public Vector2(Action cb) { _cb = cb; } protected override unsafe void Execute() { var o = GetOperand(0); switch ((o.Length - 4) / 4) { case 0: // Number case 1: // Array[1] float num = o.AsNumber(); _cb(new UnityEngine.Vector2(num, num)); break; case 2: _cb(*(UnityEngine.Vector2*)o.TrustedAsOfLength(sizeof(UnityEngine.Vector2))); break; default: throw new InvalidOperationException("Invalid array size"); } } } public class Vector3 : PropOp { readonly Action _cb; public Vector3(Action cb) { _cb = cb; } protected override unsafe void Execute() { var o = GetOperand(0); switch ((o.Length - 4) / 4) { case 0: // Number case 1: // Array[1] float num = o.AsNumber(); _cb(new UnityEngine.Vector3(num, num)); break; case 2: _cb(*(UnityEngine.Vector2*)o.TrustedAsOfLength(sizeof(UnityEngine.Vector2))); break; case 3: _cb(*(UnityEngine.Vector3*)o.TrustedAsOfLength(sizeof(UnityEngine.Vector3))); break; default: throw new InvalidOperationException("Invalid array size"); } } } public class Color : PropOp { readonly Action _cb; public Color(Action cb) { _cb = cb; } protected override unsafe void Execute() { var o = GetOperand(0); switch ((o.Length - 4) / 4) { case 3: var ptr = (float*)o.TrustedAsOfLength(sizeof(float) * 3); _cb(new UnityEngine.Color(ptr[0], ptr[1], ptr[2])); break; case 4: _cb(*(UnityEngine.Color*)o.TrustedAsOfLength(sizeof(UnityEngine.Color))); break; default: throw new InvalidOperationException("Invalid array size"); } } } } }