Files
crtr/Assets/Cryville/Crtr/PropOp.cs
2022-09-30 17:32:21 +08:00

116 lines
3.5 KiB
C#

using Cryville.Common.Pdt;
using System;
using System.Collections.Generic;
using System.Reflection;
namespace Cryville.Crtr {
public abstract class PropOp : PdtOperator {
internal PropOp() : base(1) { }
public class Boolean : PropOp {
readonly Action<bool> _cb;
public Boolean(Action<bool> cb) { _cb = cb; }
protected override void Execute() {
_cb(GetOperand(0).AsNumber() != 0);
}
}
public class Integer : PropOp {
readonly Action<int> _cb;
public Integer(Action<int> cb) { _cb = cb; }
protected override void Execute() {
_cb((int)GetOperand(0).AsNumber());
}
}
public class Float : PropOp {
readonly Action<float> _cb;
public Float(Action<float> cb) { _cb = cb; }
protected override void Execute() {
_cb(GetOperand(0).AsNumber());
}
}
public class String : PropOp {
readonly Action<string> _cb;
public String(Action<string> cb) { _cb = cb; }
protected override void Execute() {
_cb(GetOperand(0).AsString());
}
}
public class Enum<T> : PropOp {
readonly static Dictionary<string, int> _cache = new Dictionary<string, int>();
readonly Action<T> _cb;
public Enum(Action<T> 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[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 Vector2 : PropOp {
readonly Action<UnityEngine.Vector2> _cb;
public Vector2(Action<UnityEngine.Vector2> 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<UnityEngine.Vector3> _cb;
public Vector3(Action<UnityEngine.Vector3> 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<UnityEngine.Color> _cb;
public Color(Action<UnityEngine.Color> 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");
}
}
}
}
}