Browse Source
* Removed System.Numerics.Vectors dependency. Implemented basic Vector2<T> type to replace it. * ScalingQuality can now be changed for each canvas independently, as well as for the rendering target texture. * Point type is now based on the new Vector2<T> generic.improved_timing
Ian Burgmyer
5 years ago
11 changed files with 420 additions and 83 deletions
@ -0,0 +1,18 @@
|
||||
using System; |
||||
|
||||
namespace DotSDL.Exceptions { |
||||
/// <summary> |
||||
/// This <see cref="Exception"/> is thrown when an invalid type is used for |
||||
/// a genetic class or method. |
||||
/// </summary> |
||||
public class InvalidTypeException : Exception { |
||||
/// <summary> |
||||
/// Initializes an <see cref="InvalidTypeException"/>. |
||||
/// </summary> |
||||
/// <param name="objectName">The class or method that was called.</param> |
||||
/// <param name="invalidType">The invalid type that was passed.</param> |
||||
/// <param name="message">A message that should be appended to the base message.</param> |
||||
public InvalidTypeException(string objectName, Type invalidType, string message = "") |
||||
: base($"{objectName} cannot accept the type {nameof(invalidType)}" + message != "" ? $" ({message})" : "") { } |
||||
} |
||||
} |
@ -1,61 +1,67 @@
|
||||
using DotSDL.Interop.Core; |
||||
using DotSDL.Math.Vector; |
||||
|
||||
namespace DotSDL.Graphics { |
||||
/// <summary> |
||||
/// Represents a point in 2D space. |
||||
/// </summary> |
||||
public class Point { |
||||
public class Point : Vector2<int> { |
||||
/// <summary> |
||||
/// The base <see cref="SdlPoint"/> structure that this class wraps around. |
||||
/// </summary> |
||||
internal Rect.SdlPoint SdlPoint; |
||||
internal Rect.SdlPoint SdlPoint => new Rect.SdlPoint { X = X, Y = Y }; |
||||
|
||||
/// <summary> |
||||
/// Returns a <see cref="Point"/> with the coordinates (1, 1). |
||||
/// </summary> |
||||
public static Point One => new Point(1, 1); |
||||
public new static Point One => new Point(1, 1); |
||||
|
||||
/// <summary> |
||||
/// Returns a <see cref="Point"/> with the coordinates (1, 0). |
||||
/// </summary> |
||||
public static Point UnitX => new Point(1, 0); |
||||
public new static Point UnitX => new Point(1, 0); |
||||
|
||||
/// <summary> |
||||
/// Returns a <see cref="Point"/> with the coordinates (0, 1). |
||||
/// </summary> |
||||
public static Point UnitY => new Point(0, 1); |
||||
public new static Point UnitY => new Point(0, 1); |
||||
|
||||
/// <summary> |
||||
/// Returns a <see cref="Point"/> with the coordinates (0, 0). |
||||
/// </summary> |
||||
public static Point Zero => new Point(0, 0); |
||||
public new static Point Zero => new Point(0, 0); |
||||
|
||||
/// <summary> |
||||
/// The X coordinate of the point. |
||||
/// Creates a new <see cref="Point"/> with the coordinates (0, 0). |
||||
/// </summary> |
||||
public int X { |
||||
get => SdlPoint.X; |
||||
set => SdlPoint.X = value; |
||||
public Point() : this(Zero) { } |
||||
|
||||
/// <summary> |
||||
/// Creates a new <see cref="Point"/> based on an existing <see cref="Point"/>. |
||||
/// </summary> |
||||
/// <param name="point">The <see cref="Point"/> to base this new object on.</param> |
||||
public Point(Point point) { |
||||
X = point.X; |
||||
Y = point.Y; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// The Y coordinate of the point. |
||||
/// Creates a new <see cref="Point"/> based on an existing <see cref="Vector2{T}"/>. |
||||
/// </summary> |
||||
public int Y { |
||||
get => SdlPoint.Y; |
||||
set => SdlPoint.Y = value; |
||||
/// <param name="vec">The <see cref="Vector2{T}"/> to based this new object on.</param> |
||||
public Point(Vector2<int> vec) { |
||||
X = vec.X; |
||||
Y = vec.Y; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Creates a new <see cref="Point"/>. |
||||
/// Creates a new <see cref="Point"/> based on integer coordinates. |
||||
/// </summary> |
||||
/// <param name="x">The X value of the new <see cref="Point"/>.</param> |
||||
/// <param name="y">The Y value of the new <see cref="Point"/>.</param> |
||||
public Point(int x = 0, int y = 0) { |
||||
SdlPoint = new Rect.SdlPoint { |
||||
X = x, |
||||
Y = y |
||||
}; |
||||
/// <param name="x">The X coordinate of the new <see cref="Point"/>.</param> |
||||
/// <param name="y">The Y coordinate of the new <see cref="Point"/>.</param> |
||||
public Point(int x, int y) { |
||||
X = x; |
||||
Y = y; |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,112 @@
|
||||
using DotSDL.Exceptions; |
||||
using System; |
||||
using System.Collections.Generic; |
||||
|
||||
namespace DotSDL.Math.Vector { |
||||
/// <summary> |
||||
/// Represents a generic vector type. |
||||
/// </summary> |
||||
public class Vector2<T> : IEquatable<Vector2<T>> { |
||||
public T X { get; set; } |
||||
public T Y { get; set; } |
||||
|
||||
/// <summary> |
||||
/// Initializes a new <see cref="Vector2{T}"/> object. |
||||
/// </summary> |
||||
/// <exception cref="InvalidTypeException">Thrown if this <see cref="Vector2{T}"/> is created with an unsupported type.</exception> |
||||
public Vector2() { |
||||
if(!VectorBase<T>.IsNumericType()) |
||||
throw new InvalidTypeException(GetType().ToString(), typeof(T)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Initializes a new <see cref="Vector2{T}"/> object using the values from another <see cref="Vector2{T}"/>. |
||||
/// </summary> |
||||
/// <param name="initialValue">The <see cref="Vector2{T}"/> that should be used to initialize the new object.</param> |
||||
/// <exception cref="InvalidTypeException">Thrown if this <see cref="Vector2{T}"/> is created with an unsupported type.</exception> |
||||
public Vector2(Vector2<T> initialValue) : this() { |
||||
X = initialValue.X; |
||||
Y = initialValue.Y; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Initializes a new <see cref="Vector2{T}"/> object with the X and Y values both set to a given value. |
||||
/// </summary> |
||||
/// <param name="initialValue">The value to initialize the X and Y values to.</param> |
||||
/// <exception cref="InvalidTypeException">Thrown if this <see cref="Vector2{T}"/> is created with an unsupported type.</exception> |
||||
public Vector2(T initialValue) : this() { |
||||
X = Y = initialValue; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Initializes a new <see cref="Vector2{T}"/> object with preset X and Y values. |
||||
/// </summary> |
||||
/// <param name="initialX">The initial value to set the X component to.</param> |
||||
/// <param name="initialY">The initial value to set the Y component to.</param> |
||||
/// <exception cref="InvalidTypeException">Thrown if this <see cref="Vector2{T}"/> is created with an unsupported type.</exception> |
||||
public Vector2(T initialX, T initialY) : this() { |
||||
X = initialX; |
||||
Y = initialY; |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Checks to see if two <see cref="Vector2{T}"/> objects are equal. |
||||
/// </summary> |
||||
/// <param name="left">The first <see cref="Vector2{T}"/> in the comparison.</param> |
||||
/// <param name="right">The second <see cref="Vector2{T}"/> in the comparison.</param> |
||||
/// <returns><c>true</c> if the two <see cref="Vector2{T}"/> objects are equal, otherwise <c>false</c>.</returns> |
||||
public static bool operator ==(Vector2<T> left, Vector2<T> right) { |
||||
if(left is null && right is null) return true; |
||||
if(left is null || right is null) return false; |
||||
if(left.GetType() != right.GetType()) return false; |
||||
|
||||
return left.X.Equals(right.X) && left.Y.Equals(right.Y); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Checks to see if two <see cref="Vector2{T}"/> objects are different. |
||||
/// </summary> |
||||
/// <param name="left">The first <see cref="Vector2{T}"/> in the comparison.</param> |
||||
/// <param name="right">The second <see cref="Vector2{T}"/> in the comparison.</param> |
||||
/// <returns><c>true</c> if the two <see cref="Vector2{T}"/> objects are different, otherwise <c>false</c>.</returns> |
||||
public static bool operator !=(Vector2<T> left, Vector2<T> right) { |
||||
return !(left == right); |
||||
} |
||||
|
||||
/// <summary>Returns a new <see cref="Vector2{T}"/> with both X and Y set to 1.</summary> |
||||
public static Vector2<T> One => new Vector2<T>(VectorBase<T>.GetOne()); |
||||
|
||||
/// <summary>Returns a new <see cref="Vector2{T}"/> containing (1, 0).</summary> |
||||
public static Vector2<T> UnitX => new Vector2<T>(VectorBase<T>.GetOne(), VectorBase<T>.GetZero()); |
||||
|
||||
/// <summary>Returns a new <see cref="Vector2{T}"/> containing (0, 1).</summary> |
||||
public static Vector2<T> UnitY => new Vector2<T>(VectorBase<T>.GetZero(), VectorBase<T>.GetOne()); |
||||
|
||||
/// <summary>Returns a new <see cref="Vector2{T}"/> with both X and Y set to 0.</summary> |
||||
public static Vector2<T> Zero => new Vector2<T>(VectorBase<T>.GetZero()); |
||||
|
||||
/// <inheritdoc/> |
||||
public bool Equals(Vector2<T> other) { |
||||
if(ReferenceEquals(null, other)) return false; |
||||
if(ReferenceEquals(this, other)) return true; |
||||
return EqualityComparer<T>.Default.Equals(X, other.X) && EqualityComparer<T>.Default.Equals(Y, other.Y); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Determines whether this <see cref="Vector2{T}"/> is equal to another one. |
||||
/// </summary> |
||||
/// <param name="other">Another <see cref="Vector2{T}"/> to compare this instance to.</param> |
||||
/// <returns><c>true</c> if the two <see cref="Vector2{T}"/> objects are equal, otherwise <c>false</c>.</returns> |
||||
public override bool Equals(object obj) { |
||||
if(!(obj is Vector2<T>)) return false; |
||||
return this == (Vector2<T>)obj; |
||||
} |
||||
|
||||
/// <inheritdoc/> |
||||
public override int GetHashCode() { |
||||
unchecked { |
||||
return (EqualityComparer<T>.Default.GetHashCode(X) * 397) ^ EqualityComparer<T>.Default.GetHashCode(Y); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,158 @@
|
||||
using DotSDL.Exceptions; |
||||
using System.Runtime.CompilerServices; |
||||
|
||||
namespace DotSDL.Math.Vector { |
||||
/// <summary> |
||||
/// A class containing static functions that support the implemented vector types. |
||||
/// </summary> |
||||
/// <typeparam name="T">The type of the vector that should be supported..</typeparam> |
||||
internal static class VectorBase<T> { |
||||
/// <summary> |
||||
/// Retrieves a one value in one of the supported types. |
||||
/// </summary> |
||||
/// <returns>A one value in one of the supported types.</returns> |
||||
/// <exception cref="InvalidTypeException">Thrown if a non-numeric or unsupported type is passed.</exception> |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
internal static T GetOne() { |
||||
if(typeof(T) == typeof(sbyte)) { |
||||
const sbyte val = 1; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(byte)) { |
||||
const byte val = 1; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(short)) { |
||||
const short val = 1; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(ushort)) { |
||||
const ushort val = 1; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(int)) { |
||||
const int val = 1; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(uint)) { |
||||
const uint val = 1; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(long)) { |
||||
const long val = 1; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(ulong)) { |
||||
const ulong val = 1; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(float)) { |
||||
const float val = 1.0f; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(double)) { |
||||
const double val = 1.0d; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(decimal)) { |
||||
const decimal val = 1.0m; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
throw new InvalidTypeException("VectorBase<T>.GetOne()", typeof(T)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Retrieves a zero value in one of the supported types. |
||||
/// </summary> |
||||
/// <returns>A zero value in one of the supported types.</returns> |
||||
/// <exception cref="InvalidTypeException">Thrown if a non-numeric or unsupported type is passed.</exception> |
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)] |
||||
internal static T GetZero() { |
||||
if(typeof(T) == typeof(sbyte)) { |
||||
const sbyte val = 0; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(byte)) { |
||||
const byte val = 0; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(short)) { |
||||
const short val = 0; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(ushort)) { |
||||
const ushort val = 0; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(int)) { |
||||
const int val = 0; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(uint)) { |
||||
const uint val = 0; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(long)) { |
||||
const long val = 0; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(ulong)) { |
||||
const ulong val = 0; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(float)) { |
||||
const float val = 0.0f; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(double)) { |
||||
const double val = 0.0d; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
if(typeof(T) == typeof(decimal)) { |
||||
const decimal val = 0.0m; |
||||
return (T)(object)val; |
||||
} |
||||
|
||||
throw new InvalidTypeException("VectorBase<T>.GetZero()", typeof(T)); |
||||
} |
||||
|
||||
/// <summary> |
||||
/// Determines whether or not the desired type is a valid and supported numeric type. |
||||
/// </summary> |
||||
/// <returns><c>type</c> if the value is a supported numeric type, otherwise <c>false</c>.</returns> |
||||
internal static bool IsNumericType() { |
||||
return typeof(T) == typeof(sbyte) |
||||
|| typeof(T) == typeof(byte) |
||||
|| typeof(T) == typeof(short) |
||||
|| typeof(T) == typeof(ushort) |
||||
|| typeof(T) == typeof(int) |
||||
|| typeof(T) == typeof(uint) |
||||
|| typeof(T) == typeof(long) |
||||
|| typeof(T) == typeof(ulong) |
||||
|| typeof(T) == typeof(float) |
||||
|| typeof(T) == typeof(double) |
||||
|| typeof(T) == typeof(decimal); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue