using Cryville.Common; using Cryville.Common.Pdt; using System; using System.Collections.Generic; using System.Reflection; using RBeatTime = Cryville.Crtr.BeatTime; using RClip = Cryville.Crtr.Clip; using RColor = UnityEngine.Color; using RTargetString = Cryville.Common.Buffers.TargetString; using RVector2 = UnityEngine.Vector2; using RVector3 = UnityEngine.Vector3; namespace Cryville.Crtr { public abstract class PropOp : PdtOperator { protected PropOp() : base(1) { } protected PropOp(int pc) : base(pc) { } 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 Clip : PropOp { readonly Action _cb; public Clip(Action cb) : base(2) { _cb = cb; } protected override void Execute() { if (LoadedOperandCount < 2) throw new ArgumentException("Invalid clip syntax"); _cb(new RClip(GetOperand(0).AsNumber(), GetOperand(1).AsNumber())); } } 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 StringArray : PropOp { readonly Action _cb; public StringArray(Action cb) { _cb = cb; } protected unsafe override void Execute() { var op = GetOperand(0); int arrtype; int len; op.GetArraySuffix(out arrtype, out len); if (arrtype != PdtInternalType.String) throw new InvalidCastException("Not an array of strings"); var result = new string[len]; int o = 0; for (int i = 0; i < len; i++) { string v = op.AsString(o); o += v.Length * sizeof(char) + sizeof(int); result[i] = v; } _cb(result); } } public class TargetString : PropOp { readonly Func _cb; public TargetString(Func cb) { _cb = cb; } protected override void Execute() { var target = _cb(); var op = GetOperand(0); if (op.Type != PdtInternalType.String) throw new ArgumentException("Not a string"); int len = op.As(); target.Length = len; for (int i = 0; i < len; i++) target[i] = op.As(sizeof(int) + i * sizeof(char)); target.Validate(); } } 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; readonly Func _caster; public Enum(Action cb, Func caster) { 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; _caster = caster; } protected override void Execute() { int result = 0; for (int i = 0; i < LoadedOperandCount; i++) result |= _cache[GetOperand(0).AsIdentifier()]; _cb(_caster(result)); } } public class BeatTime : PropOp { readonly Action _cb; public BeatTime(Action cb) { _cb = cb; } protected override unsafe void Execute() { var o = GetOperand(0); _cb(o.As()); } } 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 RVector2(num, num)); break; case 2: _cb(o.As()); 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 RVector3(num, num)); break; case 2: _cb(o.As()); break; case 3: _cb(o.As()); 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: _cb(new RColor(o.As(), o.As(sizeof(float)), o.As(2 * sizeof(float)))); break; case 4: _cb(o.As()); break; default: throw new InvalidOperationException("Invalid array size"); } } } } }