Add invalid cast exceptions to frame conversion operators.

This commit is contained in:
H. Utku Maden 2024-04-09 10:50:52 +03:00
parent 4dff6eba91
commit 09ce8d3229

@ -9,22 +9,22 @@ namespace Quik.CommandMachine
[FieldOffset(0)] [FieldOffset(0)]
private FrameType _type; private FrameType _type;
[FieldOffset(sizeof(FrameType) + 0*sizeof(int))] [FieldOffset(sizeof(FrameType) + 0 * sizeof(int))]
private int _i1; private int _i1;
[FieldOffset(sizeof(FrameType) + 1*sizeof(int))] [FieldOffset(sizeof(FrameType) + 1 * sizeof(int))]
private int _i2; private int _i2;
[FieldOffset(sizeof(FrameType) + 2*sizeof(int))] [FieldOffset(sizeof(FrameType) + 2 * sizeof(int))]
private int _i3; private int _i3;
[FieldOffset(sizeof(FrameType) + 3*sizeof(int))] [FieldOffset(sizeof(FrameType) + 3 * sizeof(int))]
private int _i4; private int _i4;
[FieldOffset(sizeof(FrameType) + 0*sizeof(float))] [FieldOffset(sizeof(FrameType) + 0 * sizeof(float))]
private float _f1; private float _f1;
[FieldOffset(sizeof(FrameType) + 1*sizeof(float))] [FieldOffset(sizeof(FrameType) + 1 * sizeof(float))]
private float _f2; private float _f2;
[FieldOffset(sizeof(FrameType) + 2*sizeof(float))] [FieldOffset(sizeof(FrameType) + 2 * sizeof(float))]
private float _f3; private float _f3;
[FieldOffset(sizeof(FrameType) + 3*sizeof(float))] [FieldOffset(sizeof(FrameType) + 3 * sizeof(float))]
private float _f4; private float _f4;
[FieldOffset(24)] [FieldOffset(24)]
@ -36,7 +36,7 @@ namespace Quik.CommandMachine
_type == FrameType.IVec2 || _type == FrameType.IVec2 ||
_type == FrameType.IVec3 || _type == FrameType.IVec3 ||
_type == FrameType.IVec4; _type == FrameType.IVec4;
public bool IsFloat => public bool IsFloat =>
_type == FrameType.Vec1 || _type == FrameType.Vec1 ||
_type == FrameType.Vec2 || _type == FrameType.Vec2 ||
_type == FrameType.Vec3 || _type == FrameType.Vec3 ||
@ -48,16 +48,16 @@ namespace Quik.CommandMachine
{ {
switch (_type) switch (_type)
{ {
case FrameType.None: case FrameType.None:
return 0; return 0;
default: default:
return 1; return 1;
case FrameType.Vec2: case FrameType.IVec2: case FrameType.Vec2: case FrameType.IVec2:
return 2; return 2;
case FrameType.Vec3: case FrameType.IVec3: case FrameType.Vec3: case FrameType.IVec3:
return 3; return 3;
case FrameType.Vec4: case FrameType.IVec4: case FrameType.Vec4: case FrameType.IVec4:
return 4; return 4;
} }
} }
} }
@ -78,10 +78,11 @@ namespace Quik.CommandMachine
_type = FrameType.None _type = FrameType.None
}; };
#region Constructors
public Frame(Command command) : this() public Frame(Command command) : this()
{ {
_type = FrameType.Command; _type = FrameType.Command;
_i1 = (int)command; _i1 = (int)command;
} }
public Frame(object o) public Frame(object o)
@ -195,6 +196,8 @@ namespace Quik.CommandMachine
_f4 = f4; _f4 = f4;
} }
#endregion
public T As<T>() public T As<T>()
{ {
return (T)_object; return (T)_object;
@ -204,12 +207,12 @@ namespace Quik.CommandMachine
{ {
switch (i) switch (i)
{ {
case 0: return _f1; case 0: return _f1;
case 1: return _f2; case 1: return _f2;
case 2: return _f3; case 2: return _f3;
case 3: return _f4; case 3: return _f4;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
} }
@ -217,30 +220,118 @@ namespace Quik.CommandMachine
{ {
switch (i) switch (i)
{ {
case 0: return _i1; case 0: return _i1;
case 1: return _i2; case 1: return _i2;
case 2: return _i3; case 2: return _i3;
case 3: return _i4; case 3: return _i4;
default: default:
throw new ArgumentOutOfRangeException(); throw new ArgumentOutOfRangeException();
} }
} }
public static explicit operator int(in Frame frame) => frame._i1; #region Frame->T Conversion
public static explicit operator float(in Frame frame) => frame._f1;
public static explicit operator Command(in Frame frame) => (Command)frame._i1; public static explicit operator int(in Frame frame)
public static explicit operator QVec2(in Frame frame) => {
frame.IsFloat ? new QVec2(frame._f1, frame._f2) : new QVec2(frame._i1, frame._i2); switch (frame.Type)
public static explicit operator QColor(in Frame frame) => {
new QColor((byte)frame._i1, (byte)frame._i2, (byte)frame._i3, (byte)frame._i4); default:
public static explicit operator QRectangle(in Frame frame) => throw new InvalidCastException();
frame.IsFloat ? case FrameType.Command:
new QRectangle(frame._f1, frame._f2, frame._f3, frame._f4) : case FrameType.IVec1:
new QRectangle(frame._i1, frame._i2, frame._i3, frame._i4); case FrameType.IVec2:
public static explicit operator QLine(in Frame frame) => case FrameType.IVec3:
frame.IsFloat ? case FrameType.IVec4:
new QLine(frame._f1, frame._f2, frame._f3, frame._f4) : return frame._i1;
new QLine(frame._i1, frame._i2, frame._i3, frame._i4); case FrameType.Vec1:
case FrameType.Vec2:
case FrameType.Vec3:
case FrameType.Vec4:
return (int)frame._f1;
}
}
public static explicit operator float(in Frame frame)
{
switch (frame.Type)
{
default:
throw new InvalidCastException();
case FrameType.IVec1:
case FrameType.IVec2:
case FrameType.IVec3:
case FrameType.IVec4:
return frame._i1;
case FrameType.Vec1:
case FrameType.Vec2:
case FrameType.Vec3:
case FrameType.Vec4:
return frame._f1;
}
}
public static explicit operator Command(in Frame frame)
{
if (frame.Type != FrameType.Command)
{
throw new InvalidCastException("Not a command frame.");
}
return (Command)frame._i1;
}
public static explicit operator QVec2(in Frame frame)
{
switch (frame.Type)
{
default:
throw new InvalidCastException();
case FrameType.IVec2:
case FrameType.IVec3:
case FrameType.IVec4:
return new QVec2(frame._i1, frame._i2);
case FrameType.Vec2:
case FrameType.Vec3:
case FrameType.Vec4:
return new QVec2(frame._f1, frame._f2);
}
}
public static explicit operator QColor(in Frame frame)
{
if (frame.Type != FrameType.IVec4)
throw new InvalidCastException();
return new QColor((byte)frame._i1, (byte)frame._i2, (byte)frame._i3, (byte)frame._i4);
}
public static explicit operator QRectangle(in Frame frame)
{
switch (frame.Type)
{
default:
throw new InvalidCastException();
case FrameType.IVec4:
return new QRectangle(frame._i1, frame._i2, frame._i3, frame._i4);
case FrameType.Vec4:
return new QRectangle(frame._f1, frame._f2, frame._f3, frame._f4);
}
}
public static explicit operator QLine(in Frame frame)
{
switch (frame.Type)
{
default:
throw new InvalidCastException();
case FrameType.IVec4:
return new QLine(frame._i1, frame._i2, frame._i3, frame._i4);
case FrameType.Vec4:
return new QLine(frame._f1, frame._f2, frame._f3, frame._f4);
}
}
#endregion
public static explicit operator Frame(int i) => new Frame(i); public static explicit operator Frame(int i) => new Frame(i);
public static explicit operator Frame(float f) => new Frame(f); public static explicit operator Frame(float f) => new Frame(f);