diff --git a/SharpLib.csproj b/SharpLib.csproj index 3b3457f..5911018 100644 --- a/SharpLib.csproj +++ b/SharpLib.csproj @@ -1,5 +1,5 @@  - + Debug AnyCPU @@ -10,7 +10,7 @@ Properties lib SharpLib - v3.5 + v4.6.2 512 @@ -29,7 +29,7 @@ prompt 4 AnyCPU - false + true On false @@ -61,6 +61,8 @@ + + @@ -81,6 +83,7 @@ + @@ -96,12 +99,10 @@ - - @@ -124,6 +125,8 @@ + + diff --git a/Timer.cs b/Timer.cs index ea0eb4a..b5824b7 100644 --- a/Timer.cs +++ b/Timer.cs @@ -237,22 +237,24 @@ namespace lib // Start the timer - public void Start() + public Timer Start() { m_watch.Start(); startTime = m_watch.ElapsedMicroseconds; stopTime = m_watch.ElapsedMicroseconds; + return this; } // Stop the timer - public void Stop() + public Timer Stop() { m_watch.Stop(); stopTime = m_watch.ElapsedMicroseconds; + return this; } - public double Seconds + public double Seconds { get { diff --git a/Utilities.Interop.cs b/Utilities.Interop.cs new file mode 100644 index 0000000..01d9cb1 --- /dev/null +++ b/Utilities.Interop.cs @@ -0,0 +1,165 @@ +// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +// +// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +#pragma warning disable SA1300 // Element must begin with upper-case letter +#pragma warning disable SA1649 // File name must match first type name +using System; +using System.Runtime.CompilerServices; + +namespace lib +{ + /// + /// Utility class. + /// + internal sealed class Interop + { + public static T Pin(ref T source) where T : struct + { + throw new NotImplementedException(); + } + + public static T IncrementPinned(T source) where T : struct + { + throw new NotImplementedException(); + } + + public static T AddPinned(T source, int offset) where T : struct + { + throw new NotImplementedException(); + } + + public static void Pin(T data) where T : class + { + throw new NotImplementedException(); + } + + public static unsafe void* Fixed(ref T data) + { + throw new NotImplementedException(); + } + + public static unsafe void* FixedOut(out T data) + { + throw new NotImplementedException(); + } + + public static unsafe void* Fixed(T[] data) + { + throw new NotImplementedException(); + } + + public static unsafe void* Cast(ref T data) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe void* CastOut(out T data) where T : struct + { + throw new NotImplementedException(); + } + + public static TCAST[] CastArray(T[] arrayData) + where T : struct + where TCAST : struct + { + throw new NotImplementedException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void memcpy(void* pDest, void* pSrc, int count) + { + throw new NotImplementedException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static unsafe void memset(void* pDest, byte value, int count) + { + throw new NotImplementedException(); + } + + public static unsafe void* Read(void* pSrc, ref T data) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe T ReadInline(void* pSrc) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe void WriteInline(void* pDest, ref T data) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe void CopyInline(ref T data, void* pSrc) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe void CopyInline(void* pDest, ref T srcData) + { + throw new NotImplementedException(); + } + + public static unsafe void CopyInlineOut(out T data, void* pSrc) + { + throw new NotImplementedException(); + } + + public static unsafe void* ReadOut(void* pSrc, out T data) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe void* Read(void* pSrc, T[] data, int offset, int count) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe void* Read2D(void* pSrc, T[,] data, int offset, int count) where T : struct + { + throw new NotImplementedException(); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static int SizeOf() + { + throw new NotImplementedException(); + } + + public static unsafe void* Write(void* pDest, ref T data) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe void* Write(void* pDest, T[] data, int offset, int count) where T : struct + { + throw new NotImplementedException(); + } + + public static unsafe void* Write2D(void* pDest, T[,] data, int offset, int count) where T : struct + { + throw new NotImplementedException(); + } + } +} diff --git a/Utilities.cs b/Utilities.cs new file mode 100644 index 0000000..2e3d3d9 --- /dev/null +++ b/Utilities.cs @@ -0,0 +1,823 @@ +// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +// +// Copyright (c) 2010-2012 SharpDX - Alexandre Mutel +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +#pragma warning disable SA1405 // Debug.Assert must provide message text +using att; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Security; +using System.Text; +using System.Threading; + +namespace lib +{ + /// + /// Utility class. + /// + public static class Util + { + +/* +#if XENKO_PLATFORM_UWP + public static unsafe void CopyMemory(IntPtr dest, IntPtr src, int sizeInBytesToCopy) + { + Interop.memcpy((void*)dest, (void*)src, sizeInBytesToCopy); + } +#else +#if XENKO_PLATFORM_WINDOWS_DESKTOP + private const string MemcpyDll = "msvcrt.dll"; +#elif XENKO_PLATFORM_ANDROID + private const string MemcpyDll = "libc.so"; +#elif XENKO_PLATFORM_UNIX + // We do not specifiy the .so extension as libc.so on Linux + // is actually not a .so files but a script. Using just libc + // will automatically find the corresponding .so. + private const string MemcpyDll = "libc"; +#elif XENKO_PLATFORM_IOS + private const string MemcpyDll = ObjCRuntime.Constants.SystemLibrary; +#else +# error Unsupported platform +#endif + [DllImport(MemcpyDll, EntryPoint = "memcpy", CallingConvention = CallingConvention.Cdecl, SetLastError = false)] +#if !XENKO_RUNTIME_CORECLR + [SuppressUnmanagedCodeSecurity] +#endif + private static extern IntPtr CopyMemory(IntPtr dest, IntPtr src, ulong sizeInBytesToCopy); + + /// + /// Copy memory. + /// + /// The destination memory location + /// The source memory location. + /// The count. + public static void CopyMemory(IntPtr dest, IntPtr src, int sizeInBytesToCopy) + { + CopyMemory(dest, src, (ulong)sizeInBytesToCopy); + } +#endif +*/ + + /// + /// Compares two block of memory. + /// + /// The pointer to compare from. + /// The pointer to compare against. + /// The size in bytes to compare. + /// True if the buffers are equivalent, false otherwise. + public static unsafe bool CompareMemory(IntPtr from, IntPtr against, int sizeToCompare) + { + var pSrc = (byte*)from; + var pDst = (byte*)against; + + // Compare 8 bytes. + var numberOf = sizeToCompare >> 3; + while (numberOf > 0) + { + if (*(long*)pSrc != *(long*)pDst) + return false; + pSrc += 8; + pDst += 8; + numberOf--; + } + + // Compare remaining bytes. + numberOf = sizeToCompare & 7; + while (numberOf > 0) + { + if (*pSrc != *pDst) + return false; + pSrc++; + pDst++; + numberOf--; + } + + return true; + } + + /// + /// Clears the memory. + /// + /// The dest. + /// The value. + /// The size in bytes to clear. + public static void ClearMemory(IntPtr dest, byte value, int sizeInBytesToClear) + { + unsafe + { + Interop.memset((void*)dest, value, sizeInBytesToClear); + } + } + + /// + /// Return the sizeof a struct from a CLR. Equivalent to sizeof operator but works on generics too. + /// + /// a struct to evaluate + /// sizeof this struct + public static int SizeOf() where T : struct + { + return Interop.SizeOf(); + } + + /// + /// Return the sizeof an array of struct. Equivalent to sizeof operator but works on generics too. + /// + /// a struct + /// The array of struct to evaluate. + /// sizeof in bytes of this array of struct + public static int SizeOf(T[] array) where T : struct + { + return array == null ? 0 : array.Length * Interop.SizeOf(); + } + + /// + /// Pins the specified source and call an action with the pinned pointer. + /// + /// The type of the structure to pin + /// The source. + /// The pin action to perform on the pinned pointer. + public static void Pin(ref T source, Action pinAction) where T : struct + { + unsafe + { + pinAction((IntPtr)Interop.Fixed(ref source)); + } + } + + /// + /// Pins the specified source and call an action with the pinned pointer. + /// + /// The type of the structure to pin + /// The source array. + /// The pin action to perform on the pinned pointer. + public static void Pin(T[] source, [NotNull] Action pinAction) where T : struct + { + unsafe + { + pinAction(source == null ? IntPtr.Zero : (IntPtr)Interop.Fixed(source)); + } + } + + /// + /// Covnerts a structured array to an equivalent byte array. + /// + /// The source. + /// The byte array. + public static byte[] ToByteArray(T[] source) where T : struct + { + if (source == null) return null; + + var buffer = new byte[SizeOf() * source.Length]; + + if (source.Length == 0) + return buffer; + + unsafe + { + fixed (void* pBuffer = buffer) + Interop.Write(pBuffer, source, 0, source.Length); + } + return buffer; + } + + /// + /// Reads the specified T data from a memory location. + /// + /// Type of a data to read + /// Memory location to read from. + /// The data read from the memory location + public static T Read(IntPtr source) where T : struct + { + unsafe + { + return Interop.ReadInline((void*)source); + } + } + + /// + /// Reads the specified T data from a memory location. + /// + /// Type of a data to read + /// Memory location to read from. + /// The data write to. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Read(IntPtr source, ref T data) where T : struct + { + unsafe + { + Interop.CopyInline(ref data, (void*)source); + } + } + + /// + /// Reads the specified T data from a memory location. + /// + /// Type of a data to read + /// Memory location to read from. + /// The data write to. + public static void ReadOut(IntPtr source, out T data) where T : struct + { + unsafe + { + Interop.CopyInlineOut(out data, (void*)source); + } + } + + /// + /// Reads the specified T data from a memory location. + /// + /// Type of a data to read + /// Memory location to read from. + /// The data write to. + /// source pointer + sizeof(T) + public static IntPtr ReadAndPosition(IntPtr source, ref T data) where T : struct + { + unsafe + { + return (IntPtr)Interop.Read((void*)source, ref data); + } + } + + /// + /// Reads the specified array T[] data from a memory location. + /// + /// Type of a data to read + /// Memory location to read from. + /// The data write to. + /// The offset in the array to write to. + /// The number of T element to read from the memory location + /// source pointer + sizeof(T) * count + public static IntPtr Read(IntPtr source, T[] data, int offset, int count) where T : struct + { + unsafe + { + return (IntPtr)Interop.Read((void*)source, data, offset, count); + } + } + + /// + /// Writes the specified T data to a memory location. + /// + /// Type of a data to write + /// Memory location to write to. + /// The data to write. + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Write(IntPtr destination, ref T data) where T : struct + { + unsafe + { + Interop.CopyInline((void*)destination, ref data); + } + } + + /// + /// Writes the specified T data to a memory location. + /// + /// Type of a data to write + /// Memory location to write to. + /// The data to write. + /// destination pointer + sizeof(T) + public static IntPtr WriteAndPosition(IntPtr destination, ref T data) where T : struct + { + unsafe + { + return (IntPtr)Interop.Write((void*)destination, ref data); + } + } + + /// + /// Writes the specified array T[] data to a memory location. + /// + /// Type of a data to write + /// Memory location to write to. + /// The array of T data to write. + /// The offset in the array to read from. + /// The number of T element to write to the memory location + public static void Write(byte[] destination, T[] data, int offset, int count) where T : struct + { + unsafe + { + fixed (void* pDest = destination) + { + Write((IntPtr)pDest, data, offset, count); + } + } + } + + /// + /// Writes the specified array T[] data to a memory location. + /// + /// Type of a data to write + /// Memory location to write to. + /// The array of T data to write. + /// The offset in the array to read from. + /// The number of T element to write to the memory location + /// destination pointer + sizeof(T) * count + public static IntPtr Write(IntPtr destination, T[] data, int offset, int count) where T : struct + { + unsafe + { + return (IntPtr)Interop.Write((void*)destination, data, offset, count); + } + } + + /// + /// Allocate an aligned memory buffer. + /// + /// Size of the buffer to allocate. + /// Alignment, a positive value which is a power of 2. 16 bytes by default. + /// A pointer to a buffer aligned. + /// + /// To free this buffer, call + /// + public static unsafe IntPtr AllocateMemory(int sizeInBytes, int align = 16) + { + var mask = align - 1; + if ((align & mask) != 0) + { + throw new ArgumentException("Alignment is not power of 2", nameof(align)); + } + var memPtr = Marshal.AllocHGlobal(sizeInBytes + mask + sizeof(void*)); + var ptr = (byte*)((ulong)(memPtr.ToInt32() + sizeof(void*) + mask) & ~(ulong)mask); + ((IntPtr*)ptr)[-1] = memPtr; + return new IntPtr(ptr); + } + + /// + /// Allocate an aligned memory buffer and clear it with a specified value (0 by defaault). + /// + /// Size of the buffer to allocate. + /// Default value used to clear the buffer. + /// Alignment, 16 bytes by default. + /// A pointer to a buffer aligned. + /// + /// To free this buffer, call + /// + public static IntPtr AllocateClearedMemory(int sizeInBytes, byte clearValue = 0, int align = 16) + { + var ptr = AllocateMemory(sizeInBytes, align); + ClearMemory(ptr, clearValue, sizeInBytes); + return ptr; + } + + /// + /// Determines whether the specified memory pointer is aligned in memory. + /// + /// The memory pointer. + /// The align. + /// true if the specified memory pointer is aligned in memory; otherwise, false. + public static bool IsMemoryAligned(IntPtr memoryPtr, int align = 16) + { + return (memoryPtr.ToInt64() & (align - 1)) == 0; + } + + /// + /// Allocate an aligned memory buffer. + /// + /// + /// The buffer must have been allocated with + /// + public static unsafe void FreeMemory(IntPtr alignedBuffer) + { + Marshal.FreeHGlobal(((IntPtr*)alignedBuffer)[-1]); + } + + /// + /// If non-null, disposes the specified object and set it to null, otherwise do nothing. + /// + /// The disposable. + public static void Dispose(ref T disposable) where T : class, IDisposable + { + if (disposable != null) + { + disposable.Dispose(); + disposable = null; + } + } + + /// + /// String helper join method to display an array of object as a single string. + /// + /// The separator. + /// The array. + /// a string with array elements serparated by the seperator + [NotNull] + public static string Join(string separator, T[] array) + { + var text = new StringBuilder(); + if (array != null) + { + for (var i = 0; i < array.Length; i++) + { + if (i > 0) text.Append(separator); + text.Append(array[i]); + } + } + return text.ToString(); + } + + /// + /// String helper join method to display an enumrable of object as a single string. + /// + /// The separator. + /// The enumerable. + /// a string with array elements serparated by the seperator + [NotNull] + public static string Join(string separator, [NotNull] IEnumerable elements) + { + var elementList = new List(); + foreach (var element in elements) + elementList.Add(element.ToString()); + + var text = new StringBuilder(); + for (var i = 0; i < elementList.Count; i++) + { + var element = elementList[i]; + if (i > 0) text.Append(separator); + text.Append(element); + } + return text.ToString(); + } + + /// + /// String helper join method to display an enumrable of object as a single string. + /// + /// The separator. + /// The enumerable. + /// a string with array elements serparated by the seperator + [NotNull] + public static string Join(string separator, [NotNull] IEnumerator elements) + { + var elementList = new List(); + while (elements.MoveNext()) + elementList.Add(elements.Current.ToString()); + + var text = new StringBuilder(); + for (var i = 0; i < elementList.Count; i++) + { + var element = elementList[i]; + if (i > 0) text.Append(separator); + text.Append(element); + } + return text.ToString(); + } + + /// + /// Read stream to a byte[] buffer + /// + /// input stream + /// a byte[] buffer + [NotNull] + public static byte[] ReadStream([NotNull] Stream stream) + { + var readLength = 0; + return ReadStream(stream, ref readLength); + } + + /// + /// Read stream to a byte[] buffer + /// + /// input stream + /// length to read + /// a byte[] buffer + [NotNull] + public static byte[] ReadStream([NotNull] Stream stream, ref int readLength) + { + System.Diagnostics.Debug.Assert(stream != null); + System.Diagnostics.Debug.Assert(stream.CanRead); + var num = readLength; + System.Diagnostics.Debug.Assert(num <= (stream.Length - stream.Position)); + if (num == 0) + readLength = (int)(stream.Length - stream.Position); + num = readLength; + + System.Diagnostics.Debug.Assert(num >= 0); + if (num == 0) + return new byte[0]; + + var buffer = new byte[num]; + var bytesRead = 0; + if (num > 0) + { + do + { + bytesRead += stream.Read(buffer, bytesRead, readLength - bytesRead); + } while (bytesRead < readLength); + } + return buffer; + } + + /// + /// Computes a hashcode for a dictionary. + /// + /// Hashcode for the list. + public static int GetHashCode(IDictionary dict) + { + if (dict == null) + return 0; + + var hashCode = 0; + foreach (DictionaryEntry keyValue in dict) + { + hashCode = (hashCode * 397) ^ keyValue.Key.GetHashCode(); + hashCode = (hashCode * 397) ^ (keyValue.Value?.GetHashCode() ?? 0); + } + return hashCode; + } + + /// + /// Computes a hashcode for an enumeration + /// + /// An enumerator. + /// Hashcode for the list. + public static int GetHashCode(IEnumerable it) + { + if (it == null) + return 0; + + var hashCode = 0; + foreach (var current in it) + { + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + } + return hashCode; + } + + /// + /// Computes a hashcode for an enumeration + /// + /// An enumerator. + /// Hashcode for the list. + public static int GetHashCode(IEnumerator it) + { + if (it == null) + return 0; + + var hashCode = 0; + while (it.MoveNext()) + { + var current = it.Current; + hashCode = (hashCode * 397) ^ (current?.GetHashCode() ?? 0); + } + return hashCode; + } + + /// + /// Compares two collection, element by elements. + /// + /// A "from" enumerator. + /// A "to" enumerator. + /// True if lists are identical. False otherwise. + public static bool Compare(IEnumerable left, IEnumerable right) + { + if (ReferenceEquals(left, right)) + return true; + if (ReferenceEquals(left, null) || ReferenceEquals(right, null)) + return false; + + return Compare(left.GetEnumerator(), right.GetEnumerator()); + } + + /// + /// Compares two collection, element by elements. + /// + /// A "from" enumerator. + /// A "to" enumerator. + /// True if lists are identical. False otherwise. + public static bool Compare(IEnumerator leftIt, IEnumerator rightIt) + { + if (ReferenceEquals(leftIt, rightIt)) + return true; + if (ReferenceEquals(leftIt, null) || ReferenceEquals(rightIt, null)) + return false; + + bool hasLeftNext; + bool hasRightNext; + while (true) + { + hasLeftNext = leftIt.MoveNext(); + hasRightNext = rightIt.MoveNext(); + if (!hasLeftNext || !hasRightNext) + break; + + if (!Equals(leftIt.Current, rightIt.Current)) + return false; + } + + // If there is any left element + if (hasLeftNext != hasRightNext) + return false; + + return true; + } + + /// + /// Compares two collection, element by elements. + /// + /// The collection to compare from. + /// The colllection to compare to. + /// True if lists are identical (but no necessarely of the same time). False otherwise. + public static bool Compare(IDictionary first, IDictionary second) + { + if (ReferenceEquals(first, second)) return true; + if (ReferenceEquals(first, null) || ReferenceEquals(second, null)) return false; + if (first.Count != second.Count) return false; + + var comparer = EqualityComparer.Default; + + foreach (var keyValue in first) + { + TValue secondValue; + if (!second.TryGetValue(keyValue.Key, out secondValue)) return false; + if (!comparer.Equals(keyValue.Value, secondValue)) return false; + } + + // Check that all keys in second are in first + return second.Keys.All(first.ContainsKey); + } + + public static bool Compare(T[] left, T[] right) + { + if (ReferenceEquals(left, right)) + return true; + if (ReferenceEquals(left, null) || ReferenceEquals(right, null)) + return false; + + if (left.Length != right.Length) + return false; + + var comparer = EqualityComparer.Default; + for (var i = 0; i < left.Length; ++i) + { + if (!comparer.Equals(left[i], right[i])) + return false; + } + + return true; + } + + /// + /// Compares two collection, element by elements. + /// + /// The collection to compare from. + /// The colllection to compare to. + /// True if lists are identical (but no necessarely of the same time). False otherwise. + public static bool Compare(ICollection left, ICollection right) + { + if (ReferenceEquals(left, right)) + return true; + if (ReferenceEquals(left, null) || ReferenceEquals(right, null)) + return false; + + if (left.Count != right.Count) + return false; + + var count = 0; + var leftIt = left.GetEnumerator(); + var rightIt = right.GetEnumerator(); + var comparer = EqualityComparer.Default; + while (leftIt.MoveNext() && rightIt.MoveNext()) + { + if (!comparer.Equals(leftIt.Current, rightIt.Current)) + return false; + count++; + } + + // Just double check to make sure that the iterator actually returns + // the exact number of elements + if (count != left.Count) + return false; + + return true; + } + + /// + /// Swaps the value between two references. + /// + /// Type of a data to swap. + /// The left value. + /// The right value. + public static void Swap(ref T left, ref T right) + { + var temp = left; + left = right; + right = temp; + } + + /// + /// Suspends current thread for a . + /// + /// The duration of sleep. + public static void Sleep(TimeSpan sleepTime) + { + var ms = (long)sleepTime.TotalMilliseconds; + if (ms < 0 || ms > int.MaxValue) + { + throw new ArgumentOutOfRangeException(nameof(sleepTime), "Sleep time must be a duration less than '2^31 - 1' milliseconds."); + } + // MH PORTED NativeInvoke.Sleep((int)ms); + Thread.Sleep( (int)ms ); + } + + /// + /// Suspends current thread for a . + /// + /// The duration of sleep in milliseconds. + public static void Sleep(int sleepTimeInMillis) + { + // MH PORTED NativeInvoke.Sleep(sleepTimeInMillis); + Thread.Sleep( sleepTimeInMillis ); + } + + /// + /// Writes the specified T data to a memory location. + /// + /// Type of a data to write + /// Memory location to write to. + /// The data to write. + internal static void UnsafeWrite(IntPtr destination, ref T data) + { + unsafe + { + Interop.CopyInline((void*)destination, ref data); + } + } + + /// + /// Reads the specified T data from a memory location. + /// + /// Type of a data to read + /// Memory location to read from. + /// The data write to. + internal static void UnsafeReadOut(IntPtr source, out T data) + { + unsafe + { + Interop.CopyInlineOut(out data, (void*)source); + } + } + + /// + /// Return the sizeof a struct from a CLR. Equivalent to sizeof operator but works on generics too. + /// + /// a struct to evaluate + /// sizeof this struct + internal static int UnsafeSizeOf() + { + return Interop.SizeOf(); + } + + /// + /// Linq assisted full tree iteration and collection in a single line. + /// Warning, could be slow. + /// + /// The type to iterate. + /// The root item + /// The function to retrieve a child + public static IEnumerable IterateTree(T root, Func> childrenF) + { + var q = new List { root }; + while (q.Any()) + { + var c = q[0]; + q.RemoveAt(0); + q.AddRange(childrenF(c) ?? Enumerable.Empty()); + yield return c; + } + } + + /// + /// Converts a raw time to a . + /// + /// The delta. + /// The . + public static TimeSpan ConvertRawToTimestamp(long delta) + { + return new TimeSpan(delta == 0 ? 0 : (delta * TimeSpan.TicksPerSecond) / Stopwatch.Frequency); + } + } +} diff --git a/att/CanBeNullAttribute.cs b/att/CanBeNullAttribute.cs new file mode 100644 index 0000000..ca23334 --- /dev/null +++ b/att/CanBeNullAttribute.cs @@ -0,0 +1,51 @@ +// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +/* MIT License + +Copyright (c) 2016 JetBrains http://www.jetbrains.com + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. */ + +using System; + +namespace att +{ + /// + /// Indicates that the value of the marked element could be null sometimes, so the check for null + /// is necessary before its usage. + /// + /// + /// + /// [CanBeNull] object Test() => null; + /// + /// void UseTest() { + /// var p = Test(); + /// var s = p.ToString(); // Warning: Possible 'System.NullReferenceException' + /// } + /// + /// + [AttributeUsage( + AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | + AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event | + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)] + public sealed class CanBeNullAttribute : Attribute + { + } +} diff --git a/att/NotNullAttribute.cs b/att/NotNullAttribute.cs new file mode 100644 index 0000000..60afed4 --- /dev/null +++ b/att/NotNullAttribute.cs @@ -0,0 +1,25 @@ +// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. + +using System; + +namespace att +{ + /// + /// Indicates that the value of the marked element could never be null. + /// + /// + /// + /// [NotNull] object Foo() { + /// return null; // Warning: Possible 'null' assignment + /// } + /// + /// + [AttributeUsage( + AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.Property | + AttributeTargets.Delegate | AttributeTargets.Field | AttributeTargets.Event | + AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.GenericParameter)] + public sealed class NotNullAttribute : Attribute + { + } +} diff --git a/math/BoundingSphere.cs b/math/BoundingSphere.cs index 36496a8..02fd8f5 100644 --- a/math/BoundingSphere.cs +++ b/math/BoundingSphere.cs @@ -195,7 +195,7 @@ namespace math if (points == null) throw new ArgumentNullException("points"); fixed (void* pointsPtr = points) { - FromPoints((IntPtr)pointsPtr, 0, points.Length, Utilities.SizeOf(), out result); + FromPoints((IntPtr)pointsPtr, 0, points.Length, lib.Util.SizeOf(), out result); } } diff --git a/math/ColorExtensions.cs b/math/ColorExtensions.cs index c811b2e..0e891d9 100644 --- a/math/ColorExtensions.cs +++ b/math/ColorExtensions.cs @@ -1,7 +1,7 @@ // Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) // Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +using att; using System.Globalization; -using Xenko.Core.Annotations; using System.Runtime.Serialization; namespace math diff --git a/math/DataMemberIgnoreAttribute.cs b/math/DataMemberIgnoreAttribute.cs new file mode 100644 index 0000000..6ef7956 --- /dev/null +++ b/math/DataMemberIgnoreAttribute.cs @@ -0,0 +1,36 @@ +// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) +// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. +// +// ----------------------------------------------------------------------------- +// Original code from SlimMath project. http://code.google.com/p/slimmath/ +// Greetings to SlimDX Group. Original code published with the following license: +// ----------------------------------------------------------------------------- +/* +* Copyright (c) 2007-2011 SlimDX Group +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +* copies of the Software, and to permit persons to whom the Software is +* furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in +* all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +* THE SOFTWARE. +*/ +using System; + +namespace math +{ + internal class DataMemberIgnoreAttribute : Attribute + { + } +} \ No newline at end of file diff --git a/math/Double2.cs b/math/Double2.cs index 309dc83..7d55231 100644 --- a/math/Double2.cs +++ b/math/Double2.cs @@ -21,7 +21,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Double3.cs b/math/Double3.cs index 531f71c..5100503 100644 --- a/math/Double3.cs +++ b/math/Double3.cs @@ -21,7 +21,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Double4.cs b/math/Double4.cs index f49f96f..35ef0c9 100644 --- a/math/Double4.cs +++ b/math/Double4.cs @@ -21,7 +21,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Half.cs b/math/Half.cs index aceca1b..fd46fdc 100644 --- a/math/Half.cs +++ b/math/Half.cs @@ -25,7 +25,6 @@ using System; using System.ComponentModel; using System.Globalization; using System.Runtime.InteropServices; -using Xenko.Core.Serialization; using System.Runtime.Serialization; namespace math diff --git a/math/Half2.cs b/math/Half2.cs index b3ab4aa..b25015f 100644 --- a/math/Half2.cs +++ b/math/Half2.cs @@ -24,7 +24,6 @@ using System; using System.ComponentModel; using System.Runtime.InteropServices; -using Xenko.Core.Serialization; using System.Runtime.Serialization; namespace math diff --git a/math/Half3.cs b/math/Half3.cs index 4e48cd2..ab31870 100644 --- a/math/Half3.cs +++ b/math/Half3.cs @@ -24,7 +24,6 @@ using System; using System.ComponentModel; using System.Runtime.InteropServices; -using Xenko.Core.Serialization; using System.Runtime.Serialization; namespace math diff --git a/math/Half4.cs b/math/Half4.cs index cdcc251..d348492 100644 --- a/math/Half4.cs +++ b/math/Half4.cs @@ -24,7 +24,7 @@ using System; using System.ComponentModel; using System.Runtime.InteropServices; -using Xenko.Core.Serialization; + using System.Runtime.Serialization; namespace math diff --git a/math/Int2.cs b/math/Int2.cs index be0cae0..1c3d47b 100644 --- a/math/Int2.cs +++ b/math/Int2.cs @@ -44,7 +44,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Int3.cs b/math/Int3.cs index 6c35504..2b66a4c 100644 --- a/math/Int3.cs +++ b/math/Int3.cs @@ -44,7 +44,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Int4.cs b/math/Int4.cs index 93d2b5d..980d779 100644 --- a/math/Int4.cs +++ b/math/Int4.cs @@ -38,7 +38,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Matrix.cs b/math/Matrix.cs index 6e905dd..70a1096 100644 --- a/math/Matrix.cs +++ b/math/Matrix.cs @@ -47,7 +47,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Module.cs b/math/Module.cs deleted file mode 100644 index 9271236..0000000 --- a/math/Module.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Reflection; -using Xenko.Core.Reflection; - -namespace math -{ - /// - /// Module initializer. - /// - internal class Module - { - /// - /// Module initializer. - /// - [ModuleInitializer] - public static void Initialize() - { - AssemblyRegistry.Register(typeof(Module).GetTypeInfo().Assembly, AssemblyCommonCategories.Assets); - } - } -} diff --git a/math/Point.cs b/math/Point.cs index f862f12..5160c39 100644 --- a/math/Point.cs +++ b/math/Point.cs @@ -23,7 +23,7 @@ using System; using System.Runtime.InteropServices; -using Xenko.Core.Serialization; + using System.Runtime.Serialization; namespace math diff --git a/math/Properties/AssemblyInfo.cs b/math/Properties/AssemblyInfo.cs deleted file mode 100644 index a507540..0000000 --- a/math/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,8 +0,0 @@ -// Copyright (c) Xenko contributors (https://xenko.com) and Silicon Studio Corp. (https://www.siliconstudio.co.jp) -// Distributed under the MIT license. See the LICENSE.md file in the project root for more information. -using System.Reflection; -using System.Runtime.CompilerServices; - -#pragma warning disable 436 // Xenko.PublicKeys is defined in multiple assemblies - -[assembly: InternalsVisibleTo("math.Serializers" + Xenko.PublicKeys.Default)] diff --git a/math/Quaternion.cs b/math/Quaternion.cs index e2f5839..646e600 100644 --- a/math/Quaternion.cs +++ b/math/Quaternion.cs @@ -44,7 +44,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/SphericalHarmonics.cs b/math/SphericalHarmonics.cs index 9698943..af7ad16 100644 --- a/math/SphericalHarmonics.cs +++ b/math/SphericalHarmonics.cs @@ -97,7 +97,7 @@ namespace math // ReSharper restore UnusedParameter.Local { if (l > maxOrder - 1) - throw new IndexOutOfRangeException("'l' parameter should be between '0' and '{0}' (order-1).".ToFormat(maxOrder-1)); + throw new IndexOutOfRangeException($"'l' parameter should be between '0' and '{maxOrder-1}' (order-1)."); if (Math.Abs(m) > l) throw new IndexOutOfRangeException("'m' parameter should be between '-l' and '+l'."); diff --git a/math/UInt4.cs b/math/UInt4.cs index 7ba3da3..48be4ac 100644 --- a/math/UInt4.cs +++ b/math/UInt4.cs @@ -23,7 +23,6 @@ using System; using System.Globalization; using System.Runtime.InteropServices; -using Xenko.Core.Serialization; using System.Runtime.Serialization; namespace math @@ -38,7 +37,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Vector2.cs b/math/Vector2.cs index 213dd84..b76cb86 100644 --- a/math/Vector2.cs +++ b/math/Vector2.cs @@ -46,7 +46,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Vector3.cs b/math/Vector3.cs index c3f68c2..6fab57c 100644 --- a/math/Vector3.cs +++ b/math/Vector3.cs @@ -46,7 +46,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero. diff --git a/math/Vector4.cs b/math/Vector4.cs index b15c73d..2a4b029 100644 --- a/math/Vector4.cs +++ b/math/Vector4.cs @@ -45,7 +45,7 @@ namespace math /// /// The size of the type, in bytes. /// - public static readonly int SizeInBytes = Utilities.SizeOf(); + public static readonly int SizeInBytes = lib.Util.SizeOf(); /// /// A with all of its components set to zero.