// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; namespace FlaxEngine { /// /// Class with helper functions. /// public static class Utils { /// /// Copies data from one memory location to another using an unmanaged memory pointers. /// /// /// Uses low-level memcpy call. /// /// The source location. /// The destination location. /// The length (amount of bytes to copy). [MethodImpl(MethodImplOptions.InternalCall)] public static extern void MemoryCopy(IntPtr source, IntPtr destination, int length); /// /// Rounds the floating point value up to 1 decimal place. /// /// The value. /// The rounded result. public static float RoundTo1DecimalPlace(float value) { return (float)Math.Round(value * 10) / 10; } /// /// Rounds the floating point value up to 2 decimal places. /// /// The value. /// The rounded result. public static float RoundTo2DecimalPlaces(float value) { return (float)Math.Round(value * 100) / 100; } /// /// Rounds the floating point value up to 3 decimal places. /// /// The value. /// The rounded result. public static float RoundTo3DecimalPlaces(float value) { return (float)Math.Round(value * 1000) / 1000; } /// /// Gets the empty array of the given type (shared one). /// /// The type. /// The empty array object. public static T[] GetEmptyArray() { return Enumerable.Empty() as T[]; } /// /// Determines whether two arrays are equal by comparing the elements by using the default equality comparer for their type. /// /// The type of the elements of the input sequences. /// The first array. /// The second array. /// true if the two source sequences are of equal length and their corresponding elements are equal according to the default equality comparer for their type; otherwise, false. public static bool ArraysEqual(T[] a1, T[] a2) { if (ReferenceEquals(a1, a2)) return true; if (a1 == null || a2 == null) return false; if (a1.Length != a2.Length) return false; var comparer = EqualityComparer.Default; for (int i = 0; i < a1.Length; i++) { if (!comparer.Equals(a1[i], a2[i])) return false; } return true; } /// /// Determines whether two arrays are equal by comparing the elements by using the default equality comparer for their type. /// /// The type of the elements of the input sequences. /// The first array. /// The second array. /// true if the two source sequences are of equal length and their corresponding elements are equal according to the default equality comparer for their type; otherwise, false. public static bool ArraysEqual(T[] a1, IReadOnlyList a2) { if (a1 == null || a2 == null) return false; if (a1.Length != a2.Count) return false; var comparer = EqualityComparer.Default; for (int i = 0; i < a1.Length; i++) { if (!comparer.Equals(a1[i], a2[i])) return false; } return true; } /// /// Determines whether two arrays are equal by comparing the elements by using the default equality comparer for their type. /// /// The type of the elements of the input sequences. /// The first array. /// The second array. /// true if the two source sequences are of equal length and their corresponding elements are equal according to the default equality comparer for their type; otherwise, false. public static bool ArraysEqual(List a1, List a2) { if (ReferenceEquals(a1, a2)) return true; if (a1 == null || a2 == null) return false; if (a1.Count != a2.Count) return false; var comparer = EqualityComparer.Default; for (int i = 0; i < a1.Count; i++) { if (!comparer.Equals(a1[i], a2[i])) return false; } return true; } /// /// Gets the assembly with the given name. /// /// The name. /// The assembly or null if not found. public static Assembly GetAssemblyByName(string name) { return GetAssemblyByName(name, AppDomain.CurrentDomain.GetAssemblies()); } /// /// Gets the assembly with the given name. /// /// The name. /// The assemblies collection to search for. /// The assembly or null if not found. public static Assembly GetAssemblyByName(string name, Assembly[] assemblies) { Assembly result = null; for (int i = 0; i < assemblies.Length; i++) { var assemblyName = assemblies[i].GetName(); if (assemblyName.Name == name) { result = assemblies[i]; break; } } return result; } internal static T[] ExtractArrayFromList(List list) { T[] result = null; if (list != null) { // TODO: move it to the native code var field = list.GetType().GetField("_items", BindingFlags.Instance | BindingFlags.NonPublic); result = (T[])field.GetValue(list); } return result; } /// /// Reads the color from the binary stream. /// /// The stream. /// The value. public static Color32 ReadColor32(this BinaryReader stream) { return new Color32(stream.ReadByte(), stream.ReadByte(), stream.ReadByte(), stream.ReadByte()); } /// /// Reads the color from the binary stream. /// /// The stream. /// The value. public static Color ReadColor(this BinaryReader stream) { return new Color(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()); } /// /// Reads the Vector2 from the binary stream. /// /// The stream. /// The value. public static Vector2 ReadVector2(this BinaryReader stream) { return new Vector2(stream.ReadSingle(), stream.ReadSingle()); } /// /// Reads the Vector3 from the binary stream. /// /// The stream. /// The value. public static Vector3 ReadVector3(this BinaryReader stream) { return new Vector3(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()); } /// /// Reads the Vector4 from the binary stream. /// /// The stream. /// The value. public static Vector4 ReadVector4(this BinaryReader stream) { return new Vector4(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()); } /// /// Reads the Quaternion from the binary stream. /// /// The stream. /// The value. public static Quaternion ReadQuaternion(this BinaryReader stream) { return new Quaternion(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()); } /// /// Reads the BoundingBox from the binary stream. /// /// The stream. /// The value. public static BoundingBox ReadBoundingBox(this BinaryReader stream) { return new BoundingBox(stream.ReadVector3(), stream.ReadVector3()); } /// /// Reads the BoundingSphere from the binary stream. /// /// The stream. /// The value. public static BoundingSphere ReadBoundingSphere(this BinaryReader stream) { return new BoundingSphere(stream.ReadVector3(), stream.ReadSingle()); } /// /// Reads the Ray from the binary stream. /// /// The stream. /// The value. public static Ray ReadRay(this BinaryReader stream) { return new Ray(stream.ReadVector3(), stream.ReadVector3()); } /// /// Reads the Transform from the binary stream. /// /// The stream. /// The value. public static Transform ReadTransform(this BinaryReader stream) { return new Transform(stream.ReadVector3(), stream.ReadQuaternion(), stream.ReadVector3()); } /// /// Reads the Matrix from the binary stream. /// /// The stream. /// The value. public static Matrix ReadMatrix(this BinaryReader stream) { return new Matrix(stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle(), stream.ReadSingle()); } /// /// Writes the color to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Color32 value) { stream.Write(value.R); stream.Write(value.G); stream.Write(value.B); stream.Write(value.A); } /// /// Writes the color to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Color value) { stream.Write(value.R); stream.Write(value.G); stream.Write(value.B); stream.Write(value.A); } /// /// Writes the Vector2 to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Vector2 value) { stream.Write(value.X); stream.Write(value.Y); } /// /// Writes the Vector3 to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Vector3 value) { stream.Write(value.X); stream.Write(value.Y); stream.Write(value.Z); } /// /// Writes the Vector4 to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Vector4 value) { stream.Write(value.X); stream.Write(value.Y); stream.Write(value.Z); stream.Write(value.W); } /// /// Writes the Quaternion to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Quaternion value) { stream.Write(value.X); stream.Write(value.Y); stream.Write(value.Z); stream.Write(value.W); } /// /// Writes the BoundingBox to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, BoundingBox value) { stream.Write(value.Minimum); stream.Write(value.Maximum); } /// /// Writes the BoundingSphere to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, BoundingSphere value) { stream.Write(value.Center); stream.Write(value.Radius); } /// /// Writes the Transform to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Transform value) { stream.Write(value.Translation); stream.Write(value.Orientation); stream.Write(value.Scale); } /// /// Writes the Rectangle to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Rectangle value) { stream.Write(value.Location); stream.Write(value.Size); } /// /// Writes the Ray to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Ray value) { stream.Write(value.Position); stream.Write(value.Direction); } /// /// Writes the Matrix to the binary stream. /// /// The stream. /// The value to write. public static void Write(this BinaryWriter stream, Matrix value) { stream.Write(value.M11); stream.Write(value.M12); stream.Write(value.M13); stream.Write(value.M14); stream.Write(value.M21); stream.Write(value.M22); stream.Write(value.M23); stream.Write(value.M24); stream.Write(value.M31); stream.Write(value.M32); stream.Write(value.M33); stream.Write(value.M34); stream.Write(value.M41); stream.Write(value.M42); stream.Write(value.M43); stream.Write(value.M44); } } }