Dashboard/Quik/CommandQueue/Frame.cs

212 lines
6.1 KiB
C#

using System.Runtime.InteropServices;
namespace Quik.CommandQueue
{
[StructLayout(LayoutKind.Explicit)]
public struct Frame
{
[FieldOffset(0)]
private FrameType _type;
[FieldOffset(sizeof(FrameType) + 0*sizeof(int))]
private int _i1;
[FieldOffset(sizeof(FrameType) + 1*sizeof(int))]
private int _i2;
[FieldOffset(sizeof(FrameType) + 2*sizeof(int))]
private int _i3;
[FieldOffset(sizeof(FrameType) + 3*sizeof(int))]
private int _i4;
[FieldOffset(sizeof(FrameType) + 0*sizeof(float))]
private float _f1;
[FieldOffset(sizeof(FrameType) + 1*sizeof(float))]
private float _f2;
[FieldOffset(sizeof(FrameType) + 2*sizeof(float))]
private float _f3;
[FieldOffset(sizeof(FrameType) + 3*sizeof(float))]
private float _f4;
[FieldOffset(sizeof(FrameType))]
private object _object;
public bool IsCommand => _type == FrameType.Command;
public bool IsInteger =>
_type == FrameType.IVec1 ||
_type == FrameType.IVec2 ||
_type == FrameType.IVec3 ||
_type == FrameType.IVec4;
public bool IsFloat =>
_type == FrameType.IVec1 ||
_type == FrameType.IVec2 ||
_type == FrameType.IVec3 ||
_type == FrameType.IVec4;
public int VectorSize
{
get
{
switch (_type)
{
case FrameType.None:
return 0;
default:
return 1;
case FrameType.Vec2: case FrameType.IVec2:
return 2;
case FrameType.Vec3: case FrameType.IVec3:
return 3;
case FrameType.Vec4: case FrameType.IVec4:
return 4;
}
}
}
public static Frame None { get; } = new Frame() {
_type = FrameType.None
};
public Frame(Command command) : this((int)command)
{
}
public Frame(object o)
{
_type = FrameType.Object;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_object = o;
}
public Frame(int i1)
{
_type = FrameType.IVec1;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_i1 = i1;
}
public Frame(int i1, int i2)
{
_type = FrameType.IVec2;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_i1 = i1;
_i2 = i2;
}
public Frame(int i1, int i2, int i3)
{
_type = FrameType.IVec3;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_i1 = i1;
_i2 = i2;
_i3 = i3;
}
public Frame(int i1, int i2, int i3, int i4)
{
_type = FrameType.IVec4;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_i1 = i1;
_i2 = i2;
_i3 = i3;
_i4 = i4;
}
public Frame(float f1)
{
_type = FrameType.Vec1;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_f1 = f1;
}
public Frame(float f1, float f2)
{
_type = FrameType.Vec2;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_f1 = f1;
_f2 = f2;
}
public Frame(float f1, float f2, float f3)
{
_type = FrameType.Vec3;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_f1 = f1;
_f2 = f2;
_f3 = f3;
}
public Frame(float f1, float f2, float f3, float f4)
{
_type = FrameType.Vec4;
_i1 = _i2 = _i3 = _i4 = default;
_f1 = _f2 = _f3 = _f4 = default;
_object = null;
_f1 = f1;
_f2 = f2;
_f3 = f3;
_f4 = f4;
}
public T As<T>() where T : class
{
return (T)_object;
}
public static implicit operator int(in Frame frame) => frame._i1;
public static implicit operator float(in Frame frame) => frame._f1;
public static implicit operator Command(in Frame frame) => (Command)frame._i1;
public static explicit operator Frame(int i) => new Frame(i);
public static explicit operator Frame(float f) => new Frame(f);
public static implicit operator Frame(Command cmd) => new Frame(cmd);
public static implicit operator Frame(in QuikVec2 vector) => new Frame(vector.X, vector.Y);
public static implicit operator Frame(in QuikColor color) => new Frame(color.R, color.G, color.B, color.A);
public static implicit operator Frame(in QuikRectangle rect) => new Frame(rect.Min.X, rect.Min.Y, rect.Max.X, rect.Max.Y);
public static implicit operator Frame(in QuikLine line) => new Frame(line.Start.X, line.Start.Y, line.End.X, line.Start.Y);
public static void Create(in QuikBezier bezier, out Frame a, out Frame b)
{
a = new Frame(bezier.Start.X, bezier.Start.Y, bezier.End.X, bezier.End.Y);
b = new Frame(bezier.ControlA.X, bezier.ControlA.Y, bezier.ControlB.X, bezier.ControlB.Y);
}
public static void Create(in QuikEllipse ellipse, out Frame a, out Frame b)
{
a = new Frame(ellipse.Center.X, ellipse.Center.Y);
b = new Frame(ellipse.AxisA.X, ellipse.AxisA.Y, ellipse.AxisB.X, ellipse.AxisB.Y);
}
}
}