diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index 415d4b4..87a6e4b 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -32,6 +32,7 @@ jobs: run: | mkdir build dotnet pack X10D -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }} + dotnet pack X10D.Unity -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='nightly' -p:BuildNumber=${{ github.run_number }} - name: Push NuGet Package to GitHub run: dotnet nuget push "build/*" --source "github" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index 1f2cb8d..c400d74 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -32,6 +32,7 @@ jobs: run: | mkdir build dotnet pack X10D -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }} + dotnet pack X10D.Unity -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build -p:VersionSuffix='prerelease' -p:BuildNumber=${{ github.run_number }} - name: Push NuGet Package to GitHub run: dotnet nuget push "build/*" --source "github" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 85ed581..438abed 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,6 +32,7 @@ jobs: run: | mkdir build dotnet pack X10D -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build + dotnet pack X10D.Unity -p:SymbolPackageFormat=snupkg --include-symbols --include-source -o build - name: Push NuGet Package to GitHub run: dotnet nuget push "build/*" --source "github" --api-key ${{ secrets.GITHUB_TOKEN }} --skip-duplicate diff --git a/.github/workflows/source_validator.yml b/.github/workflows/source_validator.yml index a286122..c664fdd 100644 --- a/.github/workflows/source_validator.yml +++ b/.github/workflows/source_validator.yml @@ -32,5 +32,4 @@ jobs: run: dotnet build -c Debug - name: Run Source Validation - run: dotnet run --project X10D.SourceValidator ./X10D/src - + run: dotnet run --project X10D.SourceValidator ./X10D/src ./X10D.Unity/src diff --git a/.github/workflows/unity.yml b/.github/workflows/unity.yml new file mode 100644 index 0000000..eaba3e6 --- /dev/null +++ b/.github/workflows/unity.yml @@ -0,0 +1,50 @@ +name: Unity Test Runner + +on: + push: + branches: + - main + - develop + pull_request: + branches: + - main + - develop + +jobs: + build: + name: "Unity Test Runner" + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup .NET + uses: actions/setup-dotnet@v2 + with: + dotnet-version: 6.0.x + + - name: Add GitHub NuGet source + run: dotnet nuget add source --username oliverbooth --password ${{ secrets.GITHUB_TOKEN }} --store-password-in-clear-text --name github "https://nuget.pkg.github.com/oliverbooth/index.json" + + - name: Restore dependencies + run: dotnet restore + + - name: Build + run: dotnet build -c Release + + - name: Copy artifacts to project + run: | + mkdir -p ./X10D.Unity.Tests/Assets/Libraries + cp -r ./X10D/bin/Release/netstandard2.1/X10D.dll ./X10D.Unity.Tests/Assets/Libraries/X10D.dll + cp -r ./X10D.Unity/bin/Release/netstandard2.1/X10D.Unity.dll ./X10D.Unity.Tests/Assets/Libraries/X10D.Unity.dll + + - name: Unity - Test runner + uses: game-ci/unity-test-runner@v2.0.2 + env: + UNITY_LICENSE: ${{ secrets.UNITY_LICENSE }} + UNITY_EMAIL: ${{ secrets.UNITY_EMAIL }} + UNITY_PASSWORD: ${{ secrets.UNITY_PASSWORD }} + with: + projectPath: X10D.Unity.Tests + githubToken: ${{ secrets.GITHUB_TOKEN }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ba06d6..a5caa91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,80 @@ # Changelog +## [3.1.0] +### Added +- Reintroduced Unity support +- X10D: Added `Color.Inverted()` (#54) +- X10D: Added `Color.WithA()` (#55) +- X10D: Added `Color.WithB()` (#55) +- X10D: Added `Color.WithG()` (#55) +- X10D: Added `Color.WithR()` (#55) +- X10D: Added `ICollection.ClearAndDisposeAll()` +- X10D: Added `ICollection.ClearAndDisposeAllAsync()` +- X10D: Added `IEnumerable.For()` (#50) +- X10D: Added `IEnumerable.ForEach()` (#50) +- X10D: Added `IEnumerable.DisposeAll()` +- X10D: Added `IEnumerable.DisposeAllAsync()` +- X10D: Added `char.IsEmoji` +- X10D: Added `ReadOnlySpan.Count(Predicate)` +- X10D: Added `Rune.IsEmoji` +- X10D: Added `Span.Count(Predicate)` +- X10D: Added `string.IsEmoji` +- X10D: Added `Vector2.WithX()` (#56) +- X10D: Added `Vector2.WithY()` (#56) +- X10D: Added `Vector3.WithX()` (#56) +- X10D: Added `Vector3.WithY()` (#56) +- X10D: Added `Vector3.WithZ()` (#56) +- X10D: Added `Vector4.WithX()` (#56) +- X10D: Added `Vector4.WithY()` (#56) +- X10D: Added `Vector4.WithZ()` (#56) +- X10D: Added `Vector4.WithW()` (#56) +- X10D.Unity: Added `Singleton` class +- X10D.Unity: Added `Color.Inverted()` (#54) +- X10D.Unity: Added `Color.WithA()` (#55) +- X10D.Unity: Added `Color.WithB()` (#55) +- X10D.Unity: Added `Color.WithG()` (#55) +- X10D.Unity: Added `Color.WithR()` (#55) +- X10D.Unity: Added `Color32.Inverted()` (#54) +- X10D.Unity: Added `Color32.WithA()` (#55) +- X10D.Unity: Added `Color32.WithB()` (#55) +- X10D.Unity: Added `Color32.WithG()` (#55) +- X10D.Unity: Added `Color32.WithR()` (#55) +- X10D.Unity: Added `Component.GetComponentsInChildrenOnly()` +- X10D.Unity: Added `GameObject.GetComponentsInChildrenOnly()` +- X10D.Unity: Added `GameObject.LookAt(GameObject[, Vector3])` +- X10D.Unity: Added `GameObject.LookAt(Transform[, Vector3])` +- X10D.Unity: Added `GameObject.LookAt(Vector3[, Vector3])` +- X10D.Unity: Added `GameObject.SetLayerRecursively(int)` (#57) +- X10D.Unity: Added `GameObject.SetParent(GameObject[, bool])` +- X10D.Unity: Added `GameObject.SetParent(Transform[, bool])` +- X10D.Unity: Added `System.Numerics.Quaternion.ToUnityQuaternion()` +- X10D.Unity: Added `Quaternion.ToSystemQuaternion()` +- X10D.Unity: Added `Random.NextColorArgb()` +- X10D.Unity: Added `Random.NextColor32Argb()` +- X10D.Unity: Added `Random.NextColorRgb()` +- X10D.Unity: Added `Random.NextColor32Rgb()` +- X10D.Unity: Added `Random.NextRotation()` +- X10D.Unity: Added `Random.NextRotationUniform()` +- X10D.Unity: Added `Random.NextUnitVector2()` +- X10D.Unity: Added `Random.NextUnitVector3()` +- X10D.Unity: Added `Transform.LookAt(GameObject[, Vector3])` +- X10D.Unity: Added `Transform.SetParent(GameObject[, bool])` +- X10D.Unity: Added `System.Numerics.Vector2.ToUnityVector()` +- X10D.Unity: Added `System.Numerics.Vector3.ToUnityVector()` +- X10D.Unity: Added `System.Numerics.Vector4.ToUnityVector()` +- X10D.Unity: Added `Vector2.ToSystemVector()` +- X10D.Unity: Added `Vector3.ToSystemVector()` +- X10D.Unity: Added `Vector4.ToSystemVector()` +- X10D.Unity: Added `Vector2.WithX()` (#56) +- X10D.Unity: Added `Vector2.WithY()` (#56) +- X10D.Unity: Added `Vector3.WithX()` (#56) +- X10D.Unity: Added `Vector3.WithY()` (#56) +- X10D.Unity: Added `Vector3.WithZ()` (#56) +- X10D.Unity: Added `Vector4.WithX()` (#56) +- X10D.Unity: Added `Vector4.WithY()` (#56) +- X10D.Unity: Added `Vector4.WithZ()` (#56) +- X10D.Unity: Added `Vector4.WithW()` (#56) + ## [3.0.0] In the midst of writing these release notes, I may have missed some important changes. If you notice an API change that is not documented here, @@ -299,6 +374,7 @@ please [open an issue](https://github.com/oliverbooth/X10D/issues)! ### ***Not documented*** +[3.1.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.1.0 [3.0.0]: https://github.com/oliverbooth/X10D/releases/tag/v3.0.0 [2.6.0]: https://github.com/oliverbooth/X10D/releases/tag/2.6.0 [2.5.0]: https://github.com/oliverbooth/X10D/releases/tag/2.5.0 diff --git a/README.md b/README.md index 769d72c..e6d6fbe 100644 --- a/README.md +++ b/README.md @@ -23,12 +23,12 @@ Install-Package X10D -Version 3.0.0 ### Manual installation Download the [latest release](https://github.com/oliverbooth/X10D/releases/latest) from this repository and adding a direct assembly reference for your chosen platform. -### What happened to X10D.Unity? -I decided it was time for X10D to be migrated to .NET 6. Unity currently supports .NET Framework 4.x / .NET Standard 2.1, and as such is not compatible with X10D at this time. -Unity have announced official support for .NET 6 in the future (see [this forum post](https://forum.unity.com/threads/unity-future-net-development-status.1092205/) for more details), -but until such a time that Unity supports .NET 6, X10D.Unity will not be maintained or innovated upon. +### Unity installation +Starting with Unity 2021.2, support for .NET Standard 2.1 has been added. With this change, I am confident providing support for this version for the time being, with only minimal feature-loss. +To add X10D into your Unity project, goto the [Package Manager window](https://docs.unity3d.com/Manual/upm-ui.html), and choose to install from a Git URL, and use the URL https://github.com/oliverbooth/X10D.git#upm -The upm branch, however, is still available under version 2.6.0 - if you wish to use this version, add the package https://github.com/oliverbooth/X10D.git#upm to your Unity project. +Parity with the main branch of X10D, and full .NET 6 feature support, is planned - but a timeline is not yet available. Unity plan to add .NET 6 support in the near future. +For more information, see [this forum post](https://forum.unity.com/threads/unity-future-net-development-status.1092205/). ## Features I'm planning on writing complete and extensive documentation in the near future. As of this time, feel free to browse the source or the API using your favourite IDE. diff --git a/X10D.SourceGenerator/EmojiRegexGenerator.cs b/X10D.SourceGenerator/EmojiRegexGenerator.cs new file mode 100644 index 0000000..9b44b2f --- /dev/null +++ b/X10D.SourceGenerator/EmojiRegexGenerator.cs @@ -0,0 +1,68 @@ +using System.Text; +using System.Text.RegularExpressions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Text; + +namespace X10D.SourceGenerator; + +[Generator] +internal sealed class EmojiRegexGenerator : ISourceGenerator +{ + // ReSharper disable once IdentifierTypo + private const string TwemojiRegexUrl = "https://raw.githubusercontent.com/twitter/twemoji-parser/master/src/lib/regex.js"; + private static readonly HttpClient HttpClient = new(); + private string _emojiRegex = string.Empty; + + /// + public void Initialize(GeneratorInitializationContext context) + { + string response = HttpClient.GetStringAsync(TwemojiRegexUrl).GetAwaiter().GetResult(); + using var reader = new StringReader(response); + + while (reader.ReadLine() is { } line) + { + if (!line.StartsWith("export default /")) + { + continue; + } + + Match match = Regex.Match(line, @"export default /(?.+)/g;"); + if (!match.Success) + { + continue; + } + + _emojiRegex = $"^{match.Groups["regex"].Value}$"; + break; + } + } + + /// + public void Execute(GeneratorExecutionContext context) + { + if (string.IsNullOrEmpty(_emojiRegex)) + { + return; + } + + var builder = new StringBuilder(); + builder.AppendLine("// This file was auto-generated by X10D.SourceGenerator"); + builder.AppendLine("// Do not edit this file manually"); + builder.AppendLine(); + + builder.AppendLine("using System.Text.RegularExpressions;"); + builder.AppendLine(); + builder.AppendLine("namespace X10D.Text;"); + builder.AppendLine(); + builder.AppendLine("internal static class EmojiRegex"); + builder.AppendLine("{"); + builder.AppendLine(" internal static readonly Regex Value = new Regex("); + builder.AppendLine($" @\"{_emojiRegex}\","); + // ReSharper disable once StringLiteralTypo + builder.AppendLine(" RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.Singleline"); + builder.AppendLine(" );"); + builder.AppendLine("}"); + + context.AddSource("EmojiRegex.g.cs", SourceText.From(builder.ToString(), Encoding.UTF8)); + } +} diff --git a/X10D.SourceGenerator/X10D.SourceGenerator.csproj b/X10D.SourceGenerator/X10D.SourceGenerator.csproj new file mode 100644 index 0000000..8220df9 --- /dev/null +++ b/X10D.SourceGenerator/X10D.SourceGenerator.csproj @@ -0,0 +1,18 @@ + + + + netstandard2.0 + 10.0 + enable + enable + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/X10D.SourceValidator/Program.cs b/X10D.SourceValidator/Program.cs index 2f09427..2667598 100644 --- a/X10D.SourceValidator/Program.cs +++ b/X10D.SourceValidator/Program.cs @@ -1,64 +1,68 @@ using System.Text; -var directories = new Stack(Directory.GetDirectories(args[0])); var problems = 0; -var files = 0; - -while (directories.Count > 0) +foreach (string arg in args) { - string path = Path.GetFullPath(directories.Pop()); + var directories = new Stack(Directory.GetDirectories(arg)); + var files = 0; - foreach (string directory in Directory.EnumerateDirectories(path)) + while (directories.Count > 0) { - directories.Push(directory); - } + string path = Path.GetFullPath(directories.Pop()); - foreach (string file in Directory.EnumerateFiles(path, "*.cs")) - { - files++; - await using var stream = File.OpenRead(file); - using var reader = new StreamReader(stream, Encoding.UTF8); - var blankLine = false; - - var lineNumber = 1; - while (await reader.ReadLineAsync() is { } line) + foreach (string directory in Directory.EnumerateDirectories(path)) { - if (string.IsNullOrWhiteSpace(line)) + directories.Push(directory); + } + + foreach (string file in Directory.EnumerateFiles(path, "*.cs")) + { + files++; + await using var stream = File.OpenRead(file); + using var reader = new StreamReader(stream, Encoding.UTF8); + var blankLine = false; + + var lineNumber = 1; + while (await reader.ReadLineAsync() is { } line) { - if (blankLine) + if (string.IsNullOrWhiteSpace(line)) + { + if (blankLine) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.Out.WriteLine($"{file}({lineNumber}): Double blank line"); + Console.ResetColor(); + problems++; + } + + blankLine = true; + } + else + { + blankLine = false; + } + + if (line.Length > 130) { Console.ForegroundColor = ConsoleColor.Red; - Console.Out.WriteLine($"{file}({lineNumber}): Double blank line"); + Console.Out.WriteLine($"{file}({lineNumber}): Line is too long ({line.Length})"); + Console.ResetColor(); + problems++; + } + else if (line.Length > 0 && char.IsWhiteSpace(line[^1])) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.Out.WriteLine($"{file}({lineNumber}): Line contains trailing whitespace"); Console.ResetColor(); problems++; } - blankLine = true; + lineNumber++; } - else - { - blankLine = false; - } - - if (line.Length > 130) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.Out.WriteLine($"{file}({lineNumber}): Line is too long ({line.Length})"); - Console.ResetColor(); - problems++; - } - else if (line.Length > 0 && char.IsWhiteSpace(line[^1])) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.Out.WriteLine($"{file}({lineNumber}): Line contains trailing whitespace"); - Console.ResetColor(); - problems++; - } - - lineNumber++; } } + + Console.Out.WriteLine($"Finished scanning {files} files, {problems} problems encountered."); } -Console.Out.WriteLine($"Finished scanning {files} files, {problems} problems encountered."); return problems; diff --git a/X10D.Tests/X10D.Tests.csproj b/X10D.Tests/X10D.Tests.csproj index f6f97d4..6bba44b 100644 --- a/X10D.Tests/X10D.Tests.csproj +++ b/X10D.Tests/X10D.Tests.csproj @@ -1,7 +1,8 @@ - net6.0 + netstandard2.1;net6.0 + 10.0 false enable true diff --git a/X10D.Tests/src/Collections/ArrayTests.cs b/X10D.Tests/src/Collections/ArrayTests.cs index cc053ff..d5d745f 100644 --- a/X10D.Tests/src/Collections/ArrayTests.cs +++ b/X10D.Tests/src/Collections/ArrayTests.cs @@ -25,6 +25,7 @@ public class ArrayTests Assert.ThrowsException(array!.AsReadOnly); } + [CLSCompliant(false)] [TestMethod] [DataRow] [DataRow(1)] diff --git a/X10D.Tests/src/Collections/CollectionTests.cs b/X10D.Tests/src/Collections/CollectionTests.cs new file mode 100644 index 0000000..835a6d6 --- /dev/null +++ b/X10D.Tests/src/Collections/CollectionTests.cs @@ -0,0 +1,77 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Collections; + +namespace X10D.Tests.Collections; + +[TestClass] +public class CollectionTests +{ + [TestMethod] + public void ClearAndDisposeAll_ShouldDispose_GivenCollection() + { + var collection = new List {new(), new(), new()}; + var copy = new List(collection); + + collection.ClearAndDisposeAll(); + + Assert.IsTrue(copy.All(x => x.IsDisposed)); + Assert.AreEqual(0, collection.Count); + } + + [TestMethod] + public async Task ClearAndDisposeAllAsync_ShouldDispose_GivenCollection() + { + var collection = new List {new(), new(), new()}; + var copy = new List(collection); + + await collection.ClearAndDisposeAllAsync(); + + Assert.IsTrue(copy.All(x => x.IsDisposed)); + Assert.AreEqual(0, collection.Count); + } + + [TestMethod] + public void ClearAndDisposeAll_ShouldThrow_GivenNull() + { + List? collection = null; + Assert.ThrowsException(() => collection!.ClearAndDisposeAll()); + } + + [TestMethod] + public void ClearAndDisposeAllAsync_ShouldThrow_GivenNull() + { + List? collection = null; + Assert.ThrowsExceptionAsync(async () => await collection!.ClearAndDisposeAllAsync()); + } + + [TestMethod] + public void ClearAndDisposeAll_ShouldThrow_GivenReadOnlyCollection() + { + var collection = new List().AsReadOnly(); + Assert.ThrowsException(() => collection.ClearAndDisposeAll()); + } + + [TestMethod] + public void ClearAndDisposeAllAsync_ShouldThrow_GivenReadOnlyCollection() + { + var collection = new List().AsReadOnly(); + Assert.ThrowsExceptionAsync(async () => await collection.ClearAndDisposeAllAsync()); + } + + private class Disposable : IDisposable, IAsyncDisposable + { + public bool IsDisposed { get; private set; } + + public void Dispose() + { + Assert.IsTrue(IsDisposed = true); + } + +#pragma warning disable CS1998 + public async ValueTask DisposeAsync() +#pragma warning restore CS1998 + { + Assert.IsTrue(IsDisposed = true); + } + } +} diff --git a/X10D.Tests/src/Collections/EnumerableTests.cs b/X10D.Tests/src/Collections/EnumerableTests.cs index 6d990ee..533a00e 100644 --- a/X10D.Tests/src/Collections/EnumerableTests.cs +++ b/X10D.Tests/src/Collections/EnumerableTests.cs @@ -6,6 +6,94 @@ namespace X10D.Tests.Collections; [TestClass] public class EnumerableTests { + [TestMethod] + public void DisposeAll_ShouldDispose_GivenCollection() + { + var collection = new List {new(), new(), new()}; + collection.DisposeAll(); + Assert.IsTrue(collection.All(x => x.IsDisposed)); + } + + [TestMethod] + public async Task DisposeAllAsync_ShouldDispose_GivenCollection() + { + var collection = new List {new(), new(), new()}; + await collection.DisposeAllAsync(); + Assert.IsTrue(collection.All(x => x.IsDisposed)); + } + + [TestMethod] + public void DisposeAll_ShouldThrow_GivenNull() + { + List? collection = null; + Assert.ThrowsException(() => collection!.DisposeAll()); + } + + [TestMethod] + public async Task DisposeAllAsync_ShouldThrow_GivenNull() + { + List? collection = null; + await Assert.ThrowsExceptionAsync(async () => await collection!.DisposeAllAsync()); + } + + [TestMethod] + public void For_ShouldTransform_GivenTransformationDelegate() + { + var oneToTen = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + var multipliedByIndex = new[] {0, 2, 6, 12, 20, 30, 42, 56, 72, 90}; + + IEnumerable source = oneToTen.Select(i => new DummyClass {Value = i}).ToArray(); + IEnumerable values = source.Select(o => o.Value); + CollectionAssert.AreEqual(oneToTen, values.ToArray()); + + source.For((i, o) => o.Value *= i); + values = source.Select(o => o.Value); + CollectionAssert.AreEqual(multipliedByIndex, values.ToArray()); + } + + [TestMethod] + public void For_ShouldThrow_GivenNullSource() + { + IEnumerable? source = null; + Assert.ThrowsException(() => source!.For((_, _) => { })); + } + + [TestMethod] + public void For_ShouldThrow_GivenNullAction() + { + IEnumerable source = ArraySegment.Empty; + Assert.ThrowsException(() => source.For(null!)); + } + + [TestMethod] + public void ForEach_ShouldTransform_GivenTransformationDelegate() + { + var oneToTen = new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + var oneToTenDoubled = new[] {2, 4, 6, 8, 10, 12, 14, 16, 18, 20}; + + IEnumerable source = oneToTen.Select(i => new DummyClass {Value = i}).ToArray(); + IEnumerable values = source.Select(o => o.Value); + CollectionAssert.AreEqual(oneToTen, values.ToArray()); + + source.ForEach(o => o.Value *= 2); + values = source.Select(o => o.Value); + CollectionAssert.AreEqual(oneToTenDoubled, values.ToArray()); + } + + [TestMethod] + public void ForEach_ShouldThrow_GivenNullSource() + { + IEnumerable? source = null; + Assert.ThrowsException(() => source!.ForEach(_ => { })); + } + + [TestMethod] + public void ForEach_ShouldThrow_GivenNullAction() + { + IEnumerable source = ArraySegment.Empty; + Assert.ThrowsException(() => source.ForEach(null!)); + } + [TestMethod] public void Shuffled_ShouldThrow_GivenNull() { @@ -23,4 +111,26 @@ public class EnumerableTests shuffled = array.Shuffled().ToArray(); CollectionAssert.AreNotEqual(array, shuffled); } + + private class DummyClass + { + public int Value { get; set; } + } + + private class Disposable : IDisposable, IAsyncDisposable + { + public bool IsDisposed { get; private set; } + + public void Dispose() + { + Assert.IsTrue(IsDisposed = true); + } + +#pragma warning disable CS1998 + public async ValueTask DisposeAsync() +#pragma warning restore CS1998 + { + Assert.IsTrue(IsDisposed = true); + } + } } diff --git a/X10D.Tests/src/Collections/ListTests.cs b/X10D.Tests/src/Collections/ListTests.cs index 3be91f8..f62adc4 100644 --- a/X10D.Tests/src/Collections/ListTests.cs +++ b/X10D.Tests/src/Collections/ListTests.cs @@ -6,6 +6,7 @@ namespace X10D.Tests.Collections; [TestClass] public class ListTests { + [CLSCompliant(false)] [TestMethod] [DataRow(1)] [DataRow(1, 2, 3)] @@ -25,6 +26,7 @@ public class ListTests CollectionAssert.AreEqual(all42, list); } + [CLSCompliant(false)] [TestMethod] [DataRow(1)] [DataRow(1, 2, 3)] diff --git a/X10D.Tests/src/Core/EnumerableTests.cs b/X10D.Tests/src/Core/EnumerableTests.cs deleted file mode 100644 index 5b6deba..0000000 --- a/X10D.Tests/src/Core/EnumerableTests.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using X10D.Core; - -namespace X10D.Tests.Core; - -[TestClass] -public class EnumerableTests -{ - [TestMethod] - [DataRow(1)] - [DataRow("f")] - [DataRow(true)] - public void AsEnumerable_ShouldWrapElement_GivenValue(object o) - { - IEnumerable array = o.AsEnumerableValue().ToArray(); // prevent multiple enumeration of IEnumerable - Assert.IsNotNull(array); - Assert.IsTrue(array.Count() == 1); - Assert.AreEqual(o, array.ElementAt(0)); - } -} diff --git a/X10D.Tests/src/Drawing/ColorTests.cs b/X10D.Tests/src/Drawing/ColorTests.cs new file mode 100644 index 0000000..09c642c --- /dev/null +++ b/X10D.Tests/src/Drawing/ColorTests.cs @@ -0,0 +1,69 @@ +using System.Drawing; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Drawing; + +namespace X10D.Tests.Drawing; + +[TestClass] +public class ColorTests +{ + private static readonly Color Black = Color.FromArgb(0, 0, 0); + private static readonly Color White = Color.FromArgb(255, 255, 255); + private static readonly Color Red = Color.FromArgb(255, 0, 0); + private static readonly Color Green = Color.FromArgb(0, 255, 0); + private static readonly Color Blue = Color.FromArgb(0, 0, 255); + private static readonly Color Cyan = Color.FromArgb(0, 255, 255); + private static readonly Color Magenta = Color.FromArgb(255, 0, 255); + private static readonly Color Yellow = Color.FromArgb(255, 255, 0); + + [TestMethod] + public void Inverted_ShouldReturnInvertedColor() + { + Assert.AreEqual(White, Black.Inverted()); + Assert.AreEqual(Black, White.Inverted()); + Assert.AreEqual(Red, Cyan.Inverted()); + Assert.AreEqual(Cyan, Red.Inverted()); + Assert.AreEqual(Green, Magenta.Inverted()); + Assert.AreEqual(Magenta, Green.Inverted()); + Assert.AreEqual(Yellow, Blue.Inverted()); + Assert.AreEqual(Blue, Yellow.Inverted()); + } + + [TestMethod] + public void Inverted_ShouldIgnoreAlpha() + { + Color expected = Color.FromArgb(255, 0, 0, 0); + Color actual = Color.FromArgb(255, 255, 255, 255).Inverted(); + + Assert.AreEqual(expected, actual); + } + + [TestMethod] + public void WithA0_ShouldReturnSameColor_GivenWhite() + { + Color transparent = Color.FromArgb(0, 255, 255, 255); + Assert.AreEqual(transparent, White.WithA(0)); + Assert.AreEqual(transparent, transparent.WithA(0)); + } + + [TestMethod] + public void WithB0_ShouldReturnYellow_GivenWhite() + { + Assert.AreEqual(Yellow, White.WithB(0)); + Assert.AreEqual(Yellow, Yellow.WithB(0)); + } + + [TestMethod] + public void WithG0_ShouldReturnMagenta_GivenWhite() + { + Assert.AreEqual(Magenta, White.WithG(0)); + Assert.AreEqual(Magenta, Magenta.WithG(0)); + } + + [TestMethod] + public void WithR0_ShouldReturnCyan_GivenWhite() + { + Assert.AreEqual(Cyan, White.WithR(0)); + Assert.AreEqual(Cyan, Cyan.WithR(0)); + } +} diff --git a/X10D.Tests/src/Linq/ReadOnlySpanTests.cs b/X10D.Tests/src/Linq/ReadOnlySpanTests.cs index e33f5cd..4f2cbd9 100644 --- a/X10D.Tests/src/Linq/ReadOnlySpanTests.cs +++ b/X10D.Tests/src/Linq/ReadOnlySpanTests.cs @@ -55,4 +55,28 @@ public class ReadOnlySpanTests return span.Any(null!); }); } + + [TestMethod] + public void Count_ShouldReturn0_GivenEmptySpan() + { + var span = new ReadOnlySpan(); + Assert.AreEqual(0, span.Count(i => i % 2 == 0)); + } + + [TestMethod] + public void Count_ShouldReturn5_ForEvenNumbers_GivenNumbers1To10() + { + var span = new ReadOnlySpan(new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); + Assert.AreEqual(5, span.Count(i => i % 2 == 0)); + } + + [TestMethod] + public void Count_ShouldThrow_GivenNullPredicate() + { + Assert.ThrowsException(() => + { + var span = new ReadOnlySpan(); + return span.Count(null!); + }); + } } diff --git a/X10D.Tests/src/Linq/SByteExtensions.cs b/X10D.Tests/src/Linq/SByteTests.cs similarity index 63% rename from X10D.Tests/src/Linq/SByteExtensions.cs rename to X10D.Tests/src/Linq/SByteTests.cs index 59d01a7..3e360f9 100644 --- a/X10D.Tests/src/Linq/SByteExtensions.cs +++ b/X10D.Tests/src/Linq/SByteTests.cs @@ -12,12 +12,12 @@ public class SByteTests { sbyte Cast(int i) => (sbyte)i; - Assert.AreEqual(0, Enumerable.Range(0, 10).Product()); - Assert.AreEqual(1, Enumerable.Range(1, 1).Product()); - Assert.AreEqual(2, Enumerable.Range(1, 2).Product()); - Assert.AreEqual(6, Enumerable.Range(1, 3).Product()); - Assert.AreEqual(24, Enumerable.Range(1, 4).Product()); - Assert.AreEqual(120, Enumerable.Range(1, 5).Product()); + Assert.AreEqual(0, Enumerable.Range(0, 10).Select(Cast).Product()); + Assert.AreEqual(1, Enumerable.Range(1, 1).Select(Cast).Product()); + Assert.AreEqual(2, Enumerable.Range(1, 2).Select(Cast).Product()); + Assert.AreEqual(6, Enumerable.Range(1, 3).Select(Cast).Product()); + Assert.AreEqual(24, Enumerable.Range(1, 4).Select(Cast).Product()); + Assert.AreEqual(120, Enumerable.Range(1, 5).Select(Cast).Product()); // 6! will overflow for sbyte } diff --git a/X10D.Tests/src/Linq/SpanTests.cs b/X10D.Tests/src/Linq/SpanTests.cs index 98c5fe3..60882f4 100644 --- a/X10D.Tests/src/Linq/SpanTests.cs +++ b/X10D.Tests/src/Linq/SpanTests.cs @@ -55,4 +55,28 @@ public class SpanTests return span.Any(null!); }); } + + [TestMethod] + public void Count_ShouldReturn0_GivenEmptySpan() + { + var span = new Span(); + Assert.AreEqual(0, span.Count(i => i % 2 == 0)); + } + + [TestMethod] + public void Count_ShouldReturn5_ForEvenNumbers_GivenNumbers1To10() + { + var span = new Span(new[] {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}); + Assert.AreEqual(5, span.Count(i => i % 2 == 0)); + } + + [TestMethod] + public void Count_ShouldThrow_GivenNullPredicate() + { + Assert.ThrowsException(() => + { + var span = new Span(); + return span.Count(null!); + }); + } } diff --git a/X10D.Tests/src/Math/DecimalTests.cs b/X10D.Tests/src/Math/DecimalTests.cs index a8ce150..b84b1cf 100644 --- a/X10D.Tests/src/Math/DecimalTests.cs +++ b/X10D.Tests/src/Math/DecimalTests.cs @@ -7,6 +7,7 @@ namespace X10D.Tests.Math; [TestClass] public class DecimalTests { +#if NETCOREAPP3_0_OR_GREATER [TestMethod] public void ComplexSqrt_ShouldBeCorrect_GivenReal() { @@ -25,6 +26,7 @@ public class DecimalTests Assert.AreEqual(new Complex(0, 3.0), (-9.0m).ComplexSqrt()); Assert.AreEqual(new Complex(0, 4.0), (-16.0m).ComplexSqrt()); } +#endif [TestMethod] public void IsEven_ShouldBeFalse_GivenOddNumber() diff --git a/X10D.Tests/src/Math/DoubleTests.cs b/X10D.Tests/src/Math/DoubleTests.cs index 2496348..96034bc 100644 --- a/X10D.Tests/src/Math/DoubleTests.cs +++ b/X10D.Tests/src/Math/DoubleTests.cs @@ -29,6 +29,7 @@ public class DoubleTests Assert.AreEqual(12.0, 0.20943951023931953.RadiansToDegrees(), 1e-6); } +#if NETCOREAPP3_0_OR_GREATER [TestMethod] public void ComplexSqrt_ShouldBeCorrect_GivenReal() { @@ -60,6 +61,7 @@ public class DoubleTests { Assert.AreEqual(Complex.NaN, double.NaN.ComplexSqrt()); } +#endif [TestMethod] public void IsEven_ShouldBeFalse_GivenOddNumber() diff --git a/X10D.Tests/src/Math/SingleTests.cs b/X10D.Tests/src/Math/SingleTests.cs index 12b1ae2..82c2c0d 100644 --- a/X10D.Tests/src/Math/SingleTests.cs +++ b/X10D.Tests/src/Math/SingleTests.cs @@ -29,6 +29,7 @@ public class SingleTests Assert.AreEqual(12.0f, 0.20943952f.RadiansToDegrees(), 1e-6f); } +#if NETCOREAPP3_0_OR_GREATER [TestMethod] public void ComplexSqrt_ShouldBeCorrect_GivenReal() { @@ -60,6 +61,7 @@ public class SingleTests { Assert.AreEqual(Complex.NaN, float.NaN.ComplexSqrt()); } +#endif [TestMethod] public void IsEven_ShouldBeFalse_GivenOddNumber() diff --git a/X10D.Tests/src/Numerics/Vector2Tests.cs b/X10D.Tests/src/Numerics/Vector2Tests.cs new file mode 100644 index 0000000..72c1ddb --- /dev/null +++ b/X10D.Tests/src/Numerics/Vector2Tests.cs @@ -0,0 +1,37 @@ +using System.Numerics; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +public class Vector2Tests +{ + [TestMethod] + public void WithX_ShouldReturnVectorWithNewX_GivenVector() + { + Assert.AreEqual(Vector2.UnitY, Vector2.One.WithX(0)); + Assert.AreEqual(Vector2.Zero, Vector2.Zero.WithX(0)); + Assert.AreEqual(Vector2.Zero, Vector2.UnitX.WithX(0)); + Assert.AreEqual(Vector2.UnitY, Vector2.UnitY.WithX(0)); + + Assert.AreEqual(Vector2.One, Vector2.One.WithX(1)); + Assert.AreEqual(Vector2.UnitX, Vector2.Zero.WithX(1)); + Assert.AreEqual(Vector2.UnitX, Vector2.UnitX.WithX(1)); + Assert.AreEqual(Vector2.One, Vector2.UnitY.WithX(1)); + } + + [TestMethod] + public void WithY_ShouldReturnVectorWithNewY_GivenVector() + { + Assert.AreEqual(Vector2.UnitX, Vector2.One.WithY(0)); + Assert.AreEqual(Vector2.Zero, Vector2.Zero.WithY(0)); + Assert.AreEqual(Vector2.UnitX, Vector2.UnitX.WithY(0)); + Assert.AreEqual(Vector2.Zero, Vector2.UnitY.WithY(0)); + + Assert.AreEqual(Vector2.One, Vector2.One.WithY(1)); + Assert.AreEqual(Vector2.UnitY, Vector2.Zero.WithY(1)); + Assert.AreEqual(Vector2.One, Vector2.UnitX.WithY(1)); + Assert.AreEqual(Vector2.UnitY, Vector2.UnitY.WithY(1)); + } +} diff --git a/X10D.Tests/src/Numerics/Vector3Tests.cs b/X10D.Tests/src/Numerics/Vector3Tests.cs new file mode 100644 index 0000000..285a253 --- /dev/null +++ b/X10D.Tests/src/Numerics/Vector3Tests.cs @@ -0,0 +1,57 @@ +using System.Numerics; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +public class Vector3Tests +{ + [TestMethod] + public void WithX_ShouldReturnVectorWithNewX_GivenVector() + { + Assert.AreEqual(new Vector3(0, 1, 1), Vector3.One.WithX(0)); + Assert.AreEqual(Vector3.Zero, Vector3.Zero.WithX(0)); + Assert.AreEqual(Vector3.Zero, Vector3.UnitX.WithX(0)); + Assert.AreEqual(Vector3.UnitY, Vector3.UnitY.WithX(0)); + Assert.AreEqual(Vector3.UnitZ, Vector3.UnitZ.WithX(0)); + + Assert.AreEqual(Vector3.One, Vector3.One.WithX(1)); + Assert.AreEqual(Vector3.UnitX, Vector3.Zero.WithX(1)); + Assert.AreEqual(Vector3.UnitX, Vector3.UnitX.WithX(1)); + Assert.AreEqual(new Vector3(1, 1, 0), Vector3.UnitY.WithX(1)); + Assert.AreEqual(new Vector3(1, 0, 1), Vector3.UnitZ.WithX(1)); + } + + [TestMethod] + public void WithY_ShouldReturnVectorWithNewY_GivenVector() + { + Assert.AreEqual(new Vector3(1, 0, 1), Vector3.One.WithY(0)); + Assert.AreEqual(Vector3.Zero, Vector3.Zero.WithY(0)); + Assert.AreEqual(Vector3.UnitX, Vector3.UnitX.WithY(0)); + Assert.AreEqual(Vector3.Zero, Vector3.UnitY.WithY(0)); + Assert.AreEqual(Vector3.UnitZ, Vector3.UnitZ.WithY(0)); + + Assert.AreEqual(Vector3.One, Vector3.One.WithY(1)); + Assert.AreEqual(Vector3.UnitY, Vector3.Zero.WithY(1)); + Assert.AreEqual(new Vector3(1, 1, 0), Vector3.UnitX.WithY(1)); + Assert.AreEqual(Vector3.UnitY, Vector3.UnitY.WithY(1)); + Assert.AreEqual(new Vector3(0, 1, 1), Vector3.UnitZ.WithY(1)); + } + + [TestMethod] + public void WithZ_ShouldReturnVectorWithNewZ_GivenVector() + { + Assert.AreEqual(new Vector3(1, 1, 0), Vector3.One.WithZ(0)); + Assert.AreEqual(Vector3.Zero, Vector3.Zero.WithZ(0)); + Assert.AreEqual(Vector3.UnitX, Vector3.UnitX.WithZ(0)); + Assert.AreEqual(Vector3.UnitY, Vector3.UnitY.WithZ(0)); + Assert.AreEqual(Vector3.Zero, Vector3.UnitZ.WithZ(0)); + + Assert.AreEqual(Vector3.One, Vector3.One.WithZ(1)); + Assert.AreEqual(Vector3.UnitZ, Vector3.Zero.WithZ(1)); + Assert.AreEqual(new Vector3(1, 0, 1), Vector3.UnitX.WithZ(1)); + Assert.AreEqual(new Vector3(0, 1, 1), Vector3.UnitY.WithZ(1)); + Assert.AreEqual(Vector3.UnitZ, Vector3.UnitZ.WithZ(1)); + } +} diff --git a/X10D.Tests/src/Numerics/Vector4Tests.cs b/X10D.Tests/src/Numerics/Vector4Tests.cs new file mode 100644 index 0000000..4a0b927 --- /dev/null +++ b/X10D.Tests/src/Numerics/Vector4Tests.cs @@ -0,0 +1,81 @@ +using System.Numerics; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using X10D.Numerics; + +namespace X10D.Tests.Numerics; + +[TestClass] +public class Vector4Tests +{ + [TestMethod] + public void WithW_ShouldReturnVectorWithNewW_GivenVector() + { + Assert.AreEqual(new Vector4(1, 1, 1, 0), Vector4.One.WithW(0)); + Assert.AreEqual(Vector4.Zero, Vector4.Zero.WithW(0)); + Assert.AreEqual(Vector4.Zero, Vector4.UnitW.WithW(0)); + Assert.AreEqual(Vector4.UnitX, Vector4.UnitX.WithW(0)); + Assert.AreEqual(Vector4.UnitY, Vector4.UnitY.WithW(0)); + Assert.AreEqual(Vector4.UnitZ, Vector4.UnitZ.WithW(0)); + + Assert.AreEqual(Vector4.One, Vector4.One.WithW(1)); + Assert.AreEqual(Vector4.UnitW, Vector4.Zero.WithW(1)); + Assert.AreEqual(Vector4.UnitW, Vector4.UnitW.WithW(1)); + Assert.AreEqual(new Vector4(1, 0, 0, 1), Vector4.UnitX.WithW(1)); + Assert.AreEqual(new Vector4(0, 1, 0, 1), Vector4.UnitY.WithW(1)); + Assert.AreEqual(new Vector4(0, 0, 1, 1), Vector4.UnitZ.WithW(1)); + } + + [TestMethod] + public void WithX_ShouldReturnVectorWithNewX_GivenVector() + { + Assert.AreEqual(new Vector4(0, 1, 1, 1), Vector4.One.WithX(0)); + Assert.AreEqual(Vector4.Zero, Vector4.Zero.WithX(0)); + Assert.AreEqual(Vector4.UnitW, Vector4.UnitW.WithX(0)); + Assert.AreEqual(Vector4.Zero, Vector4.UnitX.WithX(0)); + Assert.AreEqual(Vector4.UnitY, Vector4.UnitY.WithX(0)); + Assert.AreEqual(Vector4.UnitZ, Vector4.UnitZ.WithX(0)); + + Assert.AreEqual(Vector4.One, Vector4.One.WithX(1)); + Assert.AreEqual(Vector4.UnitX, Vector4.Zero.WithX(1)); + Assert.AreEqual(new Vector4(1, 0, 0, 1), Vector4.UnitW.WithX(1)); + Assert.AreEqual(Vector4.UnitX, Vector4.UnitX.WithX(1)); + Assert.AreEqual(new Vector4(1, 1, 0, 0), Vector4.UnitY.WithX(1)); + Assert.AreEqual(new Vector4(1, 0, 1, 0), Vector4.UnitZ.WithX(1)); + } + + [TestMethod] + public void WithY_ShouldReturnVectorWithNewY_GivenVector() + { + Assert.AreEqual(new Vector4(1, 0, 1, 1), Vector4.One.WithY(0)); + Assert.AreEqual(Vector4.Zero, Vector4.Zero.WithY(0)); + Assert.AreEqual(Vector4.UnitW, Vector4.UnitW.WithY(0)); + Assert.AreEqual(Vector4.UnitX, Vector4.UnitX.WithY(0)); + Assert.AreEqual(Vector4.Zero, Vector4.UnitY.WithY(0)); + Assert.AreEqual(Vector4.UnitZ, Vector4.UnitZ.WithY(0)); + + Assert.AreEqual(Vector4.One, Vector4.One.WithY(1)); + Assert.AreEqual(Vector4.UnitY, Vector4.Zero.WithY(1)); + Assert.AreEqual(new Vector4(0, 1, 0, 1), Vector4.UnitW.WithY(1)); + Assert.AreEqual(new Vector4(1, 1, 0, 0), Vector4.UnitX.WithY(1)); + Assert.AreEqual(Vector4.UnitY, Vector4.UnitY.WithY(1)); + Assert.AreEqual(new Vector4(0, 1, 1, 0), Vector4.UnitZ.WithY(1)); + } + + [TestMethod] + public void WithZ_ShouldReturnVectorWithNewZ_GivenVector() + { + Assert.AreEqual(new Vector4(1, 1, 0, 1), Vector4.One.WithZ(0)); + Assert.AreEqual(Vector4.Zero, Vector4.Zero.WithZ(0)); + Assert.AreEqual(Vector4.UnitW, Vector4.UnitW.WithZ(0)); + Assert.AreEqual(Vector4.UnitX, Vector4.UnitX.WithZ(0)); + Assert.AreEqual(Vector4.UnitY, Vector4.UnitY.WithZ(0)); + Assert.AreEqual(Vector4.Zero, Vector4.UnitZ.WithZ(0)); + + Assert.AreEqual(Vector4.One, Vector4.One.WithZ(1)); + Assert.AreEqual(Vector4.UnitZ, Vector4.Zero.WithZ(1)); + Assert.AreEqual(new Vector4(0, 0, 1, 1), Vector4.UnitW.WithZ(1)); + Assert.AreEqual(new Vector4(1, 0, 1, 0), Vector4.UnitX.WithZ(1)); + Assert.AreEqual(new Vector4(0, 1, 1, 0), Vector4.UnitY.WithZ(1)); + Assert.AreEqual(Vector4.UnitZ, Vector4.UnitZ.WithZ(1)); + } +} diff --git a/X10D.Tests/src/Text/CharTests.cs b/X10D.Tests/src/Text/CharTests.cs index cea0606..7963f21 100644 --- a/X10D.Tests/src/Text/CharTests.cs +++ b/X10D.Tests/src/Text/CharTests.cs @@ -1,4 +1,5 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +using System.Text; +using Microsoft.VisualStudio.TestTools.UnitTesting; using X10D.Text; namespace X10D.Tests.Text; @@ -6,6 +7,25 @@ namespace X10D.Tests.Text; [TestClass] public class CharTests { + [TestMethod] + public void IsEmoji_ShouldReturnTrue_GivenBasicEmoji() + { + Assert.IsTrue('✂'.IsEmoji()); + Assert.IsTrue('✅'.IsEmoji()); + Assert.IsTrue('❎'.IsEmoji()); + Assert.IsTrue('➕'.IsEmoji()); + Assert.IsTrue('➖'.IsEmoji()); + } + + [TestMethod] + public void IsEmoji_ShouldReturnFalse_GivenNonEmoji() + { + for (var letter = 'A'; letter <= 'Z'; letter++) + { + Assert.IsFalse(letter.IsEmoji()); + } + } + [TestMethod] public void RepeatShouldBeCorrect() { diff --git a/X10D.Tests/src/Text/CoreTests.cs b/X10D.Tests/src/Text/CoreTests.cs index f6d9aea..6c4c58a 100644 --- a/X10D.Tests/src/Text/CoreTests.cs +++ b/X10D.Tests/src/Text/CoreTests.cs @@ -6,6 +6,7 @@ namespace X10D.Tests.Text; [TestClass] public class CoreTests { +#if NET5_0_OR_GREATER [TestMethod] public void ToJsonShouldNotBeEmpty() { @@ -23,4 +24,5 @@ public class CoreTests CollectionAssert.AreEqual(source, target); CollectionAssert.AreEquivalent(source, target); } +#endif } diff --git a/X10D.Tests/src/Text/RuneTests.cs b/X10D.Tests/src/Text/RuneTests.cs index 7d3315d..c8181b1 100644 --- a/X10D.Tests/src/Text/RuneTests.cs +++ b/X10D.Tests/src/Text/RuneTests.cs @@ -1,4 +1,5 @@ -using System.Text; +#if NETCOREAPP3_0_OR_GREATER +using System.Text; using Microsoft.VisualStudio.TestTools.UnitTesting; using X10D.Text; @@ -7,6 +8,25 @@ namespace X10D.Tests.Text; [TestClass] public class RuneTests { + [TestMethod] + public void IsEmoji_ShouldReturnTrue_GivenBasicEmoji() + { + Assert.IsTrue(new Rune('✂').IsEmoji()); + Assert.IsTrue(new Rune('✅').IsEmoji()); + Assert.IsTrue(new Rune('❎').IsEmoji()); + Assert.IsTrue(new Rune('➕').IsEmoji()); + Assert.IsTrue(new Rune('➖').IsEmoji()); + } + + [TestMethod] + public void IsEmoji_ShouldReturnFalse_GivenNonEmoji() + { + for (var letter = 'A'; letter <= 'Z'; letter++) + { + Assert.IsFalse(new Rune(letter).IsEmoji()); + } + } + [TestMethod] public void RepeatShouldBeCorrect() { @@ -37,3 +57,4 @@ public class RuneTests Assert.ThrowsException(() => new Rune('a').Repeat(-1)); } } +#endif diff --git a/X10D.Tests/src/Text/StringTests.cs b/X10D.Tests/src/Text/StringTests.cs index 5d509f0..fa99f40 100644 --- a/X10D.Tests/src/Text/StringTests.cs +++ b/X10D.Tests/src/Text/StringTests.cs @@ -1,5 +1,7 @@ using System.Text; +#if NET5_0_OR_GREATER using System.Text.Json.Serialization; +#endif using Microsoft.VisualStudio.TestTools.UnitTesting; using X10D.Text; @@ -149,6 +151,7 @@ public class StringTests Assert.ThrowsException(() => " ".EnumParse()); } +#if NET5_0_OR_GREATER [TestMethod] public void FromJson_ShouldDeserializeCorrectly_GivenJsonString() { @@ -162,6 +165,7 @@ public class StringTests Assert.AreEqual(2, target.Values[1]); Assert.AreEqual(3, target.Values[2]); } +#endif [TestMethod] public void GetBytes_ShouldReturnUtf8Bytes_GivenHelloWorld() @@ -195,6 +199,44 @@ public class StringTests Assert.ThrowsException(() => "Hello World".GetBytes(null!)); } + [TestMethod] + public void IsEmoji_ShouldReturnTrue_GivenBasicEmoji() + { + Assert.IsTrue("😀".IsEmoji()); + Assert.IsTrue("🤓".IsEmoji()); + Assert.IsTrue("🟦".IsEmoji()); + Assert.IsTrue("🟧".IsEmoji()); + Assert.IsTrue("🟨".IsEmoji()); + Assert.IsTrue("🟩".IsEmoji()); + Assert.IsTrue("🟪".IsEmoji()); + Assert.IsTrue("🟫".IsEmoji()); + Assert.IsTrue("📱".IsEmoji()); + Assert.IsTrue("🎨".IsEmoji()); + } + + [TestMethod] + public void IsEmoji_ShouldReturnTrue_GivenMultiByteEmoji() + { + string[] regionalIndicatorCodes = Enumerable.Range(0, 26) + .Select(i => Encoding.Unicode.GetString(new byte[] {0x3C, 0xD8, (byte)(0xE6 + i), 0xDD})) + .ToArray(); + + for (var i = 0; i < 26; i++) + for (var j = 0; j < 26; j++) + { + string flag = (regionalIndicatorCodes[i] + regionalIndicatorCodes[j]); + Assert.IsTrue(flag.IsEmoji()); + } + } + + [TestMethod] + public void IsEmoji_ShouldReturnFalse_GivenNonEmoji() + { + Assert.IsFalse("Hello World".IsEmoji()); + Assert.IsFalse("Hello".IsEmoji()); + Assert.IsFalse("World".IsEmoji()); + } + [TestMethod] public void IsLower_ShouldReturnTrue_GivenLowercaseString() { @@ -441,9 +483,11 @@ public class StringTests Assert.AreEqual(alternative, ((string?)null).WithWhiteSpaceAlternative(alternative)); } +#if NET5_0_OR_GREATER private struct SampleStructure { [JsonPropertyName("values")] public int[] Values { get; set; } } +#endif } diff --git a/X10D.Tests/src/Time/DoubleTests.cs b/X10D.Tests/src/Time/DoubleTests.cs index 17c7f2e..799c1b1 100644 --- a/X10D.Tests/src/Time/DoubleTests.cs +++ b/X10D.Tests/src/Time/DoubleTests.cs @@ -1,4 +1,5 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; +#if NET5_0_OR_GREATER +using Microsoft.VisualStudio.TestTools.UnitTesting; using X10D.Time; namespace X10D.Tests.Time; @@ -51,3 +52,4 @@ public class DoubleTests Assert.IsTrue((_negativeOne).Weeks() < TimeSpan.Zero); } } +#endif diff --git a/X10D.Unity.Tests/.gitignore b/X10D.Unity.Tests/.gitignore new file mode 100644 index 0000000..58cbc82 --- /dev/null +++ b/X10D.Unity.Tests/.gitignore @@ -0,0 +1,72 @@ +# This .gitignore file should be placed at the root of your Unity project directory +# +# Get latest from https://github.com/github/gitignore/blob/main/Unity.gitignore +# +/[Ll]ibrary/ +/[Tt]emp/ +/[Oo]bj/ +/[Bb]uild/ +/[Bb]uilds/ +/[Ll]ogs/ +/[Uu]ser[Ss]ettings/ + +# MemoryCaptures can get excessive in size. +# They also could contain extremely sensitive data +/[Mm]emoryCaptures/ + +# Recordings can get excessive in size +/[Rr]ecordings/ + +# Uncomment this line if you wish to ignore the asset store tools plugin +# /[Aa]ssets/AssetStoreTools* + +# Autogenerated Jetbrains Rider plugin +/[Aa]ssets/Plugins/Editor/JetBrains* + +# Visual Studio cache directory +.vs/ + +# Gradle cache directory +.gradle/ + +# Autogenerated VS/MD/Consulo solution and project files +ExportedObj/ +.consulo/ +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db + +# Unity3D generated meta files +*.pidb.meta +*.pdb.meta +*.mdb.meta + +# Unity3D generated file on crash reports +sysinfo.txt + +# Builds +*.apk +*.aab +*.unitypackage +*.app + +# Crashlytics generated file +crashlytics-build.properties + +# Packed Addressables +/[Aa]ssets/[Aa]ddressable[Aa]ssets[Dd]ata/*/*.bin* + +# Temporary auto-generated Android Assets +/[Aa]ssets/[Ss]treamingAssets/aa.meta +/[Aa]ssets/[Ss]treamingAssets/aa/* diff --git a/X10D.Unity.Tests/Assets/Scenes.meta b/X10D.Unity.Tests/Assets/Scenes.meta new file mode 100644 index 0000000..83c741b --- /dev/null +++ b/X10D.Unity.Tests/Assets/Scenes.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 6ea315d0fd7389c41b19996891e99ae3 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/X10D.Unity.Tests/Assets/Scenes/SampleScene.unity b/X10D.Unity.Tests/Assets/Scenes/SampleScene.unity new file mode 100644 index 0000000..2221b04 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Scenes/SampleScene.unity @@ -0,0 +1,267 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!29 &1 +OcclusionCullingSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_OcclusionBakeSettings: + smallestOccluder: 5 + smallestHole: 0.25 + backfaceThreshold: 100 + m_SceneGUID: 00000000000000000000000000000000 + m_OcclusionCullingData: {fileID: 0} +--- !u!104 &2 +RenderSettings: + m_ObjectHideFlags: 0 + serializedVersion: 9 + m_Fog: 0 + m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} + m_FogMode: 3 + m_FogDensity: 0.01 + m_LinearFogStart: 0 + m_LinearFogEnd: 300 + m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} + m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} + m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} + m_AmbientIntensity: 1 + m_AmbientMode: 0 + m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} + m_SkyboxMaterial: {fileID: 10304, guid: 0000000000000000f000000000000000, type: 0} + m_HaloStrength: 0.5 + m_FlareStrength: 1 + m_FlareFadeSpeed: 3 + m_HaloTexture: {fileID: 0} + m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} + m_DefaultReflectionMode: 0 + m_DefaultReflectionResolution: 128 + m_ReflectionBounces: 1 + m_ReflectionIntensity: 1 + m_CustomReflection: {fileID: 0} + m_Sun: {fileID: 705507994} + m_IndirectSpecularColor: {r: 0, g: 0, b: 0, a: 1} + m_UseRadianceAmbientProbe: 0 +--- !u!157 &3 +LightmapSettings: + m_ObjectHideFlags: 0 + serializedVersion: 12 + m_GIWorkflowMode: 1 + m_GISettings: + serializedVersion: 2 + m_BounceScale: 1 + m_IndirectOutputScale: 1 + m_AlbedoBoost: 1 + m_EnvironmentLightingMode: 0 + m_EnableBakedLightmaps: 1 + m_EnableRealtimeLightmaps: 0 + m_LightmapEditorSettings: + serializedVersion: 12 + m_Resolution: 2 + m_BakeResolution: 40 + m_AtlasSize: 1024 + m_AO: 0 + m_AOMaxDistance: 1 + m_CompAOExponent: 1 + m_CompAOExponentDirect: 0 + m_ExtractAmbientOcclusion: 0 + m_Padding: 2 + m_LightmapParameters: {fileID: 0} + m_LightmapsBakeMode: 1 + m_TextureCompression: 1 + m_FinalGather: 0 + m_FinalGatherFiltering: 1 + m_FinalGatherRayCount: 256 + m_ReflectionCompression: 2 + m_MixedBakeMode: 2 + m_BakeBackend: 1 + m_PVRSampling: 1 + m_PVRDirectSampleCount: 32 + m_PVRSampleCount: 500 + m_PVRBounces: 2 + m_PVREnvironmentSampleCount: 500 + m_PVREnvironmentReferencePointCount: 2048 + m_PVRFilteringMode: 2 + m_PVRDenoiserTypeDirect: 0 + m_PVRDenoiserTypeIndirect: 0 + m_PVRDenoiserTypeAO: 0 + m_PVRFilterTypeDirect: 0 + m_PVRFilterTypeIndirect: 0 + m_PVRFilterTypeAO: 0 + m_PVREnvironmentMIS: 0 + m_PVRCulling: 1 + m_PVRFilteringGaussRadiusDirect: 1 + m_PVRFilteringGaussRadiusIndirect: 5 + m_PVRFilteringGaussRadiusAO: 2 + m_PVRFilteringAtrousPositionSigmaDirect: 0.5 + m_PVRFilteringAtrousPositionSigmaIndirect: 2 + m_PVRFilteringAtrousPositionSigmaAO: 1 + m_ExportTrainingData: 0 + m_TrainingDataDestination: TrainingData + m_LightProbeSampleCountMultiplier: 4 + m_LightingDataAsset: {fileID: 0} + m_LightingSettings: {fileID: 0} +--- !u!196 &4 +NavMeshSettings: + serializedVersion: 2 + m_ObjectHideFlags: 0 + m_BuildSettings: + serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.4 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_NavMeshData: {fileID: 0} +--- !u!1 &705507993 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 705507995} + - component: {fileID: 705507994} + m_Layer: 0 + m_Name: Directional Light + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!108 &705507994 +Light: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 705507993} + m_Enabled: 1 + serializedVersion: 8 + m_Type: 1 + m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} + m_Intensity: 1 + m_Range: 10 + m_SpotAngle: 30 + m_CookieSize: 10 + m_Shadows: + m_Type: 2 + m_Resolution: -1 + m_CustomResolution: -1 + m_Strength: 1 + m_Bias: 0.05 + m_NormalBias: 0.4 + m_NearPlane: 0.2 + m_Cookie: {fileID: 0} + m_DrawHalo: 0 + m_Flare: {fileID: 0} + m_RenderMode: 0 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_Lightmapping: 1 + m_LightShadowCasterMode: 0 + m_AreaSize: {x: 1, y: 1} + m_BounceIntensity: 1 + m_ColorTemperature: 6570 + m_UseColorTemperature: 0 + m_ShadowRadius: 0 + m_ShadowAngle: 0 +--- !u!4 &705507995 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 705507993} + m_LocalRotation: {x: 0.40821788, y: -0.23456968, z: 0.10938163, w: 0.8754261} + m_LocalPosition: {x: 0, y: 3, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 1 + m_LocalEulerAnglesHint: {x: 50, y: -30, z: 0} +--- !u!1 &963194225 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 963194228} + - component: {fileID: 963194227} + - component: {fileID: 963194226} + m_Layer: 0 + m_Name: Main Camera + m_TagString: MainCamera + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!81 &963194226 +AudioListener: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 +--- !u!20 &963194227 +Camera: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_Enabled: 1 + serializedVersion: 2 + m_ClearFlags: 1 + m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} + m_projectionMatrixMode: 1 + m_SensorSize: {x: 36, y: 24} + m_LensShift: {x: 0, y: 0} + m_GateFitMode: 2 + m_FocalLength: 50 + m_NormalizedViewPortRect: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + near clip plane: 0.3 + far clip plane: 1000 + field of view: 60 + orthographic: 0 + orthographic size: 5 + m_Depth: -1 + m_CullingMask: + serializedVersion: 2 + m_Bits: 4294967295 + m_RenderingPath: -1 + m_TargetTexture: {fileID: 0} + m_TargetDisplay: 0 + m_TargetEye: 3 + m_HDR: 1 + m_AllowMSAA: 1 + m_AllowDynamicResolution: 0 + m_ForceIntoRT: 0 + m_OcclusionCulling: 1 + m_StereoConvergence: 10 + m_StereoSeparation: 0.022 +--- !u!4 &963194228 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInternal: {fileID: 0} + m_GameObject: {fileID: 963194225} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 1, z: -10} + m_LocalScale: {x: 1, y: 1, z: 1} + m_Children: [] + m_Father: {fileID: 0} + m_RootOrder: 0 + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} diff --git a/X10D.Unity.Tests/Assets/Scenes/SampleScene.unity.meta b/X10D.Unity.Tests/Assets/Scenes/SampleScene.unity.meta new file mode 100644 index 0000000..952bd1e --- /dev/null +++ b/X10D.Unity.Tests/Assets/Scenes/SampleScene.unity.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 9fc0d4010bbf28b4594072e72b8655ab +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/X10D.Unity.Tests/Assets/Tests.meta b/X10D.Unity.Tests/Assets/Tests.meta new file mode 100644 index 0000000..01f5869 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 478095eaef020f34ea189f98c9369aab +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/X10D.Unity.Tests/Assets/Tests/ComponentTests.cs b/X10D.Unity.Tests/Assets/Tests/ComponentTests.cs new file mode 100644 index 0000000..c77f83e --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/ComponentTests.cs @@ -0,0 +1,29 @@ +#nullable enable + +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace X10D.Unity.Tests +{ + public class ComponentTests + { + [UnityTest] + public IEnumerator GetComponentsInChildrenOnly_ShouldIgnoreParent() + { + var parent = new GameObject(); + var rigidbody = parent.AddComponent(); + + var child = new GameObject(); + child.transform.SetParent(parent.transform); + child.AddComponent(); + + Rigidbody[] components = rigidbody.GetComponentsInChildrenOnly(); + Assert.AreEqual(1, components.Length); + Assert.AreEqual(components[0].gameObject, child); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/ComponentTests.cs.meta b/X10D.Unity.Tests/Assets/Tests/ComponentTests.cs.meta new file mode 100644 index 0000000..a5fe42b --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/ComponentTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0619dbb274114e4aa247ed8f4e7cff03 +timeCreated: 1652006240 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Drawing.meta b/X10D.Unity.Tests/Assets/Tests/Drawing.meta new file mode 100644 index 0000000..43ccd4b --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Drawing.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 9674f5a2171d4c7d88cbfe9f1249bb27 +timeCreated: 1652006440 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Drawing/Color32Tests.cs b/X10D.Unity.Tests/Assets/Tests/Drawing/Color32Tests.cs new file mode 100644 index 0000000..ec25662 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Drawing/Color32Tests.cs @@ -0,0 +1,83 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using X10D.Unity.Drawing; + +namespace X10D.Unity.Tests.Drawing +{ + public class Color32Tests + { + private static readonly Color32 Black = new(0, 0, 0, 1); + private static readonly Color32 White = new(255, 255, 255, 1); + private static readonly Color32 Red = new(255, 0, 0, 1); + private static readonly Color32 Green = new(0, 255, 0, 1); + private static readonly Color32 Blue = new(0, 0, 255, 1); + private static readonly Color32 Cyan = new(0, 255, 255, 1); + private static readonly Color32 Magenta = new(255, 0, 255, 1); + private static readonly Color32 Yellow = new(255, 255, 0, 1); + + [UnityTest] + public IEnumerator Inverted_ShouldReturnInvertedColor() + { + Assert.AreEqual(White, Black.Inverted()); + Assert.AreEqual(Black, White.Inverted()); + Assert.AreEqual(Red, Cyan.Inverted()); + Assert.AreEqual(Cyan, Red.Inverted()); + Assert.AreEqual(Green, Magenta.Inverted()); + Assert.AreEqual(Magenta, Green.Inverted()); + Assert.AreEqual(Yellow, Blue.Inverted()); + Assert.AreEqual(Blue, Yellow.Inverted()); + + yield break; + } + + [UnityTest] + public IEnumerator Inverted_ShouldIgnoreAlpha() + { + var expected = new Color32(0, 0, 0, 255); + var actual = new Color32(255, 255, 255, 255).Inverted(); + + Assert.AreEqual(expected, actual); + + yield break; + } + + [UnityTest] + public IEnumerator WithA0_ShouldReturnSameColor_GivenWhite() + { + var transparent = new Color32(255, 255, 255, 0); + Assert.AreEqual(transparent, White.WithA(0)); + Assert.AreEqual(transparent, transparent.WithA(0)); + + yield break; + } + + [UnityTest] + public IEnumerator WithB0_ShouldReturnYellow_GivenWhite() + { + Assert.AreEqual(Yellow, White.WithB(0)); + Assert.AreEqual(Yellow, Yellow.WithB(0)); + + yield break; + } + + [UnityTest] + public IEnumerator WithG0_ShouldReturnMagenta_GivenWhite() + { + Assert.AreEqual(Magenta, White.WithG(0)); + Assert.AreEqual(Magenta, Magenta.WithG(0)); + + yield break; + } + + [UnityTest] + public IEnumerator WithR0_ShouldReturnCyan_GivenWhite() + { + Assert.AreEqual(Cyan, White.WithR(0)); + Assert.AreEqual(Cyan, Cyan.WithR(0)); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/Drawing/Color32Tests.cs.meta b/X10D.Unity.Tests/Assets/Tests/Drawing/Color32Tests.cs.meta new file mode 100644 index 0000000..6a819da --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Drawing/Color32Tests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 877c5a68b0dd44c68aae01463ae26b26 +timeCreated: 1652035626 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Drawing/ColorTests.cs b/X10D.Unity.Tests/Assets/Tests/Drawing/ColorTests.cs new file mode 100644 index 0000000..c27ad2c --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Drawing/ColorTests.cs @@ -0,0 +1,83 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using X10D.Unity.Drawing; + +namespace X10D.Unity.Tests.Drawing +{ + public class ColorTests + { + private static readonly Color Black = new(0, 0, 0); + private static readonly Color White = new(1, 1, 1); + private static readonly Color Red = new(1, 0, 0); + private static readonly Color Green = new(0, 1, 0); + private static readonly Color Blue = new(0, 0, 1); + private static readonly Color Cyan = new(0, 1, 1); + private static readonly Color Magenta = new(1, 0, 1); + private static readonly Color Yellow = new(1, 1, 0); + + [UnityTest] + public IEnumerator Inverted_ShouldReturnInvertedColor() + { + Assert.AreEqual(White, Black.Inverted()); + Assert.AreEqual(Black, White.Inverted()); + Assert.AreEqual(Red, Cyan.Inverted()); + Assert.AreEqual(Cyan, Red.Inverted()); + Assert.AreEqual(Green, Magenta.Inverted()); + Assert.AreEqual(Magenta, Green.Inverted()); + Assert.AreEqual(Yellow, Blue.Inverted()); + Assert.AreEqual(Blue, Yellow.Inverted()); + + yield break; + } + + [UnityTest] + public IEnumerator Inverted_ShouldIgnoreAlpha() + { + var expected = new Color(0, 0, 0, 1); + var actual = new Color(1, 1, 1, 1).Inverted(); + + Assert.AreEqual(expected, actual); + + yield break; + } + + [UnityTest] + public IEnumerator WithA0_ShouldReturnSameColor_GivenWhite() + { + var transparent = new Color(1, 1, 1, 0); + Assert.AreEqual(transparent, White.WithA(0)); + Assert.AreEqual(transparent, transparent.WithA(0)); + + yield break; + } + + [UnityTest] + public IEnumerator WithB0_ShouldReturnYellow_GivenWhite() + { + Assert.AreEqual(Yellow, White.WithB(0)); + Assert.AreEqual(Yellow, Yellow.WithB(0)); + + yield break; + } + + [UnityTest] + public IEnumerator WithG0_ShouldReturnMagenta_GivenWhite() + { + Assert.AreEqual(Magenta, White.WithG(0)); + Assert.AreEqual(Magenta, Magenta.WithG(0)); + + yield break; + } + + [UnityTest] + public IEnumerator WithR0_ShouldReturnCyan_GivenWhite() + { + Assert.AreEqual(Cyan, White.WithR(0)); + Assert.AreEqual(Cyan, Cyan.WithR(0)); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/Drawing/ColorTests.cs.meta b/X10D.Unity.Tests/Assets/Tests/Drawing/ColorTests.cs.meta new file mode 100644 index 0000000..8ab4670 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Drawing/ColorTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 61df0ae6778a4ab084e688f13adfc29c +timeCreated: 1652035747 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Drawing/RandomTests.cs b/X10D.Unity.Tests/Assets/Tests/Drawing/RandomTests.cs new file mode 100644 index 0000000..33c69e9 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Drawing/RandomTests.cs @@ -0,0 +1,87 @@ +#nullable enable + +using System; +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using X10D.Unity.Drawing; +using Random = System.Random; + +namespace X10D.Unity.Tests.Drawing +{ + public class RandomTests + { + [UnityTest] + public IEnumerator NextColorArgb_ShouldReturn331515e5_GivenSeed1234() + { + var random = new Random(1234); + var color = random.NextColorArgb(); + Assert.AreEqual(0.373868465f, color.r, 1e-6f); + Assert.AreEqual(0.391597569f, color.g, 1e-6f); + Assert.AreEqual(0.675019085f, color.b, 1e-6f); + Assert.AreEqual(0.234300315f, color.a, 1e-6f); + yield break; + } + + [UnityTest] + public IEnumerator NextColorArgb_ShouldThrow_GivenNull() + { + Random? random = null; + Assert.Throws(() => random!.NextColorArgb()); + yield break; + } + + [UnityTest] + public IEnumerator NextColor32Argb_ShouldReturn331515e5_GivenSeed1234() + { + var random = new Random(1234); + Assert.AreEqual(new Color32(21, 21, 229, 51), random.NextColor32Argb()); + yield break; + } + + [UnityTest] + public IEnumerator NextColor32Argb_ShouldThrow_GivenNull() + { + Random? random = null; + Assert.Throws(() => random!.NextColor32Argb()); + yield break; + } + + [UnityTest] + public IEnumerator NextColorRgb_ShouldReturn1515e5_GivenSeed1234() + { + var random = new Random(1234); + var color = random.NextColorRgb(); + Assert.AreEqual(0.234300315f, color.r, 1e-6f); + Assert.AreEqual(0.373868465f, color.g, 1e-6f); + Assert.AreEqual(0.391597569f, color.b, 1e-6f); + Assert.AreEqual(1, color.a, 1e-6f); + yield break; + } + + [UnityTest] + public IEnumerator NextColorRgb_ShouldThrow_GivenNull() + { + Random? random = null; + Assert.Throws(() => random!.NextColorRgb()); + yield break; + } + + [UnityTest] + public IEnumerator NextColor32Rgb_ShouldReturn1515e5_GivenSeed1234() + { + var random = new Random(1234); + Assert.AreEqual(new Color32(21, 21, 229, 255), random.NextColor32Rgb()); + yield break; + } + + [UnityTest] + public IEnumerator NextColor32Rgb_ShouldThrow_GivenNull() + { + Random? random = null; + Assert.Throws(() => random!.NextColor32Rgb()); + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/Drawing/RandomTests.cs.meta b/X10D.Unity.Tests/Assets/Tests/Drawing/RandomTests.cs.meta new file mode 100644 index 0000000..d190fdb --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Drawing/RandomTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 28fa03c101834cd79774d8138b9d4adb +timeCreated: 1652006445 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/GameObjectTests.cs b/X10D.Unity.Tests/Assets/Tests/GameObjectTests.cs new file mode 100644 index 0000000..79e649e --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/GameObjectTests.cs @@ -0,0 +1,109 @@ +#nullable enable + +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace X10D.Unity.Tests +{ + public class GameObjectTests + { + [UnityTest] + public IEnumerator GetComponentsInChildrenOnly_ShouldIgnoreParent() + { + var parent = new GameObject(); + parent.AddComponent(); + + var child = new GameObject(); + child.transform.SetParent(parent.transform); + child.AddComponent(); + + Rigidbody[] components = parent.GetComponentsInChildrenOnly(); + Assert.AreEqual(1, components.Length); + Assert.AreEqual(components[0].gameObject, child); + + yield break; + } + + [UnityTest] + public IEnumerator LookAt_ShouldRotateSameAsTransform() + { + var first = new GameObject {transform = {position = Vector3.zero, rotation = Quaternion.identity}}; + var second = new GameObject {transform = {position = Vector3.right, rotation = Quaternion.identity}}; + Transform firstTransform = first.transform; + Transform secondTransform = second.transform; + + Assert.AreEqual(Quaternion.identity, firstTransform.rotation); + Assert.AreEqual(Quaternion.identity, secondTransform.rotation); + + firstTransform.LookAt(secondTransform); + Quaternion expected = firstTransform.rotation; + + firstTransform.rotation = Quaternion.identity; + Assert.AreEqual(Quaternion.identity, firstTransform.rotation); + + first.LookAt(second); + Assert.AreEqual(expected, firstTransform.rotation); + + firstTransform.rotation = Quaternion.identity; + Assert.AreEqual(Quaternion.identity, firstTransform.rotation); + + first.LookAt(second.transform); + Assert.AreEqual(expected, firstTransform.rotation); + + firstTransform.rotation = Quaternion.identity; + Assert.AreEqual(Quaternion.identity, firstTransform.rotation); + + first.LookAt(Vector3.right); + Assert.AreEqual(expected, firstTransform.rotation); + + yield break; + } + + [UnityTest] + public IEnumerator SetLayerRecursively_ShouldSetLayerRecursively() + { + var parent = new GameObject(); + var child = new GameObject(); + var grandChild = new GameObject(); + + child.transform.SetParent(parent.transform); + grandChild.transform.SetParent(child.transform); + + int layer = LayerMask.NameToLayer("UI"); + Assert.AreNotEqual(layer, parent.layer); + Assert.AreNotEqual(layer, child.layer); + Assert.AreNotEqual(layer, grandChild.layer); + + parent.SetLayerRecursively(layer); + + Assert.AreEqual(layer, parent.layer); + Assert.AreEqual(layer, child.layer); + Assert.AreEqual(layer, grandChild.layer); + + yield break; + } + + [UnityTest] + public IEnumerator SetParent_ShouldSetParent() + { + var first = new GameObject {transform = {position = Vector3.zero, rotation = Quaternion.identity}}; + var second = new GameObject {transform = {position = Vector3.right, rotation = Quaternion.identity}}; + + Assert.AreEqual(null, first.transform.parent); + Assert.AreEqual(null, second.transform.parent); + + first.SetParent(second); + Assert.AreEqual(second.transform, first.transform.parent); + + first.transform.SetParent(null!); + Assert.AreEqual(null, first.transform.parent); + + second.SetParent(first); + Assert.AreEqual(first.transform, second.transform.parent); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/GameObjectTests.cs.meta b/X10D.Unity.Tests/Assets/Tests/GameObjectTests.cs.meta new file mode 100644 index 0000000..7cad365 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/GameObjectTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1fde6c311eaec944abe1e4531a2980bc +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics.meta b/X10D.Unity.Tests/Assets/Tests/Numerics.meta new file mode 100644 index 0000000..3410bae --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: c906e39e3c8d44c7a8dafe042fedf677 +timeCreated: 1652006420 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/QuaternionTests.cs b/X10D.Unity.Tests/Assets/Tests/Numerics/QuaternionTests.cs new file mode 100644 index 0000000..a486a75 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/QuaternionTests.cs @@ -0,0 +1,53 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using X10D.Core; +using X10D.Unity.Numerics; +using Random = System.Random; + +namespace X10D.Unity.Tests.Numerics +{ + public class QuaternionTests + { + [UnityTest] + public IEnumerator ToSystemQuaternion_ShouldReturnQuaternion_WithEqualComponents() + { + var random = new Random(); + float x = random.NextSingle(); + float y = random.NextSingle(); + float z = random.NextSingle(); + float w = random.NextSingle(); + + var quaternion = new Quaternion(x, y, z, w); + var systemQuaternion = quaternion.ToSystemQuaternion(); + + Assert.AreEqual(quaternion.x, systemQuaternion.X, 1e-6f); + Assert.AreEqual(quaternion.y, systemQuaternion.Y, 1e-6f); + Assert.AreEqual(quaternion.z, systemQuaternion.Z, 1e-6f); + Assert.AreEqual(quaternion.w, systemQuaternion.W, 1e-6f); + + yield break; + } + + [UnityTest] + public IEnumerator ToUnityQuaternion_ShouldReturnQuaternion_WithEqualComponents() + { + var random = new Random(); + float x = random.NextSingle(); + float y = random.NextSingle(); + float z = random.NextSingle(); + float w = random.NextSingle(); + + var quaternion = new System.Numerics.Quaternion(x, y, z, w); + var unityQuaternion = quaternion.ToUnityQuaternion(); + + Assert.AreEqual(quaternion.X, unityQuaternion.x, 1e-6f); + Assert.AreEqual(quaternion.Y, unityQuaternion.y, 1e-6f); + Assert.AreEqual(quaternion.Z, unityQuaternion.z, 1e-6f); + Assert.AreEqual(quaternion.W, unityQuaternion.w, 1e-6f); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/QuaternionTests.cs.meta b/X10D.Unity.Tests/Assets/Tests/Numerics/QuaternionTests.cs.meta new file mode 100644 index 0000000..a8117be --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/QuaternionTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a395fec41c5a4e9d9ffb05324e8159b0 +timeCreated: 1652124913 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/RandomTests.cs b/X10D.Unity.Tests/Assets/Tests/Numerics/RandomTests.cs new file mode 100644 index 0000000..4d768c2 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/RandomTests.cs @@ -0,0 +1,63 @@ +#nullable enable + +using System; +using System.Collections; +using NUnit.Framework; +using UnityEngine.TestTools; +using X10D.Unity.Numerics; + +namespace X10D.Unity.Tests.Numerics +{ + public class RandomTests + { + [UnityTest] + public IEnumerator NextUnitVector2_ShouldReturnVector_WithMagnitude1() + { + var random = new Random(); + var vector = random.NextUnitVector2(); + Assert.AreEqual(1, vector.magnitude, 1e-6); + yield break; + } + + [UnityTest] + public IEnumerator NextUnitVector2_ShouldThrow_GivenNullRandom() + { + Random? random = null; + Assert.Throws(() => random!.NextUnitVector2()); + yield break; + } + + [UnityTest] + public IEnumerator NextUnitVector3_ShouldReturnVector_WithMagnitude1() + { + var random = new Random(); + var vector = random.NextUnitVector3(); + Assert.AreEqual(1, vector.magnitude, 1e-6); + yield break; + } + + [UnityTest] + public IEnumerator NextUnitVector3_ShouldThrow_GivenNullRandom() + { + Random? random = null; + Assert.Throws(() => random!.NextUnitVector3()); + yield break; + } + + [UnityTest] + public IEnumerator NextRotation_ShouldThrow_GivenNullRandom() + { + Random random = null; + Assert.Throws(() => random!.NextRotation()); + yield break; + } + + [UnityTest] + public IEnumerator NextRotationUniform_ShouldThrow_GivenNullRandom() + { + Random? random = null; + Assert.Throws(() => random!.NextRotationUniform()); + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/RandomTests.cs.meta b/X10D.Unity.Tests/Assets/Tests/Numerics/RandomTests.cs.meta new file mode 100644 index 0000000..f143424 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/RandomTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 74577fe33f85446194c4ae2315caaace +timeCreated: 1652006301 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/Vector2Tests.cs b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector2Tests.cs new file mode 100644 index 0000000..3fc09e2 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector2Tests.cs @@ -0,0 +1,79 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using X10D.Core; +using X10D.Unity.Numerics; +using Random = System.Random; + +namespace X10D.Unity.Tests.Numerics +{ + public class Vector2Tests + { + [UnityTest] + public IEnumerator ToSystemVector_ShouldReturnVector_WithEqualComponents() + { + var random = new Random(); + float x = random.NextSingle(); + float y = random.NextSingle(); + + var vector = new Vector2(x, y); + var systemVector = vector.ToSystemVector(); + + Assert.AreEqual(vector.magnitude, systemVector.Length(), 1e-6f); + Assert.AreEqual(vector.x, systemVector.X, 1e-6f); + Assert.AreEqual(vector.y, systemVector.Y, 1e-6f); + + yield break; + } + + [UnityTest] + public IEnumerator ToUnityVector_ShouldReturnVector_WithEqualComponents() + { + var random = new Random(); + float x = random.NextSingle(); + float y = random.NextSingle(); + + var vector = new System.Numerics.Vector2(x, y); + var unityVector = vector.ToUnityVector(); + + Assert.AreEqual(vector.Length(), unityVector.magnitude, 1e-6f); + Assert.AreEqual(vector.X, unityVector.x, 1e-6f); + Assert.AreEqual(vector.Y, unityVector.y, 1e-6f); + + yield break; + } + + [UnityTest] + public IEnumerator WithX_ShouldReturnVectorWithNewX_GivenVector() + { + Assert.AreEqual(Vector2.up, Vector2.one.WithX(0)); + Assert.AreEqual(Vector2.zero, Vector2.zero.WithX(0)); + Assert.AreEqual(Vector2.zero, Vector2.right.WithX(0)); + Assert.AreEqual(Vector2.up, Vector2.up.WithX(0)); + + Assert.AreEqual(Vector2.one, Vector2.one.WithX(1)); + Assert.AreEqual(Vector2.right, Vector2.zero.WithX(1)); + Assert.AreEqual(Vector2.right, Vector2.right.WithX(1)); + Assert.AreEqual(Vector2.one, Vector2.up.WithX(1)); + + yield break; + } + + [UnityTest] + public IEnumerator WithY_ShouldReturnVectorWithNewY_GivenVector() + { + Assert.AreEqual(Vector2.right, Vector2.one.WithY(0)); + Assert.AreEqual(Vector2.zero, Vector2.zero.WithY(0)); + Assert.AreEqual(Vector2.right, Vector2.right.WithY(0)); + Assert.AreEqual(Vector2.zero, Vector2.up.WithY(0)); + + Assert.AreEqual(Vector2.one, Vector2.one.WithY(1)); + Assert.AreEqual(Vector2.up, Vector2.zero.WithY(1)); + Assert.AreEqual(Vector2.one, Vector2.right.WithY(1)); + Assert.AreEqual(Vector2.up, Vector2.up.WithY(1)); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/Vector2Tests.cs.meta b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector2Tests.cs.meta new file mode 100644 index 0000000..54f9a75 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector2Tests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 83385270996049569380ae9769ff1381 +timeCreated: 1652088132 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/Vector3Tests.cs b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector3Tests.cs new file mode 100644 index 0000000..f14c7e3 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector3Tests.cs @@ -0,0 +1,105 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using X10D.Core; +using X10D.Unity.Numerics; +using Random = System.Random; + +namespace X10D.Unity.Tests.Numerics +{ + public class Vector3Tests + { + [UnityTest] + public IEnumerator ToSystemVector_ShouldReturnVector_WithEqualComponents() + { + var random = new Random(); + float x = random.NextSingle(); + float y = random.NextSingle(); + float z = random.NextSingle(); + + var vector = new Vector3(x, y, z); + var systemVector = vector.ToSystemVector(); + + Assert.AreEqual(vector.magnitude, systemVector.Length(), 1e-6f); + Assert.AreEqual(vector.x, systemVector.X, 1e-6f); + Assert.AreEqual(vector.y, systemVector.Y, 1e-6f); + Assert.AreEqual(vector.z, systemVector.Z, 1e-6f); + + yield break; + } + + [UnityTest] + public IEnumerator ToUnityVector_ShouldReturnVector_WithEqualComponents() + { + var random = new Random(); + float x = random.NextSingle(); + float y = random.NextSingle(); + float z = random.NextSingle(); + + var vector = new System.Numerics.Vector3(x, y, z); + var unityVector = vector.ToUnityVector(); + + Assert.AreEqual(vector.Length(), unityVector.magnitude, 1e-6f); + Assert.AreEqual(vector.X, unityVector.x, 1e-6f); + Assert.AreEqual(vector.Y, unityVector.y, 1e-6f); + Assert.AreEqual(vector.Z, unityVector.z, 1e-6f); + + yield break; + } + + [UnityTest] + public IEnumerator WithX_ShouldReturnVectorWithNewX_GivenVector() + { + Assert.AreEqual(new Vector3(0, 1, 1), Vector3.one.WithX(0)); + Assert.AreEqual(Vector3.zero, Vector3.zero.WithX(0)); + Assert.AreEqual(Vector3.zero, Vector3.right.WithX(0)); + Assert.AreEqual(Vector3.up, Vector3.up.WithX(0)); + Assert.AreEqual(Vector3.forward, Vector3.forward.WithX(0)); + + Assert.AreEqual(Vector3.one, Vector3.one.WithX(1)); + Assert.AreEqual(Vector3.right, Vector3.zero.WithX(1)); + Assert.AreEqual(Vector3.right, Vector3.right.WithX(1)); + Assert.AreEqual(new Vector3(1, 1, 0), Vector3.up.WithX(1)); + Assert.AreEqual(new Vector3(1, 0, 1), Vector3.forward.WithX(1)); + + yield break; + } + + [UnityTest] + public IEnumerator WithY_ShouldReturnVectorWithNewY_GivenVector() + { + Assert.AreEqual(new Vector3(1, 0, 1), Vector3.one.WithY(0)); + Assert.AreEqual(Vector3.zero, Vector3.zero.WithY(0)); + Assert.AreEqual(Vector3.right, Vector3.right.WithY(0)); + Assert.AreEqual(Vector3.zero, Vector3.up.WithY(0)); + Assert.AreEqual(Vector3.forward, Vector3.forward.WithY(0)); + + Assert.AreEqual(Vector3.one, Vector3.one.WithY(1)); + Assert.AreEqual(Vector3.up, Vector3.zero.WithY(1)); + Assert.AreEqual(new Vector3(1, 1, 0), Vector3.right.WithY(1)); + Assert.AreEqual(Vector3.up, Vector3.up.WithY(1)); + Assert.AreEqual(new Vector3(0, 1, 1), Vector3.forward.WithY(1)); + + yield break; + } + + [UnityTest] + public IEnumerator WithZ_ShouldReturnVectorWithNewZ_GivenVector() + { + Assert.AreEqual(new Vector3(1, 1, 0), Vector3.one.WithZ(0)); + Assert.AreEqual(Vector3.zero, Vector3.zero.WithZ(0)); + Assert.AreEqual(Vector3.right, Vector3.right.WithZ(0)); + Assert.AreEqual(Vector3.up, Vector3.up.WithZ(0)); + Assert.AreEqual(Vector3.zero, Vector3.forward.WithZ(0)); + + Assert.AreEqual(Vector3.one, Vector3.one.WithZ(1)); + Assert.AreEqual(Vector3.forward, Vector3.zero.WithZ(1)); + Assert.AreEqual(new Vector3(1, 0, 1), Vector3.right.WithZ(1)); + Assert.AreEqual(new Vector3(0, 1, 1), Vector3.up.WithZ(1)); + Assert.AreEqual(Vector3.forward, Vector3.forward.WithZ(1)); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/Vector3Tests.cs.meta b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector3Tests.cs.meta new file mode 100644 index 0000000..6255e34 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector3Tests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: a00d613201bd497d91c9e98bca8dd6b1 +timeCreated: 1652088132 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/Vector4Tests.cs b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector4Tests.cs new file mode 100644 index 0000000..d400512 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector4Tests.cs @@ -0,0 +1,135 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; +using X10D.Core; +using X10D.Unity.Numerics; +using Random = System.Random; + +namespace X10D.Unity.Tests.Numerics +{ + public class Vector4Tests + { + [UnityTest] + public IEnumerator ToSystemVector_ShouldReturnVector_WithEqualComponents() + { + var random = new Random(); + float x = random.NextSingle(); + float y = random.NextSingle(); + float z = random.NextSingle(); + float w = random.NextSingle(); + + var vector = new Vector4(x, y, z, w); + var systemVector = vector.ToSystemVector(); + + Assert.AreEqual(vector.magnitude, systemVector.Length(), 1e-6f); + Assert.AreEqual(vector.x, systemVector.X, 1e-6f); + Assert.AreEqual(vector.y, systemVector.Y, 1e-6f); + Assert.AreEqual(vector.z, systemVector.Z, 1e-6f); + Assert.AreEqual(vector.w, systemVector.W, 1e-6f); + + yield break; + } + + [UnityTest] + public IEnumerator ToUnityVector_ShouldReturnVector_WithEqualComponents() + { + var random = new Random(); + float x = random.NextSingle(); + float y = random.NextSingle(); + float z = random.NextSingle(); + float w = random.NextSingle(); + + var vector = new System.Numerics.Vector4(x, y, z, w); + var unityVector = vector.ToUnityVector(); + + Assert.AreEqual(vector.Length(), unityVector.magnitude, 1e-6f); + Assert.AreEqual(vector.X, unityVector.x, 1e-6f); + Assert.AreEqual(vector.Y, unityVector.y, 1e-6f); + Assert.AreEqual(vector.Z, unityVector.z, 1e-6f); + Assert.AreEqual(vector.W, unityVector.w, 1e-6f); + + yield break; + } + + [UnityTest] + public IEnumerator WithW_ShouldReturnVectorWithNewW_GivenVector() + { + Assert.AreEqual(new Vector4(1, 1, 1, 0), Vector4.one.WithW(0)); + Assert.AreEqual(Vector4.zero, Vector4.zero.WithW(0)); + Assert.AreEqual(Vector4.zero, new Vector4(0, 0, 0, 1).WithW(0)); + Assert.AreEqual(new Vector4(1, 0, 0, 0), new Vector4(1, 0, 0, 0).WithW(0)); + Assert.AreEqual(new Vector4(0, 1, 0, 0), new Vector4(0, 1, 0, 0).WithW(0)); + Assert.AreEqual(new Vector4(0, 0, 1, 0), new Vector4(0, 0, 1, 0).WithW(0)); + + Assert.AreEqual(Vector4.one, Vector4.one.WithW(1)); + Assert.AreEqual(new Vector4(0, 0, 0, 1), Vector4.zero.WithW(1)); + Assert.AreEqual(new Vector4(0, 0, 0, 1), new Vector4(0, 0, 0, 1).WithW(1)); + Assert.AreEqual(new Vector4(1, 0, 0, 1), new Vector4(1, 0, 0, 0).WithW(1)); + Assert.AreEqual(new Vector4(0, 1, 0, 1), new Vector4(0, 1, 0, 0).WithW(1)); + Assert.AreEqual(new Vector4(0, 0, 1, 1), new Vector4(0, 0, 1, 0).WithW(1)); + + yield break; + } + + [UnityTest] + public IEnumerator WithX_ShouldReturnVectorWithNewX_GivenVector() + { + Assert.AreEqual(new Vector4(0, 1, 1, 1), Vector4.one.WithX(0)); + Assert.AreEqual(Vector4.zero, Vector4.zero.WithX(0)); + Assert.AreEqual(new Vector4(0, 0, 0, 1), new Vector4(0, 0, 0, 1).WithX(0)); + Assert.AreEqual(Vector4.zero, new Vector4(1, 0, 0, 0).WithX(0)); + Assert.AreEqual(new Vector4(0, 1, 0, 0), new Vector4(0, 1, 0, 0).WithX(0)); + Assert.AreEqual(new Vector4(0, 0, 1, 0), new Vector4(0, 0, 1, 0).WithX(0)); + + Assert.AreEqual(Vector4.one, Vector4.one.WithX(1)); + Assert.AreEqual(new Vector4(1, 0, 0, 0), Vector4.zero.WithX(1)); + Assert.AreEqual(new Vector4(1, 0, 0, 1), new Vector4(0, 0, 0, 1).WithX(1)); + Assert.AreEqual(new Vector4(1, 0, 0, 0), new Vector4(1, 0, 0, 0).WithX(1)); + Assert.AreEqual(new Vector4(1, 1, 0, 0), new Vector4(0, 1, 0, 0).WithX(1)); + Assert.AreEqual(new Vector4(1, 0, 1, 0), new Vector4(0, 0, 1, 0).WithX(1)); + + yield break; + } + + [UnityTest] + public IEnumerator WithY_ShouldReturnVectorWithNewY_GivenVector() + { + Assert.AreEqual(new Vector4(1, 0, 1, 1), Vector4.one.WithY(0)); + Assert.AreEqual(Vector4.zero, Vector4.zero.WithY(0)); + Assert.AreEqual(new Vector4(0, 0, 0, 1), new Vector4(0, 0, 0, 1).WithY(0)); + Assert.AreEqual(new Vector4(1, 0, 0, 0), new Vector4(1, 0, 0, 0).WithY(0)); + Assert.AreEqual(Vector4.zero, new Vector4(0, 1, 0, 0).WithY(0)); + Assert.AreEqual(new Vector4(0, 0, 1, 0), new Vector4(0, 0, 1, 0).WithY(0)); + + Assert.AreEqual(Vector4.one, Vector4.one.WithY(1)); + Assert.AreEqual(new Vector4(0, 1, 0, 0), Vector4.zero.WithY(1)); + Assert.AreEqual(new Vector4(0, 1, 0, 1), new Vector4(0, 0, 0, 1).WithY(1)); + Assert.AreEqual(new Vector4(1, 1, 0, 0), new Vector4(1, 0, 0, 0).WithY(1)); + Assert.AreEqual(new Vector4(0, 1, 0, 0), new Vector4(0, 1, 0, 0).WithY(1)); + Assert.AreEqual(new Vector4(0, 1, 1, 0), new Vector4(0, 0, 1, 0).WithY(1)); + + yield break; + } + + [UnityTest] + public IEnumerator WithZ_ShouldReturnVectorWithNewZ_GivenVector() + { + Assert.AreEqual(new Vector4(1, 1, 0, 1), Vector4.one.WithZ(0)); + Assert.AreEqual(Vector4.zero, Vector4.zero.WithZ(0)); + Assert.AreEqual(new Vector4(0, 0, 0, 1), new Vector4(0, 0, 0, 1).WithZ(0)); + Assert.AreEqual(new Vector4(1, 0, 0, 0), new Vector4(1, 0, 0, 0).WithZ(0)); + Assert.AreEqual(new Vector4(0, 1, 0, 0), new Vector4(0, 1, 0, 0).WithZ(0)); + Assert.AreEqual(Vector4.zero, new Vector4(0, 0, 1, 0).WithZ(0)); + + Assert.AreEqual(Vector4.one, Vector4.one.WithZ(1)); + Assert.AreEqual(new Vector4(0, 0, 1, 0), Vector4.zero.WithZ(1)); + Assert.AreEqual(new Vector4(0, 0, 1, 1), new Vector4(0, 0, 0, 1).WithZ(1)); + Assert.AreEqual(new Vector4(1, 0, 1, 0), new Vector4(1, 0, 0, 0).WithZ(1)); + Assert.AreEqual(new Vector4(0, 1, 1, 0), new Vector4(0, 1, 0, 0).WithZ(1)); + Assert.AreEqual(new Vector4(0, 0, 1, 0), new Vector4(0, 0, 1, 0).WithZ(1)); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/Numerics/Vector4Tests.cs.meta b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector4Tests.cs.meta new file mode 100644 index 0000000..041ceb9 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/Numerics/Vector4Tests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 0d487c2046a64354b199f4de01d57391 +timeCreated: 1652088132 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/SingletonTests.cs b/X10D.Unity.Tests/Assets/Tests/SingletonTests.cs new file mode 100644 index 0000000..9bf7a24 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/SingletonTests.cs @@ -0,0 +1,45 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace X10D.Unity.Tests +{ + public class SingletonTests + { + [UnityTest] + public IEnumerator Singleton_ShouldReturnNewInstance_WhenNoInstanceExists() + { + TestBehaviour instance = Singleton.Instance; + Assert.IsTrue(instance); + Assert.IsTrue(instance.Flag); + + yield break; + } + + [UnityTest] + public IEnumerator Singleton_ShouldReturnSameInstance_WhenAccessedTwice() + { + TestBehaviour instance = Singleton.Instance; + Assert.IsTrue(instance); + Assert.AreEqual(instance, Singleton.Instance); + + yield break; + } + + [UnityTest] + public IEnumerator Singleton_ShouldReturnNewInstance_WhenDestroyed() + { + TestBehaviour instance = Singleton.Instance; + Assert.IsTrue(instance); + Object.Destroy(instance); + yield return null; + Assert.IsFalse(instance); + + // ReSharper disable once HeuristicUnreachableCode + instance = Singleton.Instance; + Assert.IsNotNull(instance); + Assert.IsTrue(instance.Flag); + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/SingletonTests.cs.meta b/X10D.Unity.Tests/Assets/Tests/SingletonTests.cs.meta new file mode 100644 index 0000000..3f086ce --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/SingletonTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 5c51198d124f40859bd9298d3241d5a6 +timeCreated: 1652428949 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/TestBehaviour.cs b/X10D.Unity.Tests/Assets/Tests/TestBehaviour.cs new file mode 100644 index 0000000..a603e1d --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/TestBehaviour.cs @@ -0,0 +1,10 @@ +namespace X10D.Unity.Tests +{ + internal sealed class TestBehaviour : Singleton + { + public bool Flag + { + get => true; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/TestBehaviour.cs.meta b/X10D.Unity.Tests/Assets/Tests/TestBehaviour.cs.meta new file mode 100644 index 0000000..bc63104 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/TestBehaviour.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: df932718d20948ecbe9b0de8aa7bbaf4 +timeCreated: 1652428898 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/TransformTests.cs b/X10D.Unity.Tests/Assets/Tests/TransformTests.cs new file mode 100644 index 0000000..f603231 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/TransformTests.cs @@ -0,0 +1,59 @@ +#nullable enable + +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace X10D.Unity.Tests +{ + public class TransformTests + { + [UnityTest] + public IEnumerator LookAt_ShouldRotateSameAsTransform() + { + var first = new GameObject {transform = {position = Vector3.zero, rotation = Quaternion.identity}}; + var second = new GameObject {transform = {position = Vector3.right, rotation = Quaternion.identity}}; + Transform firstTransform = first.transform; + Transform secondTransform = second.transform; + + Assert.AreEqual(Quaternion.identity, firstTransform.rotation); + Assert.AreEqual(Quaternion.identity, secondTransform.rotation); + + firstTransform.LookAt(secondTransform); + Quaternion expected = firstTransform.rotation; + + firstTransform.rotation = Quaternion.identity; + Assert.AreEqual(Quaternion.identity, firstTransform.rotation); + + firstTransform.LookAt(second); + Assert.AreEqual(expected, firstTransform.rotation); + + firstTransform.rotation = Quaternion.identity; + Assert.AreEqual(Quaternion.identity, firstTransform.rotation); + + yield break; + } + + [UnityTest] + public IEnumerator SetParent_ShouldSetParent() + { + var first = new GameObject {transform = {position = Vector3.zero, rotation = Quaternion.identity}}; + var second = new GameObject {transform = {position = Vector3.right, rotation = Quaternion.identity}}; + + Assert.AreEqual(null, first.transform.parent); + Assert.AreEqual(null, second.transform.parent); + + first.transform.SetParent(second); + Assert.AreEqual(second.transform, first.transform.parent); + + first.transform.SetParent(null!); + Assert.AreEqual(null, first.transform.parent); + + second.transform.SetParent(first); + Assert.AreEqual(first.transform, second.transform.parent); + + yield break; + } + } +} diff --git a/X10D.Unity.Tests/Assets/Tests/TransformTests.cs.meta b/X10D.Unity.Tests/Assets/Tests/TransformTests.cs.meta new file mode 100644 index 0000000..362c6cc --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/TransformTests.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: 1f1518cdf51546288b7a16369297be5e +timeCreated: 1652005981 \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/X10D.Unity.Tests.asmdef b/X10D.Unity.Tests/Assets/Tests/X10D.Unity.Tests.asmdef new file mode 100644 index 0000000..3798be8 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/X10D.Unity.Tests.asmdef @@ -0,0 +1,23 @@ +{ + "name": "X10D.Unity.Tests", + "rootNamespace": "X10D.Unity", + "references": [ + "UnityEngine.TestRunner", + "UnityEditor.TestRunner" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": false, + "overrideReferences": true, + "precompiledReferences": [ + "nunit.framework.dll", + "X10D.dll", + "X10D.Unity.dll" + ], + "autoReferenced": false, + "defineConstraints": [ + "UNITY_INCLUDE_TESTS" + ], + "versionDefines": [], + "noEngineReferences": false +} \ No newline at end of file diff --git a/X10D.Unity.Tests/Assets/Tests/X10D.Unity.Tests.asmdef.meta b/X10D.Unity.Tests/Assets/Tests/X10D.Unity.Tests.asmdef.meta new file mode 100644 index 0000000..5932295 --- /dev/null +++ b/X10D.Unity.Tests/Assets/Tests/X10D.Unity.Tests.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 34215b8a0b1faf64487ff72821603aad +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/X10D.Unity.Tests/Packages/manifest.json b/X10D.Unity.Tests/Packages/manifest.json new file mode 100644 index 0000000..6f13d5a --- /dev/null +++ b/X10D.Unity.Tests/Packages/manifest.json @@ -0,0 +1,45 @@ +{ + "dependencies": { + "com.unity.collab-proxy": "1.15.17", + "com.unity.feature.development": "1.0.1", + "com.unity.ide.rider": "3.0.14", + "com.unity.ide.visualstudio": "2.0.15", + "com.unity.ide.vscode": "1.2.5", + "com.unity.test-framework": "1.1.31", + "com.unity.textmeshpro": "3.0.6", + "com.unity.timeline": "1.6.4", + "com.unity.ugui": "1.0.0", + "com.unity.visualscripting": "1.7.7", + "com.unity.modules.ai": "1.0.0", + "com.unity.modules.androidjni": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.cloth": "1.0.0", + "com.unity.modules.director": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.physics2d": "1.0.0", + "com.unity.modules.screencapture": "1.0.0", + "com.unity.modules.terrain": "1.0.0", + "com.unity.modules.terrainphysics": "1.0.0", + "com.unity.modules.tilemap": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.uielements": "1.0.0", + "com.unity.modules.umbra": "1.0.0", + "com.unity.modules.unityanalytics": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.unitywebrequesttexture": "1.0.0", + "com.unity.modules.unitywebrequestwww": "1.0.0", + "com.unity.modules.vehicles": "1.0.0", + "com.unity.modules.video": "1.0.0", + "com.unity.modules.vr": "1.0.0", + "com.unity.modules.wind": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } +} diff --git a/X10D.Unity.Tests/Packages/packages-lock.json b/X10D.Unity.Tests/Packages/packages-lock.json new file mode 100644 index 0000000..d81f525 --- /dev/null +++ b/X10D.Unity.Tests/Packages/packages-lock.json @@ -0,0 +1,413 @@ +{ + "dependencies": { + "com.unity.collab-proxy": { + "version": "1.15.17", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.services.core": "1.0.1" + }, + "url": "https://packages.unity.com" + }, + "com.unity.editorcoroutines": { + "version": "1.0.0", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.ext.nunit": { + "version": "1.0.6", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.feature.development": { + "version": "1.0.1", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.ide.visualstudio": "2.0.14", + "com.unity.ide.rider": "3.0.13", + "com.unity.ide.vscode": "1.2.5", + "com.unity.editorcoroutines": "1.0.0", + "com.unity.performance.profile-analyzer": "1.1.1", + "com.unity.test-framework": "1.1.31", + "com.unity.testtools.codecoverage": "1.0.1" + } + }, + "com.unity.ide.rider": { + "version": "3.0.14", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ide.visualstudio": { + "version": "2.0.15", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.1.9" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ide.vscode": { + "version": "1.2.5", + "depth": 0, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.nuget.newtonsoft-json": { + "version": "3.0.2", + "depth": 2, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.performance.profile-analyzer": { + "version": "1.1.1", + "depth": 1, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.services.core": { + "version": "1.3.1", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.nuget.newtonsoft-json": "3.0.2", + "com.unity.modules.androidjni": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.settings-manager": { + "version": "1.0.3", + "depth": 2, + "source": "registry", + "dependencies": {}, + "url": "https://packages.unity.com" + }, + "com.unity.test-framework": { + "version": "1.1.31", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ext.nunit": "1.0.6", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.testtools.codecoverage": { + "version": "1.0.1", + "depth": 1, + "source": "registry", + "dependencies": { + "com.unity.test-framework": "1.0.16", + "com.unity.settings-manager": "1.0.1" + }, + "url": "https://packages.unity.com" + }, + "com.unity.textmeshpro": { + "version": "3.0.6", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ugui": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.timeline": { + "version": "1.6.4", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.modules.director": "1.0.0", + "com.unity.modules.animation": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.particlesystem": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.ugui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0" + } + }, + "com.unity.visualscripting": { + "version": "1.7.7", + "depth": 0, + "source": "registry", + "dependencies": { + "com.unity.ugui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + }, + "url": "https://packages.unity.com" + }, + "com.unity.modules.ai": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.androidjni": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.animation": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.assetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.audio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.cloth": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.director": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.animation": "1.0.0" + } + }, + "com.unity.modules.imageconversion": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.imgui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.jsonserialize": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.particlesystem": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.physics2d": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.screencapture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.subsystems": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.terrain": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.terrainphysics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.terrain": "1.0.0" + } + }, + "com.unity.modules.tilemap": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics2d": "1.0.0" + } + }, + "com.unity.modules.ui": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.uielements": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.uielementsnative": "1.0.0" + } + }, + "com.unity.modules.uielementsnative": { + "version": "1.0.0", + "depth": 1, + "source": "builtin", + "dependencies": { + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.imgui": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.umbra": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unityanalytics": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0" + } + }, + "com.unity.modules.unitywebrequest": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.unitywebrequestassetbundle": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestaudio": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.audio": "1.0.0" + } + }, + "com.unity.modules.unitywebrequesttexture": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.unitywebrequestwww": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.unitywebrequest": "1.0.0", + "com.unity.modules.unitywebrequestassetbundle": "1.0.0", + "com.unity.modules.unitywebrequestaudio": "1.0.0", + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.assetbundle": "1.0.0", + "com.unity.modules.imageconversion": "1.0.0" + } + }, + "com.unity.modules.vehicles": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0" + } + }, + "com.unity.modules.video": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.audio": "1.0.0", + "com.unity.modules.ui": "1.0.0", + "com.unity.modules.unitywebrequest": "1.0.0" + } + }, + "com.unity.modules.vr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.xr": "1.0.0" + } + }, + "com.unity.modules.wind": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": {} + }, + "com.unity.modules.xr": { + "version": "1.0.0", + "depth": 0, + "source": "builtin", + "dependencies": { + "com.unity.modules.physics": "1.0.0", + "com.unity.modules.jsonserialize": "1.0.0", + "com.unity.modules.subsystems": "1.0.0" + } + } + } +} diff --git a/X10D.Unity.Tests/ProjectSettings/AudioManager.asset b/X10D.Unity.Tests/ProjectSettings/AudioManager.asset new file mode 100644 index 0000000..07ebfb0 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/AudioManager.asset @@ -0,0 +1,19 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!11 &1 +AudioManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Volume: 1 + Rolloff Scale: 1 + Doppler Factor: 1 + Default Speaker Mode: 2 + m_SampleRate: 0 + m_DSPBufferSize: 1024 + m_VirtualVoiceCount: 512 + m_RealVoiceCount: 32 + m_SpatializerPlugin: + m_AmbisonicDecoderPlugin: + m_DisableAudio: 0 + m_VirtualizeEffects: 1 + m_RequestedDSPBufferSize: 1024 diff --git a/X10D.Unity.Tests/ProjectSettings/ClusterInputManager.asset b/X10D.Unity.Tests/ProjectSettings/ClusterInputManager.asset new file mode 100644 index 0000000..e7886b2 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/ClusterInputManager.asset @@ -0,0 +1,6 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!236 &1 +ClusterInputManager: + m_ObjectHideFlags: 0 + m_Inputs: [] diff --git a/X10D.Unity.Tests/ProjectSettings/DynamicsManager.asset b/X10D.Unity.Tests/ProjectSettings/DynamicsManager.asset new file mode 100644 index 0000000..cdc1f3e --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/DynamicsManager.asset @@ -0,0 +1,34 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!55 &1 +PhysicsManager: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_Gravity: {x: 0, y: -9.81, z: 0} + m_DefaultMaterial: {fileID: 0} + m_BounceThreshold: 2 + m_SleepThreshold: 0.005 + m_DefaultContactOffset: 0.01 + m_DefaultSolverIterations: 6 + m_DefaultSolverVelocityIterations: 1 + m_QueriesHitBackfaces: 0 + m_QueriesHitTriggers: 1 + m_EnableAdaptiveForce: 0 + m_ClothInterCollisionDistance: 0 + m_ClothInterCollisionStiffness: 0 + m_ContactsGeneration: 1 + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff + m_AutoSimulation: 1 + m_AutoSyncTransforms: 0 + m_ReuseCollisionCallbacks: 1 + m_ClothInterCollisionSettingsToggle: 0 + m_ContactPairsMode: 0 + m_BroadphaseType: 0 + m_WorldBounds: + m_Center: {x: 0, y: 0, z: 0} + m_Extent: {x: 250, y: 250, z: 250} + m_WorldSubdivisions: 8 + m_FrictionType: 0 + m_EnableEnhancedDeterminism: 0 + m_EnableUnifiedHeightmaps: 1 + m_DefaultMaxAngluarSpeed: 7 diff --git a/X10D.Unity.Tests/ProjectSettings/EditorBuildSettings.asset b/X10D.Unity.Tests/ProjectSettings/EditorBuildSettings.asset new file mode 100644 index 0000000..0147887 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/EditorBuildSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1045 &1 +EditorBuildSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Scenes: [] + m_configObjects: {} diff --git a/X10D.Unity.Tests/ProjectSettings/EditorSettings.asset b/X10D.Unity.Tests/ProjectSettings/EditorSettings.asset new file mode 100644 index 0000000..1e44a0a --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/EditorSettings.asset @@ -0,0 +1,30 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!159 &1 +EditorSettings: + m_ObjectHideFlags: 0 + serializedVersion: 11 + m_ExternalVersionControlSupport: Visible Meta Files + m_SerializationMode: 2 + m_LineEndingsForNewScripts: 0 + m_DefaultBehaviorMode: 0 + m_PrefabRegularEnvironment: {fileID: 0} + m_PrefabUIEnvironment: {fileID: 0} + m_SpritePackerMode: 0 + m_SpritePackerPaddingPower: 1 + m_EtcTextureCompressorBehavior: 1 + m_EtcTextureFastCompressor: 1 + m_EtcTextureNormalCompressor: 2 + m_EtcTextureBestCompressor: 4 + m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref + m_ProjectGenerationRootNamespace: + m_CollabEditorSettings: + inProgressEnabled: 1 + m_EnableTextureStreamingInEditMode: 1 + m_EnableTextureStreamingInPlayMode: 1 + m_AsyncShaderCompilation: 1 + m_EnterPlayModeOptionsEnabled: 0 + m_EnterPlayModeOptions: 3 + m_ShowLightmapResolutionOverlay: 1 + m_UseLegacyProbeSampleCount: 0 + m_SerializeInlineMappingsOnOneLine: 1 diff --git a/X10D.Unity.Tests/ProjectSettings/GraphicsSettings.asset b/X10D.Unity.Tests/ProjectSettings/GraphicsSettings.asset new file mode 100644 index 0000000..43369e3 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/GraphicsSettings.asset @@ -0,0 +1,63 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!30 &1 +GraphicsSettings: + m_ObjectHideFlags: 0 + serializedVersion: 13 + m_Deferred: + m_Mode: 1 + m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} + m_DeferredReflections: + m_Mode: 1 + m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} + m_ScreenSpaceShadows: + m_Mode: 1 + m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} + m_LegacyDeferred: + m_Mode: 1 + m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} + m_DepthNormals: + m_Mode: 1 + m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} + m_MotionVectors: + m_Mode: 1 + m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} + m_LightHalo: + m_Mode: 1 + m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} + m_LensFlare: + m_Mode: 1 + m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} + m_AlwaysIncludedShaders: + - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} + - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} + m_PreloadedShaders: [] + m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, + type: 0} + m_CustomRenderPipeline: {fileID: 0} + m_TransparencySortMode: 0 + m_TransparencySortAxis: {x: 0, y: 0, z: 1} + m_DefaultRenderingPath: 1 + m_DefaultMobileRenderingPath: 1 + m_TierSettings: [] + m_LightmapStripping: 0 + m_FogStripping: 0 + m_InstancingStripping: 0 + m_LightmapKeepPlain: 1 + m_LightmapKeepDirCombined: 1 + m_LightmapKeepDynamicPlain: 1 + m_LightmapKeepDynamicDirCombined: 1 + m_LightmapKeepShadowMask: 1 + m_LightmapKeepSubtractive: 1 + m_FogKeepLinear: 1 + m_FogKeepExp: 1 + m_FogKeepExp2: 1 + m_AlbedoSwatchInfos: [] + m_LightsUseLinearIntensity: 0 + m_LightsUseColorTemperature: 0 + m_LogWhenShaderIsCompiled: 0 + m_AllowEnlightenSupportForUpgradedProject: 0 diff --git a/X10D.Unity.Tests/ProjectSettings/InputManager.asset b/X10D.Unity.Tests/ProjectSettings/InputManager.asset new file mode 100644 index 0000000..17c8f53 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/InputManager.asset @@ -0,0 +1,295 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!13 &1 +InputManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_Axes: + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: left + positiveButton: right + altNegativeButton: a + altPositiveButton: d + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: down + positiveButton: up + altNegativeButton: s + altPositiveButton: w + gravity: 3 + dead: 0.001 + sensitivity: 3 + snap: 1 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left ctrl + altNegativeButton: + altPositiveButton: mouse 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left alt + altNegativeButton: + altPositiveButton: mouse 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: left shift + altNegativeButton: + altPositiveButton: mouse 2 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: space + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse X + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse Y + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Mouse ScrollWheel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0 + sensitivity: 0.1 + snap: 0 + invert: 0 + type: 1 + axis: 2 + joyNum: 0 + - serializedVersion: 3 + m_Name: Horizontal + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 0 + type: 2 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Vertical + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: + altNegativeButton: + altPositiveButton: + gravity: 0 + dead: 0.19 + sensitivity: 1 + snap: 0 + invert: 1 + type: 2 + axis: 1 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire1 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 0 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire2 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 1 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Fire3 + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 2 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Jump + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: joystick button 3 + altNegativeButton: + altPositiveButton: + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: return + altNegativeButton: + altPositiveButton: joystick button 0 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Submit + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: enter + altNegativeButton: + altPositiveButton: space + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 + - serializedVersion: 3 + m_Name: Cancel + descriptiveName: + descriptiveNegativeName: + negativeButton: + positiveButton: escape + altNegativeButton: + altPositiveButton: joystick button 1 + gravity: 1000 + dead: 0.001 + sensitivity: 1000 + snap: 0 + invert: 0 + type: 0 + axis: 0 + joyNum: 0 diff --git a/X10D.Unity.Tests/ProjectSettings/MemorySettings.asset b/X10D.Unity.Tests/ProjectSettings/MemorySettings.asset new file mode 100644 index 0000000..5b5face --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/MemorySettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!387306366 &1 +MemorySettings: + m_ObjectHideFlags: 0 + m_EditorMemorySettings: + m_MainAllocatorBlockSize: -1 + m_ThreadAllocatorBlockSize: -1 + m_MainGfxBlockSize: -1 + m_ThreadGfxBlockSize: -1 + m_CacheBlockSize: -1 + m_TypetreeBlockSize: -1 + m_ProfilerBlockSize: -1 + m_ProfilerEditorBlockSize: -1 + m_BucketAllocatorGranularity: -1 + m_BucketAllocatorBucketsCount: -1 + m_BucketAllocatorBlockSize: -1 + m_BucketAllocatorBlockCount: -1 + m_ProfilerBucketAllocatorGranularity: -1 + m_ProfilerBucketAllocatorBucketsCount: -1 + m_ProfilerBucketAllocatorBlockSize: -1 + m_ProfilerBucketAllocatorBlockCount: -1 + m_TempAllocatorSizeMain: -1 + m_JobTempAllocatorBlockSize: -1 + m_BackgroundJobTempAllocatorBlockSize: -1 + m_JobTempAllocatorReducedBlockSize: -1 + m_TempAllocatorSizeGIBakingWorker: -1 + m_TempAllocatorSizeNavMeshWorker: -1 + m_TempAllocatorSizeAudioWorker: -1 + m_TempAllocatorSizeCloudWorker: -1 + m_TempAllocatorSizeGfx: -1 + m_TempAllocatorSizeJobWorker: -1 + m_TempAllocatorSizeBackgroundWorker: -1 + m_TempAllocatorSizePreloadManager: -1 + m_PlatformMemorySettings: {} diff --git a/X10D.Unity.Tests/ProjectSettings/NavMeshAreas.asset b/X10D.Unity.Tests/ProjectSettings/NavMeshAreas.asset new file mode 100644 index 0000000..3b0b7c3 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/NavMeshAreas.asset @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!126 &1 +NavMeshProjectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 2 + areas: + - name: Walkable + cost: 1 + - name: Not Walkable + cost: 1 + - name: Jump + cost: 2 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + - name: + cost: 1 + m_LastAgentTypeID: -887442657 + m_Settings: + - serializedVersion: 2 + agentTypeID: 0 + agentRadius: 0.5 + agentHeight: 2 + agentSlope: 45 + agentClimb: 0.75 + ledgeDropHeight: 0 + maxJumpAcrossDistance: 0 + minRegionArea: 2 + manualCellSize: 0 + cellSize: 0.16666667 + manualTileSize: 0 + tileSize: 256 + accuratePlacement: 0 + debug: + m_Flags: 0 + m_SettingNames: + - Humanoid diff --git a/X10D.Unity.Tests/ProjectSettings/PackageManagerSettings.asset b/X10D.Unity.Tests/ProjectSettings/PackageManagerSettings.asset new file mode 100644 index 0000000..112a053 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/PackageManagerSettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 61 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 13964, guid: 0000000000000000e000000000000000, type: 0} + m_Name: + m_EditorClassIdentifier: + m_EnablePreReleasePackages: 0 + m_EnablePackageDependencies: 0 + m_AdvancedSettingsExpanded: 1 + m_ScopedRegistriesSettingsExpanded: 1 + m_SeeAllPackageVersions: 0 + oneTimeWarningShown: 0 + m_Registries: + - m_Id: main + m_Name: + m_Url: https://packages.unity.com + m_Scopes: [] + m_IsDefault: 1 + m_Capabilities: 7 + m_UserSelectedRegistryName: + m_UserAddingNewScopedRegistry: 0 + m_RegistryInfoDraft: + m_Modified: 0 + m_ErrorMessage: + m_UserModificationsInstanceId: -830 + m_OriginalInstanceId: -832 + m_LoadAssets: 0 diff --git a/X10D.Unity.Tests/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json b/X10D.Unity.Tests/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json new file mode 100644 index 0000000..ad11087 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json @@ -0,0 +1,7 @@ +{ + "m_Name": "Settings", + "m_Path": "ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json", + "m_Dictionary": { + "m_DictionaryValues": [] + } +} \ No newline at end of file diff --git a/X10D.Unity.Tests/ProjectSettings/Physics2DSettings.asset b/X10D.Unity.Tests/ProjectSettings/Physics2DSettings.asset new file mode 100644 index 0000000..47880b1 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/Physics2DSettings.asset @@ -0,0 +1,56 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!19 &1 +Physics2DSettings: + m_ObjectHideFlags: 0 + serializedVersion: 4 + m_Gravity: {x: 0, y: -9.81} + m_DefaultMaterial: {fileID: 0} + m_VelocityIterations: 8 + m_PositionIterations: 3 + m_VelocityThreshold: 1 + m_MaxLinearCorrection: 0.2 + m_MaxAngularCorrection: 8 + m_MaxTranslationSpeed: 100 + m_MaxRotationSpeed: 360 + m_BaumgarteScale: 0.2 + m_BaumgarteTimeOfImpactScale: 0.75 + m_TimeToSleep: 0.5 + m_LinearSleepTolerance: 0.01 + m_AngularSleepTolerance: 2 + m_DefaultContactOffset: 0.01 + m_JobOptions: + serializedVersion: 2 + useMultithreading: 0 + useConsistencySorting: 0 + m_InterpolationPosesPerJob: 100 + m_NewContactsPerJob: 30 + m_CollideContactsPerJob: 100 + m_ClearFlagsPerJob: 200 + m_ClearBodyForcesPerJob: 200 + m_SyncDiscreteFixturesPerJob: 50 + m_SyncContinuousFixturesPerJob: 50 + m_FindNearestContactsPerJob: 100 + m_UpdateTriggerContactsPerJob: 100 + m_IslandSolverCostThreshold: 100 + m_IslandSolverBodyCostScale: 1 + m_IslandSolverContactCostScale: 10 + m_IslandSolverJointCostScale: 10 + m_IslandSolverBodiesPerJob: 50 + m_IslandSolverContactsPerJob: 50 + m_AutoSimulation: 1 + m_QueriesHitTriggers: 1 + m_QueriesStartInColliders: 1 + m_CallbacksOnDisable: 1 + m_ReuseCollisionCallbacks: 1 + m_AutoSyncTransforms: 0 + m_AlwaysShowColliders: 0 + m_ShowColliderSleep: 1 + m_ShowColliderContacts: 0 + m_ShowColliderAABB: 0 + m_ContactArrowScale: 0.2 + m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} + m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} + m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} + m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} + m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff diff --git a/X10D.Unity.Tests/ProjectSettings/PresetManager.asset b/X10D.Unity.Tests/ProjectSettings/PresetManager.asset new file mode 100644 index 0000000..67a94da --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/PresetManager.asset @@ -0,0 +1,7 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1386491679 &1 +PresetManager: + m_ObjectHideFlags: 0 + serializedVersion: 2 + m_DefaultPresets: {} diff --git a/X10D.Unity.Tests/ProjectSettings/ProjectSettings.asset b/X10D.Unity.Tests/ProjectSettings/ProjectSettings.asset new file mode 100644 index 0000000..67fd210 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/ProjectSettings.asset @@ -0,0 +1,708 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!129 &1 +PlayerSettings: + m_ObjectHideFlags: 0 + serializedVersion: 23 + productGUID: a5313041f8a8e9240a746c81c45bc60b + AndroidProfiler: 0 + AndroidFilterTouchesWhenObscured: 0 + AndroidEnableSustainedPerformanceMode: 0 + defaultScreenOrientation: 4 + targetDevice: 2 + useOnDemandResources: 0 + accelerometerFrequency: 60 + companyName: DefaultCompany + productName: X10D.Unity.Tests + defaultCursor: {fileID: 0} + cursorHotspot: {x: 0, y: 0} + m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} + m_ShowUnitySplashScreen: 1 + m_ShowUnitySplashLogo: 1 + m_SplashScreenOverlayOpacity: 1 + m_SplashScreenAnimation: 1 + m_SplashScreenLogoStyle: 1 + m_SplashScreenDrawMode: 0 + m_SplashScreenBackgroundAnimationZoom: 1 + m_SplashScreenLogoAnimationZoom: 1 + m_SplashScreenBackgroundLandscapeAspect: 1 + m_SplashScreenBackgroundPortraitAspect: 1 + m_SplashScreenBackgroundLandscapeUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenBackgroundPortraitUvs: + serializedVersion: 2 + x: 0 + y: 0 + width: 1 + height: 1 + m_SplashScreenLogos: [] + m_VirtualRealitySplashScreen: {fileID: 0} + m_HolographicTrackingLossScreen: {fileID: 0} + defaultScreenWidth: 1920 + defaultScreenHeight: 1080 + defaultScreenWidthWeb: 960 + defaultScreenHeightWeb: 600 + m_StereoRenderingPath: 0 + m_ActiveColorSpace: 0 + m_MTRendering: 1 + mipStripping: 0 + numberOfMipsStripped: 0 + m_StackTraceTypes: 010000000100000001000000010000000100000001000000 + iosShowActivityIndicatorOnLoading: -1 + androidShowActivityIndicatorOnLoading: -1 + iosUseCustomAppBackgroundBehavior: 0 + iosAllowHTTPDownload: 1 + allowedAutorotateToPortrait: 1 + allowedAutorotateToPortraitUpsideDown: 1 + allowedAutorotateToLandscapeRight: 1 + allowedAutorotateToLandscapeLeft: 1 + useOSAutorotation: 1 + use32BitDisplayBuffer: 1 + preserveFramebufferAlpha: 0 + disableDepthAndStencilBuffers: 0 + androidStartInFullscreen: 1 + androidRenderOutsideSafeArea: 1 + androidUseSwappy: 1 + androidBlitType: 0 + androidResizableWindow: 0 + androidDefaultWindowWidth: 1920 + androidDefaultWindowHeight: 1080 + androidMinimumWindowWidth: 400 + androidMinimumWindowHeight: 300 + androidFullscreenMode: 1 + defaultIsNativeResolution: 1 + macRetinaSupport: 1 + runInBackground: 1 + captureSingleScreen: 0 + muteOtherAudioSources: 0 + Prepare IOS For Recording: 0 + Force IOS Speakers When Recording: 0 + deferSystemGesturesMode: 0 + hideHomeButton: 0 + submitAnalytics: 1 + usePlayerLog: 1 + bakeCollisionMeshes: 0 + forceSingleInstance: 0 + useFlipModelSwapchain: 1 + resizableWindow: 0 + useMacAppStoreValidation: 0 + macAppStoreCategory: public.app-category.games + gpuSkinning: 1 + xboxPIXTextureCapture: 0 + xboxEnableAvatar: 0 + xboxEnableKinect: 0 + xboxEnableKinectAutoTracking: 0 + xboxEnableFitness: 0 + visibleInBackground: 1 + allowFullscreenSwitch: 1 + fullscreenMode: 1 + xboxSpeechDB: 0 + xboxEnableHeadOrientation: 0 + xboxEnableGuest: 0 + xboxEnablePIXSampling: 0 + metalFramebufferOnly: 0 + xboxOneResolution: 0 + xboxOneSResolution: 0 + xboxOneXResolution: 3 + xboxOneMonoLoggingLevel: 0 + xboxOneLoggingLevel: 1 + xboxOneDisableEsram: 0 + xboxOneEnableTypeOptimization: 0 + xboxOnePresentImmediateThreshold: 0 + switchQueueCommandMemory: 0 + switchQueueControlMemory: 16384 + switchQueueComputeMemory: 262144 + switchNVNShaderPoolsGranularity: 33554432 + switchNVNDefaultPoolsGranularity: 16777216 + switchNVNOtherPoolsGranularity: 16777216 + switchNVNMaxPublicTextureIDCount: 0 + switchNVNMaxPublicSamplerIDCount: 0 + stadiaPresentMode: 0 + stadiaTargetFramerate: 0 + vulkanNumSwapchainBuffers: 3 + vulkanEnableSetSRGBWrite: 0 + vulkanEnablePreTransform: 1 + vulkanEnableLateAcquireNextImage: 0 + vulkanEnableCommandBufferRecycling: 1 + m_SupportedAspectRatios: + 4:3: 1 + 5:4: 1 + 16:10: 1 + 16:9: 1 + Others: 1 + bundleVersion: 0.1 + preloadedAssets: [] + metroInputSource: 0 + wsaTransparentSwapchain: 0 + m_HolographicPauseOnTrackingLoss: 1 + xboxOneDisableKinectGpuReservation: 1 + xboxOneEnable7thCore: 1 + vrSettings: + enable360StereoCapture: 0 + isWsaHolographicRemotingEnabled: 0 + enableFrameTimingStats: 0 + useHDRDisplay: 0 + D3DHDRBitDepth: 0 + m_ColorGamuts: 00000000 + targetPixelDensity: 30 + resolutionScalingMode: 0 + androidSupportedAspectRatio: 1 + androidMaxAspectRatio: 2.1 + applicationIdentifier: {} + buildNumber: + Standalone: 0 + iPhone: 0 + tvOS: 0 + overrideDefaultApplicationIdentifier: 0 + AndroidBundleVersionCode: 1 + AndroidMinSdkVersion: 22 + AndroidTargetSdkVersion: 0 + AndroidPreferredInstallLocation: 1 + aotOptions: + stripEngineCode: 1 + iPhoneStrippingLevel: 0 + iPhoneScriptCallOptimization: 0 + ForceInternetPermission: 0 + ForceSDCardPermission: 0 + CreateWallpaper: 0 + APKExpansionFiles: 0 + keepLoadedShadersAlive: 0 + StripUnusedMeshComponents: 1 + VertexChannelCompressionMask: 4054 + iPhoneSdkVersion: 988 + iOSTargetOSVersionString: 11.0 + tvOSSdkVersion: 0 + tvOSRequireExtendedGameController: 0 + tvOSTargetOSVersionString: 11.0 + uIPrerenderedIcon: 0 + uIRequiresPersistentWiFi: 0 + uIRequiresFullScreen: 1 + uIStatusBarHidden: 1 + uIExitOnSuspend: 0 + uIStatusBarStyle: 0 + appleTVSplashScreen: {fileID: 0} + appleTVSplashScreen2x: {fileID: 0} + tvOSSmallIconLayers: [] + tvOSSmallIconLayers2x: [] + tvOSLargeIconLayers: [] + tvOSLargeIconLayers2x: [] + tvOSTopShelfImageLayers: [] + tvOSTopShelfImageLayers2x: [] + tvOSTopShelfImageWideLayers: [] + tvOSTopShelfImageWideLayers2x: [] + iOSLaunchScreenType: 0 + iOSLaunchScreenPortrait: {fileID: 0} + iOSLaunchScreenLandscape: {fileID: 0} + iOSLaunchScreenBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreenFillPct: 100 + iOSLaunchScreenSize: 100 + iOSLaunchScreenCustomXibPath: + iOSLaunchScreeniPadType: 0 + iOSLaunchScreeniPadImage: {fileID: 0} + iOSLaunchScreeniPadBackgroundColor: + serializedVersion: 2 + rgba: 0 + iOSLaunchScreeniPadFillPct: 100 + iOSLaunchScreeniPadSize: 100 + iOSLaunchScreeniPadCustomXibPath: + iOSLaunchScreenCustomStoryboardPath: + iOSLaunchScreeniPadCustomStoryboardPath: + iOSDeviceRequirements: [] + iOSURLSchemes: [] + macOSURLSchemes: [] + iOSBackgroundModes: 0 + iOSMetalForceHardShadows: 0 + metalEditorSupport: 1 + metalAPIValidation: 1 + iOSRenderExtraFrameOnPause: 0 + iosCopyPluginsCodeInsteadOfSymlink: 0 + appleDeveloperTeamID: + iOSManualSigningProvisioningProfileID: + tvOSManualSigningProvisioningProfileID: + iOSManualSigningProvisioningProfileType: 0 + tvOSManualSigningProvisioningProfileType: 0 + appleEnableAutomaticSigning: 0 + iOSRequireARKit: 0 + iOSAutomaticallyDetectAndAddCapabilities: 1 + appleEnableProMotion: 0 + shaderPrecisionModel: 0 + clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea + templatePackageId: com.unity.template.3d@8.1.0 + templateDefaultScene: Assets/Scenes/SampleScene.unity + useCustomMainManifest: 0 + useCustomLauncherManifest: 0 + useCustomMainGradleTemplate: 0 + useCustomLauncherGradleManifest: 0 + useCustomBaseGradleTemplate: 0 + useCustomGradlePropertiesTemplate: 0 + useCustomProguardFile: 0 + AndroidTargetArchitectures: 1 + AndroidTargetDevices: 0 + AndroidSplashScreenScale: 0 + androidSplashScreen: {fileID: 0} + AndroidKeystoreName: + AndroidKeyaliasName: + AndroidBuildApkPerCpuArchitecture: 0 + AndroidTVCompatibility: 0 + AndroidIsGame: 1 + AndroidEnableTango: 0 + androidEnableBanner: 1 + androidUseLowAccuracyLocation: 0 + androidUseCustomKeystore: 0 + m_AndroidBanners: + - width: 320 + height: 180 + banner: {fileID: 0} + androidGamepadSupportLevel: 0 + chromeosInputEmulation: 1 + AndroidMinifyWithR8: 0 + AndroidMinifyRelease: 0 + AndroidMinifyDebug: 0 + AndroidValidateAppBundleSize: 1 + AndroidAppBundleSizeToValidate: 150 + m_BuildTargetIcons: [] + m_BuildTargetPlatformIcons: [] + m_BuildTargetBatching: + - m_BuildTarget: Standalone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: tvOS + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: Android + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: iPhone + m_StaticBatching: 1 + m_DynamicBatching: 0 + - m_BuildTarget: WebGL + m_StaticBatching: 0 + m_DynamicBatching: 0 + m_BuildTargetGraphicsJobs: + - m_BuildTarget: MacStandaloneSupport + m_GraphicsJobs: 0 + - m_BuildTarget: Switch + m_GraphicsJobs: 1 + - m_BuildTarget: MetroSupport + m_GraphicsJobs: 1 + - m_BuildTarget: AppleTVSupport + m_GraphicsJobs: 0 + - m_BuildTarget: BJMSupport + m_GraphicsJobs: 1 + - m_BuildTarget: LinuxStandaloneSupport + m_GraphicsJobs: 1 + - m_BuildTarget: PS4Player + m_GraphicsJobs: 1 + - m_BuildTarget: iOSSupport + m_GraphicsJobs: 0 + - m_BuildTarget: WindowsStandaloneSupport + m_GraphicsJobs: 1 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobs: 1 + - m_BuildTarget: LuminSupport + m_GraphicsJobs: 0 + - m_BuildTarget: AndroidPlayer + m_GraphicsJobs: 0 + - m_BuildTarget: WebGLSupport + m_GraphicsJobs: 0 + m_BuildTargetGraphicsJobMode: + - m_BuildTarget: PS4Player + m_GraphicsJobMode: 0 + - m_BuildTarget: XboxOnePlayer + m_GraphicsJobMode: 0 + m_BuildTargetGraphicsAPIs: + - m_BuildTarget: AndroidPlayer + m_APIs: 150000000b000000 + m_Automatic: 1 + - m_BuildTarget: iOSSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: AppleTVSupport + m_APIs: 10000000 + m_Automatic: 1 + - m_BuildTarget: WebGLSupport + m_APIs: 0b000000 + m_Automatic: 1 + m_BuildTargetVRSettings: + - m_BuildTarget: Standalone + m_Enabled: 0 + m_Devices: + - Oculus + - OpenVR + openGLRequireES31: 0 + openGLRequireES31AEP: 0 + openGLRequireES32: 0 + m_TemplateCustomTags: {} + mobileMTRendering: + Android: 1 + iPhone: 1 + tvOS: 1 + m_BuildTargetGroupLightmapEncodingQuality: + - m_BuildTarget: Android + m_EncodingQuality: 1 + - m_BuildTarget: iPhone + m_EncodingQuality: 1 + - m_BuildTarget: tvOS + m_EncodingQuality: 1 + m_BuildTargetGroupLightmapSettings: [] + m_BuildTargetNormalMapEncoding: + - m_BuildTarget: Android + m_Encoding: 1 + - m_BuildTarget: iPhone + m_Encoding: 1 + - m_BuildTarget: tvOS + m_Encoding: 1 + m_BuildTargetDefaultTextureCompressionFormat: + - m_BuildTarget: Android + m_Format: 3 + playModeTestRunnerEnabled: 0 + runPlayModeTestAsEditModeTest: 0 + actionOnDotNetUnhandledException: 1 + enableInternalProfiler: 0 + logObjCUncaughtExceptions: 1 + enableCrashReportAPI: 0 + cameraUsageDescription: + locationUsageDescription: + microphoneUsageDescription: + bluetoothUsageDescription: + switchNMETAOverride: + switchNetLibKey: + switchSocketMemoryPoolSize: 6144 + switchSocketAllocatorPoolSize: 128 + switchSocketConcurrencyLimit: 14 + switchScreenResolutionBehavior: 2 + switchUseCPUProfiler: 0 + switchUseGOLDLinker: 0 + switchLTOSetting: 0 + switchApplicationID: 0x01004b9000490000 + switchNSODependencies: + switchTitleNames_0: + switchTitleNames_1: + switchTitleNames_2: + switchTitleNames_3: + switchTitleNames_4: + switchTitleNames_5: + switchTitleNames_6: + switchTitleNames_7: + switchTitleNames_8: + switchTitleNames_9: + switchTitleNames_10: + switchTitleNames_11: + switchTitleNames_12: + switchTitleNames_13: + switchTitleNames_14: + switchTitleNames_15: + switchPublisherNames_0: + switchPublisherNames_1: + switchPublisherNames_2: + switchPublisherNames_3: + switchPublisherNames_4: + switchPublisherNames_5: + switchPublisherNames_6: + switchPublisherNames_7: + switchPublisherNames_8: + switchPublisherNames_9: + switchPublisherNames_10: + switchPublisherNames_11: + switchPublisherNames_12: + switchPublisherNames_13: + switchPublisherNames_14: + switchPublisherNames_15: + switchIcons_0: {fileID: 0} + switchIcons_1: {fileID: 0} + switchIcons_2: {fileID: 0} + switchIcons_3: {fileID: 0} + switchIcons_4: {fileID: 0} + switchIcons_5: {fileID: 0} + switchIcons_6: {fileID: 0} + switchIcons_7: {fileID: 0} + switchIcons_8: {fileID: 0} + switchIcons_9: {fileID: 0} + switchIcons_10: {fileID: 0} + switchIcons_11: {fileID: 0} + switchIcons_12: {fileID: 0} + switchIcons_13: {fileID: 0} + switchIcons_14: {fileID: 0} + switchIcons_15: {fileID: 0} + switchSmallIcons_0: {fileID: 0} + switchSmallIcons_1: {fileID: 0} + switchSmallIcons_2: {fileID: 0} + switchSmallIcons_3: {fileID: 0} + switchSmallIcons_4: {fileID: 0} + switchSmallIcons_5: {fileID: 0} + switchSmallIcons_6: {fileID: 0} + switchSmallIcons_7: {fileID: 0} + switchSmallIcons_8: {fileID: 0} + switchSmallIcons_9: {fileID: 0} + switchSmallIcons_10: {fileID: 0} + switchSmallIcons_11: {fileID: 0} + switchSmallIcons_12: {fileID: 0} + switchSmallIcons_13: {fileID: 0} + switchSmallIcons_14: {fileID: 0} + switchSmallIcons_15: {fileID: 0} + switchManualHTML: + switchAccessibleURLs: + switchLegalInformation: + switchMainThreadStackSize: 1048576 + switchPresenceGroupId: + switchLogoHandling: 0 + switchReleaseVersion: 0 + switchDisplayVersion: 1.0.0 + switchStartupUserAccount: 0 + switchTouchScreenUsage: 0 + switchSupportedLanguagesMask: 0 + switchLogoType: 0 + switchApplicationErrorCodeCategory: + switchUserAccountSaveDataSize: 0 + switchUserAccountSaveDataJournalSize: 0 + switchApplicationAttribute: 0 + switchCardSpecSize: -1 + switchCardSpecClock: -1 + switchRatingsMask: 0 + switchRatingsInt_0: 0 + switchRatingsInt_1: 0 + switchRatingsInt_2: 0 + switchRatingsInt_3: 0 + switchRatingsInt_4: 0 + switchRatingsInt_5: 0 + switchRatingsInt_6: 0 + switchRatingsInt_7: 0 + switchRatingsInt_8: 0 + switchRatingsInt_9: 0 + switchRatingsInt_10: 0 + switchRatingsInt_11: 0 + switchRatingsInt_12: 0 + switchLocalCommunicationIds_0: + switchLocalCommunicationIds_1: + switchLocalCommunicationIds_2: + switchLocalCommunicationIds_3: + switchLocalCommunicationIds_4: + switchLocalCommunicationIds_5: + switchLocalCommunicationIds_6: + switchLocalCommunicationIds_7: + switchParentalControl: 0 + switchAllowsScreenshot: 1 + switchAllowsVideoCapturing: 1 + switchAllowsRuntimeAddOnContentInstall: 0 + switchDataLossConfirmation: 0 + switchUserAccountLockEnabled: 0 + switchSystemResourceMemory: 16777216 + switchSupportedNpadStyles: 22 + switchNativeFsCacheSize: 32 + switchIsHoldTypeHorizontal: 0 + switchSupportedNpadCount: 8 + switchSocketConfigEnabled: 0 + switchTcpInitialSendBufferSize: 32 + switchTcpInitialReceiveBufferSize: 64 + switchTcpAutoSendBufferSizeMax: 256 + switchTcpAutoReceiveBufferSizeMax: 256 + switchUdpSendBufferSize: 9 + switchUdpReceiveBufferSize: 42 + switchSocketBufferEfficiency: 4 + switchSocketInitializeEnabled: 1 + switchNetworkInterfaceManagerInitializeEnabled: 1 + switchPlayerConnectionEnabled: 1 + switchUseNewStyleFilepaths: 0 + switchUseMicroSleepForYield: 1 + switchEnableRamDiskSupport: 0 + switchMicroSleepForYieldTime: 25 + switchRamDiskSpaceSize: 12 + ps4NPAgeRating: 12 + ps4NPTitleSecret: + ps4NPTrophyPackPath: + ps4ParentalLevel: 11 + ps4ContentID: ED1633-NPXX51362_00-0000000000000000 + ps4Category: 0 + ps4MasterVersion: 01.00 + ps4AppVersion: 01.00 + ps4AppType: 0 + ps4ParamSfxPath: + ps4VideoOutPixelFormat: 0 + ps4VideoOutInitialWidth: 1920 + ps4VideoOutBaseModeInitialWidth: 1920 + ps4VideoOutReprojectionRate: 60 + ps4PronunciationXMLPath: + ps4PronunciationSIGPath: + ps4BackgroundImagePath: + ps4StartupImagePath: + ps4StartupImagesFolder: + ps4IconImagesFolder: + ps4SaveDataImagePath: + ps4SdkOverride: + ps4BGMPath: + ps4ShareFilePath: + ps4ShareOverlayImagePath: + ps4PrivacyGuardImagePath: + ps4ExtraSceSysFile: + ps4NPtitleDatPath: + ps4RemotePlayKeyAssignment: -1 + ps4RemotePlayKeyMappingDir: + ps4PlayTogetherPlayerCount: 0 + ps4EnterButtonAssignment: 1 + ps4ApplicationParam1: 0 + ps4ApplicationParam2: 0 + ps4ApplicationParam3: 0 + ps4ApplicationParam4: 0 + ps4DownloadDataSize: 0 + ps4GarlicHeapSize: 2048 + ps4ProGarlicHeapSize: 2560 + playerPrefsMaxSize: 32768 + ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ + ps4pnSessions: 1 + ps4pnPresence: 1 + ps4pnFriends: 1 + ps4pnGameCustomData: 1 + playerPrefsSupport: 0 + enableApplicationExit: 0 + resetTempFolder: 1 + restrictedAudioUsageRights: 0 + ps4UseResolutionFallback: 0 + ps4ReprojectionSupport: 0 + ps4UseAudio3dBackend: 0 + ps4UseLowGarlicFragmentationMode: 1 + ps4SocialScreenEnabled: 0 + ps4ScriptOptimizationLevel: 0 + ps4Audio3dVirtualSpeakerCount: 14 + ps4attribCpuUsage: 0 + ps4PatchPkgPath: + ps4PatchLatestPkgPath: + ps4PatchChangeinfoPath: + ps4PatchDayOne: 0 + ps4attribUserManagement: 0 + ps4attribMoveSupport: 0 + ps4attrib3DSupport: 0 + ps4attribShareSupport: 0 + ps4attribExclusiveVR: 0 + ps4disableAutoHideSplash: 0 + ps4videoRecordingFeaturesUsed: 0 + ps4contentSearchFeaturesUsed: 0 + ps4CompatibilityPS5: 0 + ps4GPU800MHz: 1 + ps4attribEyeToEyeDistanceSettingVR: 0 + ps4IncludedModules: [] + ps4attribVROutputEnabled: 0 + monoEnv: + splashScreenBackgroundSourceLandscape: {fileID: 0} + splashScreenBackgroundSourcePortrait: {fileID: 0} + blurSplashScreenBackground: 1 + spritePackerPolicy: + webGLMemorySize: 16 + webGLExceptionSupport: 1 + webGLNameFilesAsHashes: 0 + webGLDataCaching: 1 + webGLDebugSymbols: 0 + webGLEmscriptenArgs: + webGLModulesDirectory: + webGLTemplate: APPLICATION:Default + webGLAnalyzeBuildSize: 0 + webGLUseEmbeddedResources: 0 + webGLCompressionFormat: 1 + webGLWasmArithmeticExceptions: 0 + webGLLinkerTarget: 1 + webGLThreadsSupport: 0 + webGLDecompressionFallback: 0 + scriptingDefineSymbols: {} + additionalCompilerArguments: {} + platformArchitecture: {} + scriptingBackend: {} + il2cppCompilerConfiguration: {} + managedStrippingLevel: {} + incrementalIl2cppBuild: {} + suppressCommonWarnings: 1 + allowUnsafeCode: 0 + useDeterministicCompilation: 1 + enableRoslynAnalyzers: 1 + additionalIl2CppArgs: + scriptingRuntimeVersion: 1 + gcIncremental: 1 + assemblyVersionValidation: 1 + gcWBarrierValidation: 0 + apiCompatibilityLevelPerPlatform: {} + m_RenderingPath: 1 + m_MobileRenderingPath: 1 + metroPackageName: Template_3D + metroPackageVersion: + metroCertificatePath: + metroCertificatePassword: + metroCertificateSubject: + metroCertificateIssuer: + metroCertificateNotAfter: 0000000000000000 + metroApplicationDescription: Template_3D + wsaImages: {} + metroTileShortName: + metroTileShowName: 0 + metroMediumTileShowName: 0 + metroLargeTileShowName: 0 + metroWideTileShowName: 0 + metroSupportStreamingInstall: 0 + metroLastRequiredScene: 0 + metroDefaultTileSize: 1 + metroTileForegroundText: 2 + metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} + metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, a: 1} + metroSplashScreenUseBackgroundColor: 0 + platformCapabilities: {} + metroTargetDeviceFamilies: {} + metroFTAName: + metroFTAFileTypes: [] + metroProtocolName: + vcxProjDefaultLanguage: + XboxOneProductId: + XboxOneUpdateKey: + XboxOneSandboxId: + XboxOneContentId: + XboxOneTitleId: + XboxOneSCId: + XboxOneGameOsOverridePath: + XboxOnePackagingOverridePath: + XboxOneAppManifestOverridePath: + XboxOneVersion: 1.0.0.0 + XboxOnePackageEncryption: 0 + XboxOnePackageUpdateGranularity: 2 + XboxOneDescription: + XboxOneLanguage: + - enus + XboxOneCapability: [] + XboxOneGameRating: {} + XboxOneIsContentPackage: 0 + XboxOneEnhancedXboxCompatibilityMode: 0 + XboxOneEnableGPUVariability: 1 + XboxOneSockets: {} + XboxOneSplashScreen: {fileID: 0} + XboxOneAllowedProductIds: [] + XboxOnePersistentLocalStorageSize: 0 + XboxOneXTitleMemory: 8 + XboxOneOverrideIdentityName: + XboxOneOverrideIdentityPublisher: + vrEditorSettings: {} + cloudServicesEnabled: + UNet: 1 + luminIcon: + m_Name: + m_ModelFolderPath: + m_PortalFolderPath: + luminCert: + m_CertPath: + m_SignPackage: 1 + luminIsChannelApp: 0 + luminVersion: + m_VersionCode: 1 + m_VersionName: + apiCompatibilityLevel: 6 + activeInputHandler: 0 + cloudProjectId: + framebufferDepthMemorylessMode: 0 + qualitySettingsNames: [] + projectName: + organizationId: + cloudEnabled: 0 + legacyClampBlendShapeWeights: 0 + playerDataPath: + forceSRGBBlit: 1 + virtualTexturingSupportEnabled: 0 diff --git a/X10D.Unity.Tests/ProjectSettings/ProjectVersion.txt b/X10D.Unity.Tests/ProjectSettings/ProjectVersion.txt new file mode 100644 index 0000000..3dcb827 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/ProjectVersion.txt @@ -0,0 +1,2 @@ +m_EditorVersion: 2021.3.2f1 +m_EditorVersionWithRevision: 2021.3.2f1 (d6360bedb9a0) diff --git a/X10D.Unity.Tests/ProjectSettings/QualitySettings.asset b/X10D.Unity.Tests/ProjectSettings/QualitySettings.asset new file mode 100644 index 0000000..7b7658d --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/QualitySettings.asset @@ -0,0 +1,232 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!47 &1 +QualitySettings: + m_ObjectHideFlags: 0 + serializedVersion: 5 + m_CurrentQuality: 5 + m_QualitySettings: + - serializedVersion: 2 + name: Very Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 15 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 1 + textureQuality: 1 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.3 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Low + pixelLightCount: 0 + shadows: 0 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 0 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 0 + lodBias: 0.4 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 16 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Medium + pixelLightCount: 1 + shadows: 1 + shadowResolution: 0 + shadowProjection: 1 + shadowCascades: 1 + shadowDistance: 20 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 0 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 0 + realtimeReflectionProbes: 0 + billboardsFaceCameraPosition: 0 + vSyncCount: 1 + lodBias: 0.7 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 64 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: High + pixelLightCount: 2 + shadows: 2 + shadowResolution: 1 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 40 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 2 + textureQuality: 0 + anisotropicTextures: 1 + antiAliasing: 0 + softParticles: 0 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 256 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Very High + pixelLightCount: 3 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 2 + shadowDistance: 70 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 1.5 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 1024 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + - serializedVersion: 2 + name: Ultra + pixelLightCount: 4 + shadows: 2 + shadowResolution: 2 + shadowProjection: 1 + shadowCascades: 4 + shadowDistance: 150 + shadowNearPlaneOffset: 3 + shadowCascade2Split: 0.33333334 + shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} + shadowmaskMode: 1 + blendWeights: 4 + textureQuality: 0 + anisotropicTextures: 2 + antiAliasing: 2 + softParticles: 1 + softVegetation: 1 + realtimeReflectionProbes: 1 + billboardsFaceCameraPosition: 1 + vSyncCount: 1 + lodBias: 2 + maximumLODLevel: 0 + streamingMipmapsActive: 0 + streamingMipmapsAddAllCameras: 1 + streamingMipmapsMemoryBudget: 512 + streamingMipmapsRenderersPerFrame: 512 + streamingMipmapsMaxLevelReduction: 2 + streamingMipmapsMaxFileIORequests: 1024 + particleRaycastBudget: 4096 + asyncUploadTimeSlice: 2 + asyncUploadBufferSize: 16 + asyncUploadPersistentBuffer: 1 + resolutionScalingFixedDPIFactor: 1 + excludedTargetPlatforms: [] + m_PerPlatformDefaultQuality: + Android: 2 + Lumin: 5 + Nintendo 3DS: 5 + Nintendo Switch: 5 + PS4: 5 + PSP2: 2 + Stadia: 5 + Standalone: 5 + WebGL: 3 + Windows Store Apps: 5 + XboxOne: 5 + iPhone: 2 + tvOS: 2 diff --git a/X10D.Unity.Tests/ProjectSettings/RiderScriptEditorPersistedState.asset b/X10D.Unity.Tests/ProjectSettings/RiderScriptEditorPersistedState.asset new file mode 100644 index 0000000..9f5ce87 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/RiderScriptEditorPersistedState.asset @@ -0,0 +1,15 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!114 &1 +MonoBehaviour: + m_ObjectHideFlags: 61 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 0} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 0} + m_Name: + m_EditorClassIdentifier: Unity.Rider.Editor:Packages.Rider.Editor:RiderScriptEditorPersistedState + lastWriteTicks: -8585496032972088364 diff --git a/X10D.Unity.Tests/ProjectSettings/SceneTemplateSettings.json b/X10D.Unity.Tests/ProjectSettings/SceneTemplateSettings.json new file mode 100644 index 0000000..6f3e60f --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/SceneTemplateSettings.json @@ -0,0 +1,167 @@ +{ + "templatePinStates": [], + "dependencyTypeInfos": [ + { + "userAdded": false, + "type": "UnityEngine.AnimationClip", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.Animations.AnimatorController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.AnimatorOverrideController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.Audio.AudioMixerController", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.ComputeShader", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Cubemap", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.GameObject", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.LightingDataAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": false + }, + { + "userAdded": false, + "type": "UnityEngine.LightingSettings", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Material", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.MonoScript", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.PhysicMaterial", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.PhysicsMaterial2D", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.PostProcessing.PostProcessProfile", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.PostProcessing.PostProcessResources", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Rendering.VolumeProfile", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEditor.SceneAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": false + }, + { + "userAdded": false, + "type": "UnityEngine.Shader", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.ShaderVariantCollection", + "ignore": true, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Texture", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Texture2D", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + }, + { + "userAdded": false, + "type": "UnityEngine.Timeline.TimelineAsset", + "ignore": false, + "defaultInstantiationMode": 0, + "supportsModification": true + } + ], + "defaultDependencyTypeInfo": { + "userAdded": false, + "type": "", + "ignore": false, + "defaultInstantiationMode": 1, + "supportsModification": true + }, + "newSceneOverride": 0 +} \ No newline at end of file diff --git a/X10D.Unity.Tests/ProjectSettings/TagManager.asset b/X10D.Unity.Tests/ProjectSettings/TagManager.asset new file mode 100644 index 0000000..1c92a78 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/TagManager.asset @@ -0,0 +1,43 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!78 &1 +TagManager: + serializedVersion: 2 + tags: [] + layers: + - Default + - TransparentFX + - Ignore Raycast + - + - Water + - UI + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + m_SortingLayers: + - name: Default + uniqueID: 0 + locked: 0 diff --git a/X10D.Unity.Tests/ProjectSettings/TimeManager.asset b/X10D.Unity.Tests/ProjectSettings/TimeManager.asset new file mode 100644 index 0000000..558a017 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/TimeManager.asset @@ -0,0 +1,9 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!5 &1 +TimeManager: + m_ObjectHideFlags: 0 + Fixed Timestep: 0.02 + Maximum Allowed Timestep: 0.33333334 + m_TimeScale: 1 + Maximum Particle Timestep: 0.03 diff --git a/X10D.Unity.Tests/ProjectSettings/UnityConnectSettings.asset b/X10D.Unity.Tests/ProjectSettings/UnityConnectSettings.asset new file mode 100644 index 0000000..6125b30 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/UnityConnectSettings.asset @@ -0,0 +1,35 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!310 &1 +UnityConnectSettings: + m_ObjectHideFlags: 0 + serializedVersion: 1 + m_Enabled: 0 + m_TestMode: 0 + m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events + m_EventUrl: https://cdp.cloud.unity3d.com/v1/events + m_ConfigUrl: https://config.uca.cloud.unity3d.com + m_DashboardUrl: https://dashboard.unity3d.com + m_TestInitMode: 0 + CrashReportingSettings: + m_EventUrl: https://perf-events.cloud.unity3d.com + m_Enabled: 0 + m_LogBufferSize: 10 + m_CaptureEditorExceptions: 1 + UnityPurchasingSettings: + m_Enabled: 0 + m_TestMode: 0 + UnityAnalyticsSettings: + m_Enabled: 0 + m_TestMode: 0 + m_InitializeOnStartup: 1 + UnityAdsSettings: + m_Enabled: 0 + m_InitializeOnStartup: 1 + m_TestMode: 0 + m_IosGameId: + m_AndroidGameId: + m_GameIds: {} + m_GameId: + PerformanceReportingSettings: + m_Enabled: 0 diff --git a/X10D.Unity.Tests/ProjectSettings/VFXManager.asset b/X10D.Unity.Tests/ProjectSettings/VFXManager.asset new file mode 100644 index 0000000..3a95c98 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/VFXManager.asset @@ -0,0 +1,12 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!937362698 &1 +VFXManager: + m_ObjectHideFlags: 0 + m_IndirectShader: {fileID: 0} + m_CopyBufferShader: {fileID: 0} + m_SortShader: {fileID: 0} + m_StripUpdateShader: {fileID: 0} + m_RenderPipeSettingsPath: + m_FixedTimeStep: 0.016666668 + m_MaxDeltaTime: 0.05 diff --git a/X10D.Unity.Tests/ProjectSettings/VersionControlSettings.asset b/X10D.Unity.Tests/ProjectSettings/VersionControlSettings.asset new file mode 100644 index 0000000..dca2881 --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/VersionControlSettings.asset @@ -0,0 +1,8 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!890905787 &1 +VersionControlSettings: + m_ObjectHideFlags: 0 + m_Mode: Visible Meta Files + m_CollabEditorSettings: + inProgressEnabled: 1 diff --git a/X10D.Unity.Tests/ProjectSettings/XRSettings.asset b/X10D.Unity.Tests/ProjectSettings/XRSettings.asset new file mode 100644 index 0000000..482590c --- /dev/null +++ b/X10D.Unity.Tests/ProjectSettings/XRSettings.asset @@ -0,0 +1,10 @@ +{ + "m_SettingKeys": [ + "VR Device Disabled", + "VR Device User Alert" + ], + "m_SettingValues": [ + "False", + "False" + ] +} \ No newline at end of file diff --git a/X10D.Unity.Tests/ProjectSettings/boot.config b/X10D.Unity.Tests/ProjectSettings/boot.config new file mode 100644 index 0000000..e69de29 diff --git a/X10D.Unity/X10D.Unity.csproj b/X10D.Unity/X10D.Unity.csproj new file mode 100644 index 0000000..271cd77 --- /dev/null +++ b/X10D.Unity/X10D.Unity.csproj @@ -0,0 +1,65 @@ + + + + netstandard2.1 + 10.0 + true + true + Oliver Booth + en + https://github.com/oliverbooth/X10D + git + Extension methods on crack. + LICENSE.md + icon.png + + dotnet extension-methods + true + 3.1.0 + enable + true + true + + + + $(VersionPrefix)-$(VersionSuffix) + $(VersionPrefix).0 + $(VersionPrefix).0 + + + + $(VersionPrefix)-$(VersionSuffix).$(BuildNumber) + $(VersionPrefix).$(BuildNumber) + $(VersionPrefix).$(BuildNumber) + + + + $(VersionPrefix) + $(VersionPrefix).0 + $(VersionPrefix).0 + + + + + + + + + + + + + True + + + + True + + + + True + + + + + diff --git a/X10D.Unity/src/ComponentExtensions.cs b/X10D.Unity/src/ComponentExtensions.cs new file mode 100644 index 0000000..6ad7388 --- /dev/null +++ b/X10D.Unity/src/ComponentExtensions.cs @@ -0,0 +1,21 @@ +using UnityEngine; + +namespace X10D.Unity; + +/// +/// Extension methods for . +/// +public static class ComponentExtensions +{ + /// + /// Returns an array of components of the specified type, excluding components that live on the object to which this + /// component is attached. + /// + /// The component whose child components to retrieve. + /// The type of the components to retrieve. + /// An array representing the child components. + public static T[] GetComponentsInChildrenOnly(this Component component) + { + return component.gameObject.GetComponentsInChildrenOnly(); + } +} diff --git a/X10D.Unity/src/Drawing/Color32Extensions.cs b/X10D.Unity/src/Drawing/Color32Extensions.cs new file mode 100644 index 0000000..363f14d --- /dev/null +++ b/X10D.Unity/src/Drawing/Color32Extensions.cs @@ -0,0 +1,95 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace X10D.Unity.Drawing; + +/// +/// Drawing-related extensions for . +/// +public static class Color32Extensions +{ + /// + /// Returns a new with the red, green, and blue components inverted. Alpha is not affected. + /// + /// The color to invert. + /// The inverted color. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color32 Inverted(this Color32 color) + { + return new Color32((byte)(255 - color.r), (byte)(255 - color.g), (byte)(255 - color.b), color.a); + } + + /// + /// Returns a vector whose red, green, and blue components are the same as the specified color, and whose alpha component + /// is a new value. + /// + /// The color to copy. + /// The new alpha component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color32 WithA(this Color32 color, byte a) + { + return color with {a = a}; + } + + /// + /// Returns a vector whose red, green, and alpha components are the same as the specified color, and whose blue component + /// is a new value. + /// + /// The color to copy. + /// The new blue component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color32 WithB(this Color32 color, byte b) + { + return color with {b = b}; + } + + /// + /// Returns a vector whose red, blue, and alpha components are the same as the specified color, and whose green component + /// is a new value. + /// + /// The color to copy. + /// The new green component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color32 WithG(this Color32 color, byte g) + { + return color with {g = g}; + } + + /// + /// Returns a vector whose green, blue, and alpha components are the same as the specified color, and whose red component + /// is a new value. + /// + /// The color to copy. + /// The new red component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color32 WithR(this Color32 color, byte r) + { + return color with {r = r}; + } +} diff --git a/X10D.Unity/src/Drawing/ColorExtensions.cs b/X10D.Unity/src/Drawing/ColorExtensions.cs new file mode 100644 index 0000000..95a6561 --- /dev/null +++ b/X10D.Unity/src/Drawing/ColorExtensions.cs @@ -0,0 +1,95 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace X10D.Unity.Drawing; + +/// +/// Drawing-related extensions for . +/// +public static class ColorExtensions +{ + /// + /// Returns a new with the red, green, and blue components inverted. Alpha is not affected. + /// + /// The color to invert. + /// The inverted color. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color Inverted(this Color color) + { + return new Color(1f - color.r, 1f - color.g, 1f - color.b, color.a); + } + + /// + /// Returns a vector whose red, green, and blue components are the same as the specified color, and whose alpha component + /// is a new value. + /// + /// The color to copy. + /// The new alpha component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color WithA(this Color color, float a) + { + return color with {a = a}; + } + + /// + /// Returns a vector whose red, green, and alpha components are the same as the specified color, and whose blue component + /// is a new value. + /// + /// The color to copy. + /// The new blue component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color WithB(this Color color, float b) + { + return color with {b = b}; + } + + /// + /// Returns a vector whose red, blue, and alpha components are the same as the specified color, and whose green component + /// is a new value. + /// + /// The color to copy. + /// The new green component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color WithG(this Color color, float g) + { + return color with {g = g}; + } + + /// + /// Returns a vector whose green, blue, and alpha components are the same as the specified color, and whose red component + /// is a new value. + /// + /// The color to copy. + /// The new red component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Color WithR(this Color color, float r) + { + return color with {r = r}; + } +} diff --git a/X10D.Unity/src/Drawing/RandomExtensions.cs b/X10D.Unity/src/Drawing/RandomExtensions.cs new file mode 100644 index 0000000..2e90807 --- /dev/null +++ b/X10D.Unity/src/Drawing/RandomExtensions.cs @@ -0,0 +1,95 @@ +using UnityEngine; +using X10D.Core; +using Random = System.Random; + +namespace X10D.Unity.Drawing; + +/// +/// Extension methods for . +/// +public static class RandomExtensions +{ + /// + /// Returns an HDR color of random components for red, green, and blue. + /// + /// The instance. + /// A whose red, green, and blue components are all random, and whose alpha is 255 + /// is . + public static Color NextColorRgb(this Random random) + { + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } + + int seed = random.Next(); + var seededRandom = new Random(seed); + float r = seededRandom.NextSingle(); + float g = seededRandom.NextSingle(); + float b = seededRandom.NextSingle(); + return new Color(r, g, b, 1.0f); + } + + /// + /// Returns an HDR color composed of random components for apha, red, green, and blue. + /// + /// The instance. + /// A whose alpha, red, green, and blue components are all random. + /// is . + public static Color NextColorArgb(this Random random) + { + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } + + int seed = random.Next(); + var seededRandom = new Random(seed); + float a = seededRandom.NextSingle(); + float r = seededRandom.NextSingle(); + float g = seededRandom.NextSingle(); + float b = seededRandom.NextSingle(); + return new Color(r, g, b, a); + } + + /// + /// Returns a color of random components for red, green, and blue. + /// + /// The instance. + /// A whose red, green, and blue components are all random, and whose alpha is 255 + /// is . + public static Color32 NextColor32Rgb(this Random random) + { + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } + + int rgb = random.Next(); + var r = (byte)(rgb >> 16 & 0xFF); + var g = (byte)(rgb >> 8 & 0xFF); + var b = (byte)(rgb & 0xFF); + return new Color32(r, g, b, 0xFF); + } + + /// + /// Returns a color composed of random components for apha, red, green, and blue. + /// + /// The instance. + /// A whose alpha, red, green, and blue components are all random. + /// is . + public static Color32 NextColor32Argb(this Random random) + { + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } + + int argb = random.Next(); + var a = (byte)(argb >> 24 & 0xFF); + var r = (byte)(argb >> 16 & 0xFF); + var g = (byte)(argb >> 8 & 0xFF); + var b = (byte)(argb & 0xFF); + return new Color32(r, g, b, a); + } +} diff --git a/X10D.Unity/src/GameObjectExtensions.cs b/X10D.Unity/src/GameObjectExtensions.cs new file mode 100644 index 0000000..97d03d3 --- /dev/null +++ b/X10D.Unity/src/GameObjectExtensions.cs @@ -0,0 +1,317 @@ +using UnityEngine; + +namespace X10D.Unity; + +/// +/// Extension methods for . +/// +public static class GameObjectExtensions +{ + /// + /// Returns an array of components of the specified type, excluding components that live on this game object. + /// + /// The game object whose child components to retrieve. + /// The type of the components to retrieve. + /// An array representing the child components. + public static T[] GetComponentsInChildrenOnly(this GameObject gameObject) + { + var components = new List(gameObject.GetComponentsInChildren()); + + for (var index = 0; index < components.Count; index++) + { + if (components[index] is not Component childComponent) + { + // this shouldn't happen, since you can't add a non-Component to a game object, + // but GetComponentsInChildren is not constrained, so this method shouldn't be either + continue; + } + + if (childComponent.transform.parent != gameObject.transform) + { + components.RemoveAt(index); + index--; + } + } + + return components.ToArray(); + } + + /// + /// Rotates the transform component of this game object so the forward vector points at another game object. + /// + /// The game object whose rotation will be changed. + /// The game object to look at. + /// + /// is . + /// -or- + /// is . + /// + public static void LookAt(this GameObject gameObject, GameObject target) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + gameObject.transform.LookAt(target.transform); + } + + /// + /// Rotates the transform component of this game object so the forward vector points at . + /// + /// The game object whose rotation will be changed. + /// The point to look at. + /// is . + public static void LookAt(this GameObject gameObject, Vector3 target) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + gameObject.transform.LookAt(target); + } + + /// + /// Rotates the transform component of this game object so the forward vector points at a specified transform. + /// + /// The game object whose rotation will be changed. + /// The transform to look at. + /// + /// is . + /// -or- + /// is . + /// + public static void LookAt(this GameObject gameObject, Transform target) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + gameObject.transform.LookAt(target); + } + + /// + /// Rotates the transform component of this game object so the forward vector points at another game object. + /// + /// The game object whose rotation will be changed. + /// The game object to look at. + /// A vector specifying the upward direction. + /// + /// is . + /// -or- + /// is . + /// + public static void LookAt(this GameObject gameObject, GameObject target, Vector3 worldUp) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + gameObject.transform.LookAt(target.transform, worldUp); + } + + /// + /// Rotates the transform component of this game object so the forward vector points at . + /// + /// The game object whose rotation will be changed. + /// The point to look at. + /// A vector specifying the upward direction. + /// is . + public static void LookAt(this GameObject gameObject, Vector3 target, Vector3 worldUp) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + gameObject.transform.LookAt(target, worldUp); + } + + /// + /// Rotates the transform component of this game object so the forward vector points at a specified transform. + /// + /// The game object whose rotation will be changed. + /// The transform to look at. + /// A vector specifying the upward direction. + /// + /// is . + /// -or- + /// is . + /// + public static void LookAt(this GameObject gameObject, Transform target, Vector3 worldUp) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + gameObject.transform.LookAt(target, worldUp); + } + + /// + /// Sets the new layer of this game object and its children, recursively. + /// + /// The game object whose layer, and that of its children recursively, to change. + /// The new layer. + /// is . + public static void SetLayerRecursively(this GameObject gameObject, int layer) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + var children = new Stack(); + var transform = gameObject.transform; + children.Push(transform); + + while (children.Count > 0) + { + Transform child = children.Pop(); + int childCount = child.childCount; + + child.gameObject.layer = layer; + + if (childCount <= 0) + { + continue; + } + + for (var childIndex = 0; childIndex < childCount; childIndex++) + { + children.Push(child.GetChild(childIndex)); + } + } + } + + /// + /// Sets the parent of this game object. + /// + /// The game object whose parent to change. + /// The new parent. + /// + /// is . + /// -or- + /// is . + /// + public static void SetParent(this GameObject gameObject, GameObject parent) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + if (parent == null) + { + throw new ArgumentNullException(nameof(parent)); + } + + gameObject.transform.SetParent(parent.transform); + } + + /// + /// Sets the parent of this game object. + /// + /// The game object whose parent to change. + /// The new parent. + /// + /// is . + /// -or- + /// is . + /// + public static void SetParent(this GameObject gameObject, Transform parent) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + if (parent == null) + { + throw new ArgumentNullException(nameof(parent)); + } + + gameObject.transform.SetParent(parent); + } + + /// + /// Sets the parent of this game object. + /// + /// The game object whose parent to change. + /// The new parent. + /// + /// to modify the parent-relative position, scale and rotation such that the object keeps the same + /// world space position, rotation and scale as before; otherwise, . + /// + /// + /// is . + /// -or- + /// is . + /// + public static void SetParent(this GameObject gameObject, GameObject parent, bool worldPositionStays) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + if (parent == null) + { + throw new ArgumentNullException(nameof(parent)); + } + + gameObject.transform.SetParent(parent.transform, worldPositionStays); + } + + /// + /// Sets the parent of this game object. + /// + /// The game object whose parent to change. + /// The new parent. + /// + /// to modify the parent-relative position, scale and rotation such that the object keeps the same + /// world space position, rotation and scale as before; otherwise, . + /// + /// + /// is . + /// -or- + /// is . + /// + public static void SetParent(this GameObject gameObject, Transform parent, bool worldPositionStays) + { + if (gameObject == null) + { + throw new ArgumentNullException(nameof(gameObject)); + } + + if (parent == null) + { + throw new ArgumentNullException(nameof(parent)); + } + + gameObject.transform.SetParent(parent, worldPositionStays); + } +} diff --git a/X10D.Unity/src/Numerics/QuaternionExtensions.cs b/X10D.Unity/src/Numerics/QuaternionExtensions.cs new file mode 100644 index 0000000..2c6355e --- /dev/null +++ b/X10D.Unity/src/Numerics/QuaternionExtensions.cs @@ -0,0 +1,35 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace X10D.Unity.Numerics; + +/// +/// Numeric-extensions for . +/// +public static class QuaternionExtensions +{ + /// + /// Converts the current quaternion to a . + /// + /// The quaternion to convert. + /// The converted quaternion. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static System.Numerics.Quaternion ToSystemQuaternion(this Quaternion quaternion) + { + return new System.Numerics.Quaternion(quaternion.x, quaternion.y, quaternion.z, quaternion.w); + } + + /// + /// Converts the current quaternion to a . + /// + /// The quaternion to convert. + /// The converted quaternion. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Quaternion ToUnityQuaternion(this System.Numerics.Quaternion quaternion) + { + return new Quaternion(quaternion.X, quaternion.Y, quaternion.Z, quaternion.W); + } +} diff --git a/X10D.Unity/src/Numerics/RandomExtensions.cs b/X10D.Unity/src/Numerics/RandomExtensions.cs new file mode 100644 index 0000000..3b10b79 --- /dev/null +++ b/X10D.Unity/src/Numerics/RandomExtensions.cs @@ -0,0 +1,118 @@ +using UnityEngine; +using X10D.Core; +using Random = System.Random; + +namespace X10D.Unity.Numerics; + +/// +/// Extension methods for . +/// +public static class RandomExtensions +{ + /// + /// Returns a randomly generated rotation as represented by a . + /// + /// The instance. + /// + /// A constructed from 3 random single-precision floating point numbers representing the + /// yaw, pitch, and roll. + /// + /// is . + public static Quaternion NextRotation(this Random random) + { + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } + + int seed = random.Next(); + var seededRandom = new Random(seed); + + float x = seededRandom.NextSingle(0, 360); + float y = seededRandom.NextSingle(0, 360); + float z = seededRandom.NextSingle(0, 360); + + return Quaternion.Euler(x, y, z); + } + + /// + /// Returns a randomly generated rotation with uniform distribution. + /// + /// The instance. + /// A constructed with uniform distribution. + /// is . + public static Quaternion NextRotationUniform(this Random random) + { + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } + + int seed = random.Next(); + var seededRandom = new Random(seed); + float normal, w, x, y, z; + + do + { + w = seededRandom.NextSingle(-1f, 1f); + x = seededRandom.NextSingle(-1f, 1f); + y = seededRandom.NextSingle(-1f, 1f); + z = seededRandom.NextSingle(-1f, 1f); + normal = (w * w) + (x * x) + (y * y) + (z * z); + } while (normal is 0f or > 1f); + + normal = MathF.Sqrt(normal); + return new Quaternion(x / normal, y / normal, z / normal, w / normal); + } + + /// + /// Returns a with magnitude 1 whose components indicate a random point on the unit circle. + /// + /// The instance + /// + /// A whose returns 1, and whose components indicate a random + /// point on the unit circle. + /// + public static Vector2 NextUnitVector2(this Random random) + { + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } + + // no need to construct a seeded random here, since we only call Next once + + float angle = random.NextSingle(0, MathF.PI * 2.0f); + float x = MathF.Cos(angle); + float y = MathF.Sin(angle); + + return new Vector2(x, y); + } + + /// + /// Returns a with magnitude 1 whose components indicate a random point on the unit sphere. + /// + /// The instance + /// + /// A whose returns 1, and whose components indicate a random + /// point on the unit sphere. + /// + public static Vector3 NextUnitVector3(this Random random) + { + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } + + int seed = random.Next(); + var seededRandom = new Random(seed); + + float angle = seededRandom.NextSingle(0, MathF.PI * 2.0f); + float z = seededRandom.NextSingle(-1, 1); + float mp = MathF.Sqrt(1 - (z * z)); + float x = mp * MathF.Cos(angle); + float y = mp * MathF.Sin(angle); + + return new Vector3(x, y, z); + } +} diff --git a/X10D.Unity/src/Numerics/Vector2Extensions.cs b/X10D.Unity/src/Numerics/Vector2Extensions.cs new file mode 100644 index 0000000..32ff372 --- /dev/null +++ b/X10D.Unity/src/Numerics/Vector2Extensions.cs @@ -0,0 +1,67 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace X10D.Unity.Numerics; + +/// +/// Numeric-extensions for . +/// +public static class Vector2Extensions +{ + /// + /// Converts the current vector to a . + /// + /// The vector to convert. + /// The converted vector. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static System.Numerics.Vector2 ToSystemVector(this Vector2 vector) + { + return new System.Numerics.Vector2(vector.x, vector.y); + } + + /// + /// Converts the current vector to a . + /// + /// The vector to convert. + /// The converted vector. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 ToUnityVector(this System.Numerics.Vector2 vector) + { + return new Vector2(vector.X, vector.Y); + } + + /// + /// Returns a vector whose Y component is the same as the specified vector, and whose X component is a new value. + /// + /// The vector to copy. + /// The new X component value. + /// + /// A new instance of whose components is the same as that of + /// , and whose component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 WithX(this Vector2 vector, float x) + { + return vector with {x = x}; + } + + /// + /// Returns a vector whose X component is the same as the specified vector, and whose Y component is a new value. + /// + /// The vector to copy. + /// The new Y component value. + /// + /// A new instance of whose components is the same as that of + /// , and whose component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector2 WithY(this Vector2 vector, float y) + { + return vector with {y = y}; + } +} diff --git a/X10D.Unity/src/Numerics/Vector3Extensions.cs b/X10D.Unity/src/Numerics/Vector3Extensions.cs new file mode 100644 index 0000000..1b725ce --- /dev/null +++ b/X10D.Unity/src/Numerics/Vector3Extensions.cs @@ -0,0 +1,83 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace X10D.Unity.Numerics; + +/// +/// Numeric-extensions for . +/// +public static class Vector3Extensions +{ + /// + /// Converts the current vector to a . + /// + /// The vector to convert. + /// The converted vector. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static System.Numerics.Vector3 ToSystemVector(this Vector3 vector) + { + return new System.Numerics.Vector3(vector.x, vector.y, vector.z); + } + + /// + /// Converts the current vector to a . + /// + /// The vector to convert. + /// The converted vector. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 ToUnityVector(this System.Numerics.Vector3 vector) + { + return new Vector3(vector.X, vector.Y, vector.Z); + } + + /// + /// Returns a vector whose Y and Z components are the same as the specified vector, and whose X component is a new value. + /// + /// The vector to copy. + /// The new X component value. + /// + /// A new instance of whose and components are + /// the same as that of , and whose component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 WithX(this Vector3 vector, float x) + { + return vector with {x = x}; + } + + /// + /// Returns a vector whose X and Z components are the same as the specified vector, and whose Y component is a new value. + /// + /// The vector to copy. + /// The new Y component value. + /// + /// A new instance of whose and components are + /// the same as that of , and whose component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 WithY(this Vector3 vector, float y) + { + return vector with {y = y}; + } + + /// + /// Returns a vector whose X and Y components are the same as the specified vector, and whose Z component is a new value. + /// + /// The vector to copy. + /// The new Z component value. + /// + /// A new instance of whose and components are + /// the same as that of , and whose component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector3 WithZ(this Vector3 vector, float z) + { + return vector with {z = z}; + } +} diff --git a/X10D.Unity/src/Numerics/Vector4Extensions.cs b/X10D.Unity/src/Numerics/Vector4Extensions.cs new file mode 100644 index 0000000..ca2587f --- /dev/null +++ b/X10D.Unity/src/Numerics/Vector4Extensions.cs @@ -0,0 +1,107 @@ +using System.Diagnostics.Contracts; +using System.Runtime.CompilerServices; +using UnityEngine; + +namespace X10D.Unity.Numerics; + +/// +/// Numeric-extensions for . +/// +public static class Vector4Extensions +{ + /// + /// Converts the current vector to a . + /// + /// The vector to convert. + /// The converted vector. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static System.Numerics.Vector4 ToSystemVector(this Vector4 vector) + { + return new System.Numerics.Vector4(vector.x, vector.y, vector.z, vector.w); + } + + /// + /// Converts the current vector to a . + /// + /// The vector to convert. + /// The converted vector. + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 ToUnityVector(this System.Numerics.Vector4 vector) + { + return new Vector4(vector.X, vector.Y, vector.Z, vector.W); + } + + /// + /// Returns a vector whose Y, Z, and W components are the same as the specified vector, and whose X component is a new + /// value. + /// + /// The vector to copy. + /// The new X component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 WithX(this Vector4 vector, float x) + { + return vector with {x = x}; + } + + /// + /// Returns a vector whose X, Z, and W components are the same as the specified vector, and whose Y component is a new + /// value. + /// + /// The vector to copy. + /// The new Y component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 WithY(this Vector4 vector, float y) + { + return vector with {y = y}; + } + + /// + /// Returns a vector whose X, Y, and W components are the same as the specified vector, and whose Z component is a new + /// value. + /// + /// The vector to copy. + /// The new Z component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 WithZ(this Vector4 vector, float z) + { + return vector with {z = z}; + } + + /// + /// Returns a vector whose X, Y, and Z components are the same as the specified vector, and whose W component is a new + /// value. + /// + /// The vector to copy. + /// The new W component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static Vector4 WithW(this Vector4 vector, float w) + { + return vector with {w = w}; + } +} diff --git a/X10D.Unity/src/Singleton.cs b/X10D.Unity/src/Singleton.cs new file mode 100644 index 0000000..8e506db --- /dev/null +++ b/X10D.Unity/src/Singleton.cs @@ -0,0 +1,42 @@ +using UnityEngine; + +namespace X10D.Unity; + +/// +/// Represents a class which implements the singleton pattern for a specific . This class is not +/// thread-safe. +/// +/// The type of the singleton. +public abstract class Singleton : MonoBehaviour + where T : Singleton +{ + private static Lazy s_instanceLazy = new(CreateLazyInstanceInternal, false); + + /// + /// Gets the instance of the singleton. + /// + /// The singleton instance. + public static T Instance + { + get => s_instanceLazy.Value; + } + + /// + /// Called when the object is destroyed. + /// + protected virtual void OnDestroy() + { + s_instanceLazy = new Lazy(CreateLazyInstanceInternal, false); + } + + private static T CreateLazyInstanceInternal() + { + if (FindObjectOfType() is { } instance) + { + return instance; + } + + var gameObject = new GameObject {name = typeof(T).Name}; + return gameObject.AddComponent(); + } +} diff --git a/X10D.Unity/src/TransformExtensions.cs b/X10D.Unity/src/TransformExtensions.cs new file mode 100644 index 0000000..922ed5c --- /dev/null +++ b/X10D.Unity/src/TransformExtensions.cs @@ -0,0 +1,114 @@ +using UnityEngine; + +namespace X10D.Unity; + +/// +/// Extension methods for . +/// +public static class TransformExtensions +{ + /// + /// Rotates this transform so the forward vector points at another game object. + /// + /// The transform whose rotation will be changed. + /// The game object to look at. + /// + /// is . + /// -or- + /// is . + /// + public static void LookAt(this Transform transform, GameObject target) + { + if (transform == null) + { + throw new ArgumentNullException(nameof(transform)); + } + + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + transform.LookAt(target.transform); + } + + /// + /// Rotates this transform so the forward vector points at another game object. + /// + /// The transform whose rotation will be changed. + /// The game object to look at. + /// A vector specifying the upward direction. + /// + /// is . + /// -or- + /// is . + /// + public static void LookAt(this Transform transform, GameObject target, Vector3 worldUp) + { + if (transform == null) + { + throw new ArgumentNullException(nameof(transform)); + } + + if (target == null) + { + throw new ArgumentNullException(nameof(target)); + } + + transform.LookAt(target.transform, worldUp); + } + + /// + /// Sets the parent of this transform. + /// + /// The transform whose parent to change. + /// The new parent. + /// + /// is . + /// -or- + /// is . + /// + public static void SetParent(this Transform transform, GameObject parent) + { + if (transform == null) + { + throw new ArgumentNullException(nameof(transform)); + } + + if (parent == null) + { + throw new ArgumentNullException(nameof(parent)); + } + + transform.transform.SetParent(parent.transform); + } + + /// + /// Sets the parent of this transform. + /// + /// The transform whose parent to change. + /// The new parent. + /// + /// to modify the parent-relative position, scale and rotation such that the object keeps the same + /// world space position, rotation and scale as before; otherwise, . + /// + /// + /// is . + /// -or- + /// is . + /// + public static void SetParent(this Transform transform, GameObject parent, bool worldPositionStays) + { + if (transform == null) + { + throw new ArgumentNullException(nameof(transform)); + } + + if (parent == null) + { + throw new ArgumentNullException(nameof(parent)); + } + + transform.SetParent(parent.transform, worldPositionStays); + } +} diff --git a/X10D.sln b/X10D.sln index 067e80e..e6f0bcc 100644 --- a/X10D.sln +++ b/X10D.sln @@ -20,6 +20,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X10D.SourceValidator", "X10D.SourceValidator\X10D.SourceValidator.csproj", "{84750149-9068-4780-AFDE-CDA1AC57007D}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X10D.Unity", "X10D.Unity\X10D.Unity.csproj", "{7EAB3F09-A9FD-4334-B4DB-0394DD0C6568}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X10D.SourceGenerator", "X10D.SourceGenerator\X10D.SourceGenerator.csproj", "{077A5D33-AD55-4C55-8A67-972CEBC32C7A}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -38,6 +42,14 @@ Global {84750149-9068-4780-AFDE-CDA1AC57007D}.Debug|Any CPU.Build.0 = Debug|Any CPU {84750149-9068-4780-AFDE-CDA1AC57007D}.Release|Any CPU.ActiveCfg = Release|Any CPU {84750149-9068-4780-AFDE-CDA1AC57007D}.Release|Any CPU.Build.0 = Release|Any CPU + {7EAB3F09-A9FD-4334-B4DB-0394DD0C6568}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7EAB3F09-A9FD-4334-B4DB-0394DD0C6568}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7EAB3F09-A9FD-4334-B4DB-0394DD0C6568}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7EAB3F09-A9FD-4334-B4DB-0394DD0C6568}.Release|Any CPU.Build.0 = Release|Any CPU + {077A5D33-AD55-4C55-8A67-972CEBC32C7A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {077A5D33-AD55-4C55-8A67-972CEBC32C7A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {077A5D33-AD55-4C55-8A67-972CEBC32C7A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {077A5D33-AD55-4C55-8A67-972CEBC32C7A}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/X10D/X10D.csproj b/X10D/X10D.csproj index 565369e..346271b 100644 --- a/X10D/X10D.csproj +++ b/X10D/X10D.csproj @@ -1,7 +1,7 @@  - net6.0 + net6.0;netstandard2.1 10.0 true true @@ -15,7 +15,7 @@ dotnet extension-methods true - 3.0.0 + 3.1.0 enable true true @@ -78,4 +78,10 @@ + + + + \ No newline at end of file diff --git a/X10D/src/Collections/ArrayExtensions.cs b/X10D/src/Collections/ArrayExtensions.cs index 053d27d..816fabd 100644 --- a/X10D/src/Collections/ArrayExtensions.cs +++ b/X10D/src/Collections/ArrayExtensions.cs @@ -17,10 +17,14 @@ public static class ArrayExtensions [Pure] public static IReadOnlyCollection AsReadOnly(this T[] array) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(array); +#else if (array is null) { throw new ArgumentNullException(nameof(array)); } +#endif return Array.AsReadOnly(array); } @@ -45,10 +49,14 @@ public static class ArrayExtensions /// is . public static void Clear(this T?[] array, Range range) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(array); +#else if (array is null) { throw new ArgumentNullException(nameof(array)); } +#endif int index = range.Start.Value; int end = range.End.Value; @@ -77,10 +85,14 @@ public static class ArrayExtensions /// public static void Clear(this T?[] array, int index, int length) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(array); +#else if (array is null) { throw new ArgumentNullException(nameof(array)); } +#endif if (length == 0 || array.Length == 0) { diff --git a/X10D/src/Collections/BoolListExtensions.cs b/X10D/src/Collections/BoolListExtensions.cs index 365778a..ee70050 100644 --- a/X10D/src/Collections/BoolListExtensions.cs +++ b/X10D/src/Collections/BoolListExtensions.cs @@ -18,10 +18,14 @@ public static class BoolListExtensions [Pure] public static byte PackByte(this IReadOnlyList source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif if (source.Count > 8) { @@ -48,10 +52,14 @@ public static class BoolListExtensions [Pure] public static short PackInt16(this IReadOnlyList source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif if (source.Count > 16) { @@ -78,10 +86,14 @@ public static class BoolListExtensions [Pure] public static int PackInt32(this IReadOnlyList source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif if (source.Count > 32) { @@ -108,10 +120,14 @@ public static class BoolListExtensions [Pure] public static long PackInt64(this IReadOnlyList source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif if (source.Count > 64) { diff --git a/X10D/src/Collections/CollectionExtensions.cs b/X10D/src/Collections/CollectionExtensions.cs new file mode 100644 index 0000000..6bad398 --- /dev/null +++ b/X10D/src/Collections/CollectionExtensions.cs @@ -0,0 +1,77 @@ +namespace X10D.Collections; + +/// +/// Collection-related extension methods for . +/// +public static class CollectionExtensions +{ + /// + /// Calls on each item in the collection, then clears the collection by calling + /// . + /// + /// The collection to clear, and whose elements should be disposed. + /// The type of the elements in . + /// is . + /// is read-only. + /// + public static void ClearAndDisposeAll(this ICollection source) where T : IDisposable + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (source.IsReadOnly) + { + throw new InvalidOperationException("Collection is read-only. Try using DisposeAll instead."); + } + + foreach (T item in source) + { + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract + if (item is null) + { + continue; + } + + item.Dispose(); + } + + source.Clear(); + } + + /// + /// Asynchronously calls on each item in the collection, then clears the + /// collection by calling . + /// + /// The collection to clear, and whose elements should be disposed. + /// The type of the elements in . + /// is . + /// is read-only. + /// + public static async Task ClearAndDisposeAllAsync(this ICollection source) where T : IAsyncDisposable + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (source.IsReadOnly) + { + throw new InvalidOperationException("Collection is read-only. Try using DisposeAllAsync instead."); + } + + foreach (T item in source) + { + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract + if (item is null) + { + continue; + } + + await item.DisposeAsync(); + } + + source.Clear(); + } +} diff --git a/X10D/src/Collections/DictionaryExtensions.cs b/X10D/src/Collections/DictionaryExtensions.cs index fe0db27..86ae231 100644 --- a/X10D/src/Collections/DictionaryExtensions.cs +++ b/X10D/src/Collections/DictionaryExtensions.cs @@ -34,15 +34,22 @@ public static class DictionaryExtensions Func updateValueFactory) where TKey : notnull { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(dictionary); +#else if (dictionary is null) { throw new ArgumentNullException(nameof(dictionary)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(updateValueFactory); +#else if (updateValueFactory is null) { throw new ArgumentNullException(nameof(updateValueFactory)); } +#endif if (dictionary.ContainsKey(key)) { @@ -84,20 +91,30 @@ public static class DictionaryExtensions Func addValueFactory, Func updateValueFactory) where TKey : notnull { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(dictionary); +#else if (dictionary is null) { throw new ArgumentNullException(nameof(dictionary)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(addValueFactory); +#else if (addValueFactory is null) { throw new ArgumentNullException(nameof(addValueFactory)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(updateValueFactory); +#else if (updateValueFactory is null) { throw new ArgumentNullException(nameof(updateValueFactory)); } +#endif if (dictionary.ContainsKey(key)) { @@ -145,20 +162,30 @@ public static class DictionaryExtensions Func addValueFactory, Func updateValueFactory, TArg factoryArgument) where TKey : notnull { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(dictionary); +#else if (dictionary is null) { throw new ArgumentNullException(nameof(dictionary)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(addValueFactory); +#else if (addValueFactory is null) { throw new ArgumentNullException(nameof(addValueFactory)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(updateValueFactory); +#else if (updateValueFactory is null) { throw new ArgumentNullException(nameof(updateValueFactory)); } +#endif if (dictionary.ContainsKey(key)) { @@ -184,10 +211,14 @@ public static class DictionaryExtensions [Pure] public static string ToConnectionString(this IEnumerable> source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif static string SanitizeValue(string? value) { @@ -227,15 +258,22 @@ public static class DictionaryExtensions public static string ToConnectionString(this IEnumerable> source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(selector); +#else if (selector is null) { throw new ArgumentNullException(nameof(selector)); } +#endif static string SanitizeValue(string? value) { @@ -281,20 +319,30 @@ public static class DictionaryExtensions Func keySelector, Func valueSelector) where TKey : notnull { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(keySelector); +#else if (keySelector is null) { throw new ArgumentNullException(nameof(keySelector)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(valueSelector); +#else if (valueSelector is null) { throw new ArgumentNullException(nameof(valueSelector)); } +#endif static string SanitizeValue(string? value) { @@ -326,10 +374,14 @@ public static class DictionaryExtensions public static string ToGetParameters(this IEnumerable> source) where TKey : notnull { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif static string GetQueryParameter(KeyValuePair pair) { @@ -361,15 +413,22 @@ public static class DictionaryExtensions Func selector) where TKey : notnull { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(selector); +#else if (selector is null) { throw new ArgumentNullException(nameof(selector)); } +#endif // can't static here because of 'selector' parameter string GetQueryParameter(KeyValuePair pair) @@ -407,20 +466,30 @@ public static class DictionaryExtensions Func keySelector, Func valueSelector) where TKey : notnull { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(keySelector); +#else if (keySelector is null) { throw new ArgumentNullException(nameof(keySelector)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(valueSelector); +#else if (valueSelector is null) { throw new ArgumentNullException(nameof(valueSelector)); } +#endif // can't static here because of selector parameters string GetQueryParameter(KeyValuePair pair) diff --git a/X10D/src/Collections/EnumerableExtensions.cs b/X10D/src/Collections/EnumerableExtensions.cs index baa8d19..4a75370 100644 --- a/X10D/src/Collections/EnumerableExtensions.cs +++ b/X10D/src/Collections/EnumerableExtensions.cs @@ -7,15 +7,147 @@ namespace X10D.Collections; /// public static class EnumerableExtensions { + /// + /// Performs the specified action on each element of the . + /// + /// + /// The whose elements on which to perform . + /// + /// + /// The delegate to perform on each element of the . The + /// argument passed to this delegate represents the index. + /// + /// The type of the elements in . + /// + /// is . + /// -or- + /// is . + /// + public static void For(this IEnumerable source, Action action) + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (action is null) + { + throw new ArgumentNullException(nameof(action)); + } + + var index = 0; + foreach (T item in source) + { + action(index++, item); + } + } + + /// + /// Performs the specified action on each element of the . + /// + /// + /// The whose elements on which to perform . + /// + /// + /// The delegate to perform on each element of the . + /// + /// The type of the elements in . + /// + /// is . + /// -or- + /// is . + /// + public static void ForEach(this IEnumerable source, Action action) + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + if (action is null) + { + throw new ArgumentNullException(nameof(action)); + } + + foreach (T item in source) + { + action(item); + } + } + + /// + /// Calls on all elements of the . + /// + /// The enumerable collection whose elements to dispose. + /// The type of the elements in . + /// is . + /// + public static void DisposeAll(this IEnumerable source) where T : IDisposable + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + foreach (T item in source) + { + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract + if (item is null) + { + continue; + } + + item.Dispose(); + } + } + + /// + /// Asynchronously calls on all elements of the + /// . + /// + /// The enumerable collection whose elements to dispose. + /// The type of the elements in . + /// is . + /// + public static async Task DisposeAllAsync(this IEnumerable source) where T : IAsyncDisposable + { + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } + + foreach (T item in source) + { + // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract + if (item is null) + { + continue; + } + + await item.DisposeAsync(); + } + } + /// /// Reorganizes the elements in an enumerable by implementing a Fisher-Yates shuffle, and returns th shuffled result. /// /// The element type. /// The to shuffle. /// Optional. The instance to use for the shuffling. + /// The shuffled collection. + /// is . [Pure] public static IReadOnlyCollection Shuffled(this IEnumerable source, Random? random = null) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + var list = new List(source); list.Shuffle(random); return list.AsReadOnly(); diff --git a/X10D/src/Collections/ListExtensions.cs b/X10D/src/Collections/ListExtensions.cs index d943395..bb0b601 100644 --- a/X10D/src/Collections/ListExtensions.cs +++ b/X10D/src/Collections/ListExtensions.cs @@ -17,10 +17,14 @@ public static class ListExtensions /// is . public static void Fill(this IList source, T value) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif for (var i = 0; i < source.Count; i++) { @@ -47,10 +51,14 @@ public static class ListExtensions /// public static void Fill(this IList source, T value, int startIndex, int count) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif if (startIndex < 0) { @@ -84,8 +92,8 @@ public static class ListExtensions /// The element type. /// The source collection from which to draw. /// - /// The instance to use for the shuffling. If is specified, - /// is used. + /// The instance to use for the shuffling. If is specified, a shared + /// instance is used. /// /// A random element of type from . /// is . @@ -98,12 +106,16 @@ public static class ListExtensions [Pure] public static T Random(this IReadOnlyList source, Random? random = null) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif - random ??= System.Random.Shared; + random ??= RandomExtensions.GetShared(); return random.NextFrom(source); } @@ -113,18 +125,22 @@ public static class ListExtensions /// The element type. /// The to shuffle. /// - /// The instance to use for the shuffling. If is specified, - /// is used. + /// The instance to use for the shuffling. If is specified, a shared + /// instance is used. /// /// is . public static void Shuffle(this IList source, Random? random = null) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif - random ??= System.Random.Shared; + random ??= RandomExtensions.GetShared(); int count = source.Count; while (count > 0) diff --git a/X10D/src/Core/EnumExtensions.cs b/X10D/src/Core/EnumExtensions.cs index fbba9b4..29b7649 100644 --- a/X10D/src/Core/EnumExtensions.cs +++ b/X10D/src/Core/EnumExtensions.cs @@ -20,7 +20,11 @@ public static class EnumExtensions public static T Next(this T value) where T : struct, Enum { +#if NET5_0_OR_GREATER T[] values = Enum.GetValues(); +#else + T[] values = Enum.GetValues(typeof(T)).Cast().ToArray(); +#endif int index = Array.IndexOf(values, value) + 1; index %= values.Length; return values[index]; @@ -40,7 +44,11 @@ public static class EnumExtensions public static T NextUnchecked(this T value) where T : struct, Enum { +#if NET5_0_OR_GREATER T[] values = Enum.GetValues(); +#else + T[] values = Enum.GetValues(typeof(T)).Cast().ToArray(); +#endif int index = Array.IndexOf(values, value) + 1; return values[index]; } @@ -58,7 +66,11 @@ public static class EnumExtensions public static T Previous(this T value) where T : struct, Enum { +#if NET5_0_OR_GREATER T[] values = Enum.GetValues(); +#else + T[] values = Enum.GetValues(typeof(T)).Cast().ToArray(); +#endif int index = Array.IndexOf(values, value) - 1; int length = values.Length; @@ -82,7 +94,11 @@ public static class EnumExtensions public static T PreviousUnchecked(this T value) where T : struct, Enum { +#if NET5_0_OR_GREATER T[] values = Enum.GetValues(); +#else + T[] values = Enum.GetValues(typeof(T)).Cast().ToArray(); +#endif int index = Array.IndexOf(values, value) - 1; return values[index]; } diff --git a/X10D/src/Core/Extensions.cs b/X10D/src/Core/Extensions.cs index 21348d6..8817ca0 100644 --- a/X10D/src/Core/Extensions.cs +++ b/X10D/src/Core/Extensions.cs @@ -16,7 +16,7 @@ public static class Extensions /// An array of type with length 1, whose only element is . /// [Pure] - public static T?[] AsArrayValue(this T? value) + public static T[] AsArrayValue(this T value) { return new[] {value}; } @@ -30,7 +30,7 @@ public static class Extensions /// An enumerable collection of type , whose only element is . /// [Pure] - public static IEnumerable AsEnumerableValue(this T? value) + public static IEnumerable AsEnumerableValue(this T value) { yield return value; } diff --git a/X10D/src/Core/RandomExtensions.cs b/X10D/src/Core/RandomExtensions.cs index a2c4ac9..a111704 100644 --- a/X10D/src/Core/RandomExtensions.cs +++ b/X10D/src/Core/RandomExtensions.cs @@ -9,6 +9,8 @@ namespace X10D.Core; /// public static class RandomExtensions { + private static readonly Random Shared = new(); + /// /// Returns a random value that defined in a specified enum. /// @@ -21,10 +23,14 @@ public static class RandomExtensions public static T Next(this Random random) where T : struct, Enum { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif var values = Enum.GetValues(typeof(T)); return (T)values.GetValue(random.Next(values.Length))!; @@ -44,10 +50,14 @@ public static class RandomExtensions /// is . public static bool NextBoolean(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif return random.NextDouble() >= 0.5; } @@ -67,10 +77,14 @@ public static class RandomExtensions /// is less than 0. public static double NextDouble(this Random random, double maxValue) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif if (maxValue < 0) { @@ -99,10 +113,14 @@ public static class RandomExtensions /// public static double NextDouble(this Random random, double minValue, double maxValue) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif if (maxValue < minValue) { @@ -133,15 +151,22 @@ public static class RandomExtensions /// public static T NextFrom(this Random random, IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif if (source is T[] array) { @@ -166,10 +191,14 @@ public static class RandomExtensions /// is . public static byte NextByte(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif return random.NextByte(byte.MaxValue); } @@ -190,10 +219,14 @@ public static class RandomExtensions /// is . public static byte NextByte(this Random random, byte maxValue) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif return random.NextByte(0, maxValue); } @@ -219,10 +252,14 @@ public static class RandomExtensions /// public static byte NextByte(this Random random, byte minValue, byte maxValue) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif return (byte)random.Next(minValue, maxValue); } @@ -237,10 +274,14 @@ public static class RandomExtensions /// is . public static short NextInt16(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif return random.NextInt16(short.MaxValue); } @@ -262,10 +303,14 @@ public static class RandomExtensions /// is less than 0. public static short NextInt16(this Random random, short maxValue) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif if (maxValue < 0) { @@ -295,14 +340,36 @@ public static class RandomExtensions /// /// is . public static short NextInt16(this Random random, short minValue, short maxValue) + { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else + if (random is null) + { + throw new ArgumentNullException(nameof(random)); + } +#endif + + return (short)random.Next(minValue, maxValue); + } + +#if !NET6_0_OR_GREATER + /// + /// Returns a random floating-point number that is greater than or equal to 0.0, and less than 1.0. + /// + /// The instance. + /// A single-precision floating point number that is greater than or equal to 0.0, and less than 1.0. + /// is . + public static float NextSingle(this Random random) { if (random is null) { throw new ArgumentNullException(nameof(random)); } - return (short)random.Next(minValue, maxValue); + return (float)random.NextDouble(); } +#endif /// /// Returns a non-negative random single-precision floating point number that is less than the specified maximum. @@ -319,10 +386,14 @@ public static class RandomExtensions /// is less than 0. public static float NextSingle(this Random random, float maxValue) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif if (maxValue < 0) { @@ -351,10 +422,14 @@ public static class RandomExtensions /// public static float NextSingle(this Random random, float minValue, float maxValue) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif if (maxValue < minValue) { @@ -382,15 +457,22 @@ public static class RandomExtensions /// is less than 0. public static string NextString(this Random random, IReadOnlyList source, int length) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif if (length < 0) { @@ -415,4 +497,13 @@ public static class RandomExtensions return builder.ToString(); } + + internal static Random GetShared() + { +#if NET6_0_OR_GREATER + return Random.Shared; +#else + return Shared; +#endif + } } diff --git a/X10D/src/Drawing/ColorExtensions.cs b/X10D/src/Drawing/ColorExtensions.cs new file mode 100644 index 0000000..e21cf9e --- /dev/null +++ b/X10D/src/Drawing/ColorExtensions.cs @@ -0,0 +1,115 @@ +using System.Diagnostics.Contracts; +using System.Drawing; +using System.Runtime.CompilerServices; + +namespace X10D.Drawing; + +/// +/// Drawing-related extensions for . +/// +public static class ColorExtensions +{ + /// + /// Returns a new with the red, green, and blue components inverted. Alpha is not affected. + /// + /// The color to invert. + /// The inverted color. + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Color Inverted(this Color color) + { + return Color.FromArgb(color.A, 255 - color.R, 255 - color.G, 255 - color.B); + } + + /// + /// Returns a vector whose red, green, and blue components are the same as the specified color, and whose alpha component + /// is a new value. + /// + /// The color to copy. + /// The new alpha component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Color WithA(this Color color, int a) + { + return Color.FromArgb(a, color.R, color.G, color.B); + } + + /// + /// Returns a vector whose red, green, and alpha components are the same as the specified color, and whose blue component + /// is a new value. + /// + /// The color to copy. + /// The new blue component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Color WithB(this Color color, int b) + { + return Color.FromArgb(color.A, color.R, color.G, b); + } + + /// + /// Returns a vector whose red, blue, and alpha components are the same as the specified color, and whose green component + /// is a new value. + /// + /// The color to copy. + /// The new green component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Color WithG(this Color color, int g) + { + return Color.FromArgb(color.A, color.R, g, color.B); + } + + /// + /// Returns a vector whose green, blue, and alpha components are the same as the specified color, and whose red component + /// is a new value. + /// + /// The color to copy. + /// The new red component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Color WithR(this Color color, int r) + { + return Color.FromArgb(color.A, r, color.G, color.B); + } +} diff --git a/X10D/src/Drawing/RandomExtensions.cs b/X10D/src/Drawing/RandomExtensions.cs index 32cf1e8..edfecd3 100644 --- a/X10D/src/Drawing/RandomExtensions.cs +++ b/X10D/src/Drawing/RandomExtensions.cs @@ -15,10 +15,14 @@ public static class RandomExtensions /// is . public static Color NextColorRgb(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif int rgb = random.Next(); return Color.FromArgb(0xFF, (byte)(rgb >> 16 & 0xFF), (byte)(rgb >> 8 & 0xFF), (byte)(rgb & 0xFF)); @@ -32,10 +36,14 @@ public static class RandomExtensions /// is . public static Color NextColorArgb(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif int argb = random.Next(); return Color.FromArgb(argb); diff --git a/X10D/src/IO/DoubleExtensions.cs b/X10D/src/IO/DoubleExtensions.cs index b33df1e..a981d23 100644 --- a/X10D/src/IO/DoubleExtensions.cs +++ b/X10D/src/IO/DoubleExtensions.cs @@ -1,5 +1,6 @@ using System.Buffers.Binary; using System.Diagnostics.Contracts; +using System.Runtime.InteropServices; namespace X10D.IO; @@ -55,8 +56,12 @@ public static class DoubleExtensions /// if the conversion was successful; otherwise, . public static bool TryWriteBytes(this double value, Span destination, Endianness endianness) { - return endianness == Endianness.BigEndian - ? BinaryPrimitives.TryWriteDoubleBigEndian(destination, value) - : BinaryPrimitives.TryWriteDoubleLittleEndian(destination, value); + if (BitConverter.IsLittleEndian == (endianness == Endianness.BigEndian)) + { + long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value)); + value = BitConverter.Int64BitsToDouble(tmp); + } + + return MemoryMarshal.TryWrite(destination, ref value); } } diff --git a/X10D/src/IO/FileInfoExtensions.cs b/X10D/src/IO/FileInfoExtensions.cs index 272c99a..a0878bc 100644 --- a/X10D/src/IO/FileInfoExtensions.cs +++ b/X10D/src/IO/FileInfoExtensions.cs @@ -16,7 +16,7 @@ public static class FileInfoExtensions /// The type of the whose is to be used for /// computing the hash. /// - /// The hash of represented as an array of bytes. + /// The hash of represented as an array of bytes. /// is . /// The specified file was not found. /// The opened file stream cannot be read. @@ -29,10 +29,14 @@ public static class FileInfoExtensions public static byte[] GetHash(this FileInfo value) where T : HashAlgorithm { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif using FileStream stream = value.OpenRead(); return stream.GetHash(); @@ -65,10 +69,14 @@ public static class FileInfoExtensions public static bool TryWriteHash(this FileInfo value, Span destination, out int bytesWritten) where T : HashAlgorithm { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif using FileStream stream = value.OpenRead(); return stream.TryWriteHash(destination, out bytesWritten); diff --git a/X10D/src/IO/ListOfByteExtensions.cs b/X10D/src/IO/ListOfByteExtensions.cs index dbec6e1..d9fd480 100644 --- a/X10D/src/IO/ListOfByteExtensions.cs +++ b/X10D/src/IO/ListOfByteExtensions.cs @@ -19,10 +19,14 @@ public static class ListOfByteExtensions /// is . public static string AsString(this IReadOnlyList source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToString(source.ToArray()); } @@ -50,10 +54,14 @@ public static class ListOfByteExtensions /// is . public static double ToDouble(this IReadOnlyList source, int startIndex) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToDouble(source.ToArray(), startIndex); } @@ -78,10 +86,14 @@ public static class ListOfByteExtensions /// is . public static short ToInt16(this IReadOnlyList source, int startIndex) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToInt16(source.ToArray(), startIndex); } @@ -106,10 +118,14 @@ public static class ListOfByteExtensions /// is . public static int ToInt32(this IReadOnlyList source, int startIndex) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToInt32(source.ToArray(), startIndex); } @@ -134,10 +150,14 @@ public static class ListOfByteExtensions /// is . public static long ToInt64(this IReadOnlyList source, int startIndex) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToInt64(source.ToArray(), startIndex); } @@ -164,10 +184,14 @@ public static class ListOfByteExtensions /// is . public static float ToSingle(this IReadOnlyList source, int startIndex) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToSingle(source.ToArray(), startIndex); } @@ -185,15 +209,22 @@ public static class ListOfByteExtensions /// public static string ToString(this IReadOnlyList source, Encoding encoding) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(encoding); +#else if (encoding is null) { throw new ArgumentNullException(nameof(encoding)); } +#endif return encoding.GetString(source.ToArray()); } @@ -220,10 +251,14 @@ public static class ListOfByteExtensions [CLSCompliant(false)] public static ushort ToUInt16(this IReadOnlyList source, int startIndex) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToUInt16(source.ToArray(), startIndex); } @@ -250,10 +285,14 @@ public static class ListOfByteExtensions [CLSCompliant(false)] public static uint ToUInt32(this IReadOnlyList source, int startIndex) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToUInt32(source.ToArray(), startIndex); } @@ -280,10 +319,14 @@ public static class ListOfByteExtensions [CLSCompliant(false)] public static ulong ToUInt64(this IReadOnlyList source, int startIndex) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif return BitConverter.ToUInt64(source.ToArray(), startIndex); } diff --git a/X10D/src/IO/SingleExtensions.cs b/X10D/src/IO/SingleExtensions.cs index ea9ae4b..5db19f5 100644 --- a/X10D/src/IO/SingleExtensions.cs +++ b/X10D/src/IO/SingleExtensions.cs @@ -1,5 +1,6 @@ using System.Buffers.Binary; using System.Diagnostics.Contracts; +using System.Runtime.InteropServices; namespace X10D.IO; @@ -55,8 +56,12 @@ public static class SingleExtensions /// if the conversion was successful; otherwise, . public static bool TryWriteBytes(this float value, Span destination, Endianness endianness) { - return endianness == Endianness.BigEndian - ? BinaryPrimitives.TryWriteSingleBigEndian(destination, value) - : BinaryPrimitives.TryWriteSingleLittleEndian(destination, value); + if (BitConverter.IsLittleEndian == (endianness == Endianness.BigEndian)) + { + int tmp = BinaryPrimitives.ReverseEndianness(BitConverter.SingleToInt32Bits(value)); + value = BitConverter.Int32BitsToSingle(tmp); + } + + return MemoryMarshal.TryWrite(destination, ref value); } } diff --git a/X10D/src/IO/StreamExtensions.cs b/X10D/src/IO/StreamExtensions.cs index ab353de..edabeec 100644 --- a/X10D/src/IO/StreamExtensions.cs +++ b/X10D/src/IO/StreamExtensions.cs @@ -1,5 +1,6 @@ using System.Buffers.Binary; using System.Reflection; +using System.Runtime.InteropServices; using System.Security.Cryptography; namespace X10D.IO; @@ -31,10 +32,14 @@ public static class StreamExtensions public static byte[] GetHash(this Stream stream) where T : HashAlgorithm { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif if (!stream.CanRead) { @@ -81,15 +86,26 @@ public static class StreamExtensions /// A decimal value read from the stream. public static decimal ReadDecimal(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif const int decimalSize = sizeof(decimal); const int int32Size = sizeof(int); @@ -129,22 +145,39 @@ public static class StreamExtensions /// A double-precision floating point value read from the stream. public static double ReadDouble(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(double)]; stream.Read(buffer); - return endianness == Endianness.LittleEndian - ? BinaryPrimitives.ReadDoubleLittleEndian(buffer) - : BinaryPrimitives.ReadDoubleBigEndian(buffer); + var value = MemoryMarshal.Read(buffer); + + if (BitConverter.IsLittleEndian == (endianness == Endianness.BigEndian)) + { + long tmp = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value)); + value = BitConverter.Int64BitsToDouble(tmp); + } + + return value; } /// @@ -167,15 +200,26 @@ public static class StreamExtensions /// An two-byte unsigned integer read from the stream. public static short ReadInt16(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(short)]; stream.Read(buffer); @@ -205,15 +249,26 @@ public static class StreamExtensions /// An four-byte unsigned integer read from the stream. public static int ReadInt32(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(int)]; stream.Read(buffer); @@ -243,15 +298,26 @@ public static class StreamExtensions /// An eight-byte unsigned integer read from the stream. public static long ReadInt64(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(long)]; stream.Read(buffer); @@ -281,22 +347,39 @@ public static class StreamExtensions /// A single-precision floating point value read from the stream. public static double ReadSingle(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(float)]; stream.Read(buffer); - return endianness == Endianness.LittleEndian - ? BinaryPrimitives.ReadSingleLittleEndian(buffer) - : BinaryPrimitives.ReadSingleBigEndian(buffer); + var value = MemoryMarshal.Read(buffer); + + if (BitConverter.IsLittleEndian == (endianness == Endianness.BigEndian)) + { + int tmp = BinaryPrimitives.ReverseEndianness(BitConverter.SingleToInt32Bits(value)); + value = BitConverter.Int32BitsToSingle(tmp); + } + + return value; } /// @@ -321,15 +404,26 @@ public static class StreamExtensions [CLSCompliant(false)] public static ushort ReadUInt16(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(ushort)]; stream.Read(buffer); @@ -361,15 +455,26 @@ public static class StreamExtensions [CLSCompliant(false)] public static uint ReadUInt32(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(uint)]; stream.Read(buffer); @@ -401,15 +506,26 @@ public static class StreamExtensions [CLSCompliant(false)] public static ulong ReadUInt64(this Stream stream, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(ulong)]; stream.Read(buffer); @@ -445,10 +561,14 @@ public static class StreamExtensions public static bool TryWriteHash(this Stream stream, Span destination, out int bytesWritten) where T : HashAlgorithm { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif if (!stream.CanRead) { @@ -504,15 +624,26 @@ public static class StreamExtensions /// The number of bytes written to the stream. public static int Write(this Stream stream, short value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(short)]; @@ -548,17 +679,29 @@ public static class StreamExtensions /// The four-byte signed integer to write. /// The endian encoding to use. /// The number of bytes written to the stream. + /// is . public static int Write(this Stream stream, int value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(int)]; @@ -581,6 +724,7 @@ public static class StreamExtensions /// The stream to which the value should be written. /// The eight-byte signed integer to write. /// The number of bytes written to the stream. + /// is . public static int Write(this Stream stream, long value) { return stream.Write(value, DefaultEndianness); @@ -594,17 +738,29 @@ public static class StreamExtensions /// The eight-byte signed integer to write. /// The endian encoding to use. /// The number of bytes written to the stream. + /// is . public static int Write(this Stream stream, long value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(long)]; @@ -627,6 +783,7 @@ public static class StreamExtensions /// The stream to which the value should be written. /// The two-byte unsigned integer to write. /// The number of bytes written to the stream. + /// is . [CLSCompliant(false)] public static int Write(this Stream stream, ushort value) { @@ -641,18 +798,30 @@ public static class StreamExtensions /// The two-byte unsigned integer to write. /// The endian encoding to use. /// The number of bytes written to the stream. + /// is . [CLSCompliant(false)] public static int Write(this Stream stream, ushort value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(ushort)]; @@ -675,6 +844,7 @@ public static class StreamExtensions /// The stream to which the value should be written. /// The four-byte unsigned integer to write. /// The number of bytes written to the stream. + /// is . [CLSCompliant(false)] public static int Write(this Stream stream, uint value) { @@ -689,18 +859,30 @@ public static class StreamExtensions /// The four-byte unsigned integer to write. /// The endian encoding to use. /// The number of bytes written to the stream. + /// is . [CLSCompliant(false)] public static int Write(this Stream stream, uint value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(uint)]; @@ -723,6 +905,7 @@ public static class StreamExtensions /// The stream to which the value should be written. /// The eight-byte unsigned integer to write. /// The number of bytes written to the stream. + /// is . [CLSCompliant(false)] public static int Write(this Stream stream, ulong value) { @@ -737,18 +920,30 @@ public static class StreamExtensions /// The eight-byte signed integer to write. /// The endian encoding to use. /// The number of bytes written to the stream. + /// is . [CLSCompliant(false)] public static int Write(this Stream stream, ulong value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(ulong)]; @@ -772,27 +967,57 @@ public static class StreamExtensions /// The single-precision floating point value to write. /// The endian encoding to use. /// The number of bytes written to the stream. + /// is . public static int Write(this Stream stream, float value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(float)]; if (endianness == Endianness.LittleEndian) { +#if NET5_0_OR_GREATER BinaryPrimitives.WriteSingleLittleEndian(buffer, value); +#else + if (BitConverter.IsLittleEndian) + { + value = BinaryPrimitives.ReverseEndianness(BitConverter.SingleToInt32Bits(value)); + } + + System.Runtime.InteropServices.MemoryMarshal.Write(buffer, ref value); +#endif } else { +#if NET5_0_OR_GREATER BinaryPrimitives.WriteSingleBigEndian(buffer, value); +#else + if (BitConverter.IsLittleEndian) + { + value = BinaryPrimitives.ReverseEndianness(BitConverter.SingleToInt32Bits(value)); + } + + System.Runtime.InteropServices.MemoryMarshal.Write(buffer, ref value); +#endif } return stream.WriteInternal(buffer); @@ -806,27 +1031,57 @@ public static class StreamExtensions /// The double-precision floating point value to write. /// The endian encoding to use. /// The number of bytes written to the stream. + /// is . public static int Write(this Stream stream, double value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif Span buffer = stackalloc byte[sizeof(double)]; if (endianness == Endianness.LittleEndian) { +#if NET5_0_OR_GREATER BinaryPrimitives.WriteDoubleLittleEndian(buffer, value); +#else + if (BitConverter.IsLittleEndian) + { + value = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value)); + } + + System.Runtime.InteropServices.MemoryMarshal.Write(buffer, ref value); +#endif } else { +#if NET5_0_OR_GREATER BinaryPrimitives.WriteDoubleBigEndian(buffer, value); +#else + if (BitConverter.IsLittleEndian) + { + value = BinaryPrimitives.ReverseEndianness(BitConverter.DoubleToInt64Bits(value)); + } + + System.Runtime.InteropServices.MemoryMarshal.Write(buffer, ref value); +#endif } return stream.WriteInternal(buffer); @@ -840,17 +1095,29 @@ public static class StreamExtensions /// The decimal value to write. /// The endian encoding to use. /// The number of bytes written to the stream. + /// is . public static int Write(this Stream stream, decimal value, Endianness endianness) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(stream); +#else if (stream is null) { throw new ArgumentNullException(nameof(stream)); } +#endif +#if NET5_0_OR_GREATER if (!Enum.IsDefined(endianness)) { throw new ArgumentOutOfRangeException(nameof(endianness)); } +#else + if (!Enum.IsDefined(typeof(Endianness), endianness)) + { + throw new ArgumentOutOfRangeException(nameof(endianness)); + } +#endif int[] bits = decimal.GetBits(value); long preWritePosition = stream.Position; diff --git a/X10D/src/Linq/ByteExtensions.cs b/X10D/src/Linq/ByteExtensions.cs index ee049ff..3d7524d 100644 --- a/X10D/src/Linq/ByteExtensions.cs +++ b/X10D/src/Linq/ByteExtensions.cs @@ -12,8 +12,18 @@ public static class ByteExtensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . public static byte Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate((byte)1, (current, value) => (byte)(current * value)); } @@ -22,9 +32,19 @@ public static class ByteExtensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . [CLSCompliant(false)] public static sbyte Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate((sbyte)1, (current, value) => (sbyte)(current * value)); } @@ -36,8 +56,18 @@ public static class ByteExtensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . public static byte Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } @@ -49,9 +79,19 @@ public static class ByteExtensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . [CLSCompliant(false)] public static sbyte Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } diff --git a/X10D/src/Linq/DecimalExtensions.cs b/X10D/src/Linq/DecimalExtensions.cs index bcdf193..01dde51 100644 --- a/X10D/src/Linq/DecimalExtensions.cs +++ b/X10D/src/Linq/DecimalExtensions.cs @@ -10,8 +10,18 @@ public static class DecimalExtensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . public static decimal Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate(1m, (current, value) => (current * value)); } @@ -23,8 +33,18 @@ public static class DecimalExtensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . public static decimal Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } } diff --git a/X10D/src/Linq/DoubleExtensions.cs b/X10D/src/Linq/DoubleExtensions.cs index 70ac1ca..afb38ae 100644 --- a/X10D/src/Linq/DoubleExtensions.cs +++ b/X10D/src/Linq/DoubleExtensions.cs @@ -10,8 +10,18 @@ public static class DoubleExtensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . public static double Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate(1.0, (current, value) => (current * value)); } @@ -23,8 +33,18 @@ public static class DoubleExtensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . public static double Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } } diff --git a/X10D/src/Linq/Int32Extensions.cs b/X10D/src/Linq/Int32Extensions.cs index 923470e..871e422 100644 --- a/X10D/src/Linq/Int32Extensions.cs +++ b/X10D/src/Linq/Int32Extensions.cs @@ -12,8 +12,18 @@ public static class Int32Extensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . public static int Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate(1, (current, value) => current * value); } @@ -22,9 +32,19 @@ public static class Int32Extensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . [CLSCompliant(false)] public static uint Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate(1u, (current, value) => current * value); } @@ -36,8 +56,18 @@ public static class Int32Extensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . public static int Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } @@ -49,9 +79,19 @@ public static class Int32Extensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . [CLSCompliant(false)] public static uint Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } diff --git a/X10D/src/Linq/Int64Extensions.cs b/X10D/src/Linq/Int64Extensions.cs index 4870456..07b9802 100644 --- a/X10D/src/Linq/Int64Extensions.cs +++ b/X10D/src/Linq/Int64Extensions.cs @@ -12,8 +12,18 @@ public static class Int64Extensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . public static long Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate(1L, (current, value) => current * value); } @@ -22,9 +32,19 @@ public static class Int64Extensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . [CLSCompliant(false)] public static ulong Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate(1UL, (current, value) => current * value); } @@ -36,8 +56,18 @@ public static class Int64Extensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . public static long Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } @@ -49,9 +79,19 @@ public static class Int64Extensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . [CLSCompliant(false)] public static ulong Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } diff --git a/X10D/src/Linq/ReadOnlySpanExtensions.cs b/X10D/src/Linq/ReadOnlySpanExtensions.cs index 3bbbfca..bf0d1d3 100644 --- a/X10D/src/Linq/ReadOnlySpanExtensions.cs +++ b/X10D/src/Linq/ReadOnlySpanExtensions.cs @@ -21,10 +21,14 @@ public static class ReadOnlySpanExtensions [Pure] public static bool All(this ReadOnlySpan source, Predicate predicate) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(predicate); +#else if (predicate is null) { throw new ArgumentNullException(nameof(predicate)); } +#endif if (source.IsEmpty) { @@ -56,10 +60,14 @@ public static class ReadOnlySpanExtensions [Pure] public static bool Any(this ReadOnlySpan source, Predicate predicate) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(predicate); +#else if (predicate is null) { throw new ArgumentNullException(nameof(predicate)); } +#endif if (source.IsEmpty) { @@ -76,4 +84,43 @@ public static class ReadOnlySpanExtensions return false; } + + /// + /// Returns a number that represents how many elements in the specified sequence satisfy a condition. + /// + /// A that contains elements to be tested and counted. + /// A function to test each element for a condition. + /// The type of the elements in . + /// + /// A number that represents how many elements in the sequence satisfy the condition in the predicate function. + /// + /// is . + public static int Count(this ReadOnlySpan source, Predicate predicate) + { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(predicate); +#else + if (predicate is null) + { + throw new ArgumentNullException(nameof(predicate)); + } +#endif + + if (source.IsEmpty) + { + return 0; + } + + var count = 0; + + foreach (TSource item in source) + { + if (predicate(item)) + { + count++; + } + } + + return count; + } } diff --git a/X10D/src/Linq/SingleExtensions.cs b/X10D/src/Linq/SingleExtensions.cs index 1797eaf..9d48203 100644 --- a/X10D/src/Linq/SingleExtensions.cs +++ b/X10D/src/Linq/SingleExtensions.cs @@ -10,8 +10,18 @@ public static class SingleExtensions /// /// A sequence of values that are used to calculate the product. /// The product the values in the sequence. + /// is . public static float Product(this IEnumerable source) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Aggregate(1f, (current, value) => (current * value)); } @@ -23,8 +33,18 @@ public static class SingleExtensions /// A transform function to apply to each element. /// The type of the elements of . /// The product of the projected values. + /// is . public static float Product(this IEnumerable source, Func selector) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else + if (source is null) + { + throw new ArgumentNullException(nameof(source)); + } +#endif + return source.Select(selector).Product(); } } diff --git a/X10D/src/Linq/SpanExtensions.cs b/X10D/src/Linq/SpanExtensions.cs index 6de52f3..ce2e3f3 100644 --- a/X10D/src/Linq/SpanExtensions.cs +++ b/X10D/src/Linq/SpanExtensions.cs @@ -21,10 +21,14 @@ public static class SpanExtensions [Pure] public static bool All(this Span source, Predicate predicate) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(predicate); +#else if (predicate is null) { throw new ArgumentNullException(nameof(predicate)); } +#endif if (source.IsEmpty) { @@ -56,10 +60,14 @@ public static class SpanExtensions [Pure] public static bool Any(this Span source, Predicate predicate) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(predicate); +#else if (predicate is null) { throw new ArgumentNullException(nameof(predicate)); } +#endif if (source.IsEmpty) { @@ -76,4 +84,43 @@ public static class SpanExtensions return false; } + + /// + /// Returns a number that represents how many elements in the specified sequence satisfy a condition. + /// + /// A that contains elements to be tested and counted. + /// A function to test each element for a condition. + /// The type of the elements in . + /// + /// A number that represents how many elements in the sequence satisfy the condition in the predicate function. + /// + /// is . + public static int Count(this Span source, Predicate predicate) + { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(predicate); +#else + if (predicate is null) + { + throw new ArgumentNullException(nameof(predicate)); + } +#endif + + if (source.IsEmpty) + { + return 0; + } + + var count = 0; + + foreach (TSource item in source) + { + if (predicate(item)) + { + count++; + } + } + + return count; + } } diff --git a/X10D/src/Math/ByteExtensions.cs b/X10D/src/Math/ByteExtensions.cs index 8e25088..310c4e4 100644 --- a/X10D/src/Math/ByteExtensions.cs +++ b/X10D/src/Math/ByteExtensions.cs @@ -19,7 +19,11 @@ public static class ByteExtensions /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static byte DigitalRoot(this byte value) { int root = value % 9; @@ -32,7 +36,11 @@ public static class ByteExtensions /// The value whose factorial to compute. /// The factorial of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long Factorial(this byte value) { if (value == 0) @@ -58,7 +66,11 @@ public static class ByteExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this byte value) { return value % 2 == 0; @@ -73,7 +85,11 @@ public static class ByteExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this byte value) { return !value.IsEven(); @@ -101,7 +117,11 @@ public static class ByteExtensions /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int MultiplicativePersistence(this byte value) { return ((long)value).MultiplicativePersistence(); diff --git a/X10D/src/Math/ComparableExtensions.cs b/X10D/src/Math/ComparableExtensions.cs index 53bbc0e..06cd86a 100644 --- a/X10D/src/Math/ComparableExtensions.cs +++ b/X10D/src/Math/ComparableExtensions.cs @@ -46,18 +46,27 @@ public static class ComparableExtensions /// // True /// /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool Between(this T1 value, T2 lower, T3 upper, InclusiveOptions inclusiveOptions = InclusiveOptions.None) where T1 : IComparable, IComparable where T2 : IComparable where T3 : IComparable { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif if (lower.GreaterThan(upper)) { @@ -102,11 +111,25 @@ public static class ComparableExtensions /// // clamped will be 20 /// /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static T Clamp(this T value, T lower, T upper) where T : IComparable { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } +#endif + if (lower.GreaterThan(upper)) { throw new ArgumentException( @@ -138,15 +161,24 @@ public static class ComparableExtensions /// // result will be False /// /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool GreaterThan(this T1 value, T2 other) where T1 : IComparable { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif return value.CompareTo(other) > 0; } @@ -172,15 +204,24 @@ public static class ComparableExtensions /// // result will be False /// /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool GreaterThanOrEqualTo(this T1 value, T2 other) where T1 : IComparable { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif return value.CompareTo(other) >= 0; } @@ -206,15 +247,24 @@ public static class ComparableExtensions /// // result will be True /// /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool LessThan(this T1 value, T2 other) where T1 : IComparable { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif return value.CompareTo(other) < 0; } @@ -240,15 +290,24 @@ public static class ComparableExtensions /// // result will be True /// /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool LessThanOrEqualTo(this T1 value, T2 other) where T1 : IComparable { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif return value.CompareTo(other) <= 0; } @@ -273,15 +332,24 @@ public static class ComparableExtensions /// // max will be 10 /// /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static T Max(this T value, T other) where T : IComparable { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif return value.GreaterThan(other) ? value : other; } @@ -306,15 +374,24 @@ public static class ComparableExtensions /// // min will be 5 /// /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static T Min(this T value, T other) where T : IComparable { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif return value.LessThan(other) ? value : other; } diff --git a/X10D/src/Math/DecimalExtensions.cs b/X10D/src/Math/DecimalExtensions.cs index a6dfe60..418909c 100644 --- a/X10D/src/Math/DecimalExtensions.cs +++ b/X10D/src/Math/DecimalExtensions.cs @@ -9,6 +9,7 @@ namespace X10D.Math; /// public static class DecimalExtensions { +#if NETCOREAPP3_0_OR_GREATER /// /// Returns the complex square root of this decimal number. /// @@ -20,6 +21,7 @@ public static class DecimalExtensions { return Complex.Sqrt((double)value); } +#endif /// /// Returns a value indicating whether the current value is evenly divisible by 2. @@ -30,7 +32,11 @@ public static class DecimalExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this decimal value) { return value % 2.0m == 0.0m; @@ -45,7 +51,11 @@ public static class DecimalExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this decimal value) { return !value.IsEven(); @@ -57,7 +67,11 @@ public static class DecimalExtensions /// The value to round. /// rounded to the nearest whole number. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static decimal Round(this decimal value) { return value.Round(1.0m); @@ -70,7 +84,11 @@ public static class DecimalExtensions /// The nearest multiple to which should be rounded. /// rounded to the nearest multiple of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static decimal Round(this decimal value, decimal nearest) { return System.Math.Round(value / nearest) * nearest; @@ -104,7 +122,11 @@ public static class DecimalExtensions /// /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Sign(this decimal value) { return System.Math.Sign(value); @@ -138,13 +160,12 @@ public static class DecimalExtensions /// /// /// is negative. - /// - /// For negative input, this method returns . To receive a complex number, see - /// . - /// - /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static decimal Sqrt(this decimal value) { switch (value) diff --git a/X10D/src/Math/DoubleExtensions.cs b/X10D/src/Math/DoubleExtensions.cs index 5b393a7..203eb4a 100644 --- a/X10D/src/Math/DoubleExtensions.cs +++ b/X10D/src/Math/DoubleExtensions.cs @@ -20,7 +20,11 @@ public static class DoubleExtensions /// is equal to , less than -1, or greater than 1, is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Acos(this double value) { return System.Math.Acos(value); @@ -38,7 +42,11 @@ public static class DoubleExtensions /// is less than 1 or equal to , is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Acosh(this double value) { return System.Math.Acosh(value); @@ -56,7 +64,11 @@ public static class DoubleExtensions /// is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Asin(this double value) { return System.Math.Asin(value); @@ -74,7 +86,11 @@ public static class DoubleExtensions /// , is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Asinh(this double value) { return System.Math.Asinh(value); @@ -91,7 +107,11 @@ public static class DoubleExtensions /// is equal to , is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Atan(this double value) { return System.Math.Atan(value); @@ -110,12 +130,17 @@ public static class DoubleExtensions /// is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Atanh(this double value) { return System.Math.Atanh(value); } +#if NETCOREAPP3_0_OR_GREATER /// /// Returns the complex square root of this double-precision floating-point number. /// @@ -141,6 +166,7 @@ public static class DoubleExtensions return new Complex(0, System.Math.Sqrt(-value)); } } +#endif /// /// Returns the cosine of the specified angle. @@ -152,7 +178,11 @@ public static class DoubleExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Cos(this double value) { return System.Math.Cos(value); @@ -169,7 +199,11 @@ public static class DoubleExtensions /// , is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Cosh(this double value) { return System.Math.Cosh(value); @@ -181,7 +215,11 @@ public static class DoubleExtensions /// The angle in degrees to convert. /// The result of π * / 180. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double DegreesToRadians(this double value) { return value * (System.Math.PI / 180.0); @@ -196,7 +234,11 @@ public static class DoubleExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this double value) { return System.Math.Abs(value % 2.0) < double.Epsilon; @@ -211,7 +253,11 @@ public static class DoubleExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this double value) { return !value.IsEven(); @@ -223,7 +269,11 @@ public static class DoubleExtensions /// The angle in radians to convert. /// The result of π * / 180. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double RadiansToDegrees(this double value) { return value * (180.0 / System.Math.PI); @@ -235,7 +285,11 @@ public static class DoubleExtensions /// The value to round. /// rounded to the nearest whole number. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Round(this double value) { return value.Round(1.0); @@ -248,7 +302,11 @@ public static class DoubleExtensions /// The nearest multiple to which should be rounded. /// rounded to the nearest multiple of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Round(this double value, double nearest) { return System.Math.Round(value / nearest) * nearest; @@ -264,7 +322,11 @@ public static class DoubleExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Sin(this double value) { return System.Math.Sin(value); @@ -280,7 +342,11 @@ public static class DoubleExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Sinh(this double value) { return System.Math.Sinh(value); @@ -315,7 +381,11 @@ public static class DoubleExtensions /// /// is equal to . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Sign(this double value) { return System.Math.Sign(value); @@ -348,15 +418,14 @@ public static class DoubleExtensions /// /// /// - /// - /// For negative input, this method returns . To receive a complex number, see - /// . - /// - /// /// SLenik https://stackoverflow.com/a/6755197/1467293 /// CC BY-SA 3.0 [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Sqrt(this double value) { switch (value) @@ -395,7 +464,11 @@ public static class DoubleExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Tan(this double value) { return System.Math.Tan(value); @@ -412,7 +485,11 @@ public static class DoubleExtensions /// , this method returns . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Tanh(this double value) { return System.Math.Tanh(value); diff --git a/X10D/src/Math/Int16Extensions.cs b/X10D/src/Math/Int16Extensions.cs index 731c285..50dd890 100644 --- a/X10D/src/Math/Int16Extensions.cs +++ b/X10D/src/Math/Int16Extensions.cs @@ -18,7 +18,11 @@ public static class Int16Extensions /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static short DigitalRoot(this short value) { short root = System.Math.Abs(value).Mod(9); @@ -32,7 +36,11 @@ public static class Int16Extensions /// The factorial of . /// is less than 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long Factorial(this short value) { if (value < 0) @@ -63,7 +71,11 @@ public static class Int16Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this short value) { return (value & 1) == 0; @@ -78,7 +90,11 @@ public static class Int16Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this short value) { return !value.IsEven(); @@ -92,7 +108,11 @@ public static class Int16Extensions /// if is prime; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsPrime(this short value) { return ((long)value).IsPrime(); @@ -113,7 +133,11 @@ public static class Int16Extensions /// ShreevatsaR, https://stackoverflow.com/a/1082938/1467293 /// CC-BY-SA 2.5 [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static short Mod(this short dividend, short divisor) { int r = dividend % divisor; @@ -129,7 +153,11 @@ public static class Int16Extensions /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int MultiplicativePersistence(this short value) { return ((long)value).MultiplicativePersistence(); @@ -163,7 +191,11 @@ public static class Int16Extensions /// /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Sign(this short value) { return System.Math.Sign(value); diff --git a/X10D/src/Math/Int32Extensions.cs b/X10D/src/Math/Int32Extensions.cs index faaeb5d..86d3c2f 100644 --- a/X10D/src/Math/Int32Extensions.cs +++ b/X10D/src/Math/Int32Extensions.cs @@ -18,7 +18,11 @@ public static class Int32Extensions /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int DigitalRoot(this int value) { int root = System.Math.Abs(value).Mod(9); @@ -32,7 +36,11 @@ public static class Int32Extensions /// The factorial of . /// is less than 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long Factorial(this int value) { if (value < 0) @@ -63,7 +71,11 @@ public static class Int32Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this int value) { return (value & 1) == 0; @@ -78,7 +90,11 @@ public static class Int32Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this int value) { return !value.IsEven(); @@ -92,7 +108,11 @@ public static class Int32Extensions /// if is prime; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsPrime(this int value) { return ((long)value).IsPrime(); @@ -113,7 +133,11 @@ public static class Int32Extensions /// ShreevatsaR, https://stackoverflow.com/a/1082938/1467293 /// CC-BY-SA 2.5 [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Mod(this int dividend, int divisor) { int r = dividend % divisor; @@ -129,7 +153,11 @@ public static class Int32Extensions /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int MultiplicativePersistence(this int value) { return ((long)value).MultiplicativePersistence(); @@ -163,7 +191,11 @@ public static class Int32Extensions /// /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Sign(this int value) { return System.Math.Sign(value); diff --git a/X10D/src/Math/Int64Extensions.cs b/X10D/src/Math/Int64Extensions.cs index 48d5ed3..51dfc75 100644 --- a/X10D/src/Math/Int64Extensions.cs +++ b/X10D/src/Math/Int64Extensions.cs @@ -18,7 +18,11 @@ public static class Int64Extensions /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long DigitalRoot(this long value) { long root = System.Math.Abs(value).Mod(9L); @@ -32,7 +36,11 @@ public static class Int64Extensions /// The factorial of . /// is less than 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long Factorial(this long value) { if (value < 0) @@ -63,7 +71,11 @@ public static class Int64Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this long value) { return (value & 1) == 0; @@ -78,7 +90,11 @@ public static class Int64Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this long value) { return !value.IsEven(); @@ -92,7 +108,11 @@ public static class Int64Extensions /// if is prime; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsPrime(this long value) { switch (value) @@ -138,7 +158,11 @@ public static class Int64Extensions /// ShreevatsaR, https://stackoverflow.com/a/1082938/1467293 /// CC-BY-SA 2.5 [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long Mod(this long dividend, long divisor) { long r = dividend % divisor; @@ -154,7 +178,11 @@ public static class Int64Extensions /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int MultiplicativePersistence(this long value) { var persistence = 0; @@ -219,7 +247,11 @@ public static class Int64Extensions /// /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Sign(this long value) { return System.Math.Sign(value); diff --git a/X10D/src/Math/MathUtility.cs b/X10D/src/Math/MathUtility.cs index a7aa41c..8613219 100644 --- a/X10D/src/Math/MathUtility.cs +++ b/X10D/src/Math/MathUtility.cs @@ -18,7 +18,11 @@ public static class MathUtility /// The interpolation result as determined by (1 - alpha) * value + alpha * target. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Lerp(float value, float target, float alpha) { // rookie mistake: a + t * (b - a) @@ -36,7 +40,11 @@ public static class MathUtility /// The interpolation result as determined by (1 - alpha) * value + alpha * target. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static double Lerp(double value, double target, double alpha) { // rookie mistake: a + t * (b - a) diff --git a/X10D/src/Math/SByteExtensions.cs b/X10D/src/Math/SByteExtensions.cs index 8e640a0..07252ef 100644 --- a/X10D/src/Math/SByteExtensions.cs +++ b/X10D/src/Math/SByteExtensions.cs @@ -19,7 +19,11 @@ public static class SByteExtensions /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static sbyte DigitalRoot(this sbyte value) { int root = System.Math.Abs(value).Mod(9); @@ -33,7 +37,11 @@ public static class SByteExtensions /// The factorial of . /// is less than 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long Factorial(this sbyte value) { if (value < 0) @@ -64,7 +72,11 @@ public static class SByteExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this sbyte value) { return value % 2 == 0; @@ -79,7 +91,11 @@ public static class SByteExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this sbyte value) { return !value.IsEven(); @@ -93,7 +109,11 @@ public static class SByteExtensions /// if is prime; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsPrime(this sbyte value) { return ((long)value).IsPrime(); @@ -114,7 +134,11 @@ public static class SByteExtensions /// ShreevatsaR, https://stackoverflow.com/a/1082938/1467293 /// CC-BY-SA 2.5 [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static sbyte Mod(this sbyte dividend, sbyte divisor) { int r = dividend % divisor; @@ -130,7 +154,11 @@ public static class SByteExtensions /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int MultiplicativePersistence(this sbyte value) { return ((long)value).MultiplicativePersistence(); @@ -164,7 +192,11 @@ public static class SByteExtensions /// /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Sign(this sbyte value) { return System.Math.Sign(value); diff --git a/X10D/src/Math/SingleExtensions.cs b/X10D/src/Math/SingleExtensions.cs index df6b8b8..d72360a 100644 --- a/X10D/src/Math/SingleExtensions.cs +++ b/X10D/src/Math/SingleExtensions.cs @@ -20,7 +20,11 @@ public static class SingleExtensions /// is equal to , less than -1, or greater than 1, is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Acos(this float value) { return MathF.Acos(value); @@ -38,7 +42,11 @@ public static class SingleExtensions /// is less than 1 or equal to , is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Acosh(this float value) { return MathF.Acosh(value); @@ -56,7 +64,11 @@ public static class SingleExtensions /// is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Asin(this float value) { return MathF.Asin(value); @@ -74,7 +86,11 @@ public static class SingleExtensions /// , is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Asinh(this float value) { return MathF.Asinh(value); @@ -91,7 +107,11 @@ public static class SingleExtensions /// is equal to , is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Atan(this float value) { return MathF.Atan(value); @@ -110,12 +130,17 @@ public static class SingleExtensions /// is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Atanh(this float value) { return MathF.Atanh(value); } +#if NETCOREAPP3_0_OR_GREATER /// /// Returns the complex square root of this single-precision floating-point number. /// @@ -141,6 +166,7 @@ public static class SingleExtensions return new Complex(0, MathF.Sqrt(-value)); } } +#endif /// /// Returns the cosine of the specified angle. @@ -152,7 +178,11 @@ public static class SingleExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Cos(this float value) { return MathF.Cos(value); @@ -169,7 +199,11 @@ public static class SingleExtensions /// , is returned. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Cosh(this float value) { return MathF.Cosh(value); @@ -181,7 +215,11 @@ public static class SingleExtensions /// The angle in degrees to convert. /// The result of π * / 180. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float DegreesToRadians(this float value) { return value * (MathF.PI / 180.0f); @@ -196,7 +234,11 @@ public static class SingleExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this float value) { return value % 2 == 0; @@ -211,7 +253,11 @@ public static class SingleExtensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this float value) { return !value.IsEven(); @@ -223,7 +269,11 @@ public static class SingleExtensions /// The angle in radians to convert. /// The result of π * / 180. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float RadiansToDegrees(this float value) { return value * (180.0f / MathF.PI); @@ -235,7 +285,11 @@ public static class SingleExtensions /// The value to round. /// rounded to the nearest whole number. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Round(this float value) { return value.Round(1.0f); @@ -248,7 +302,11 @@ public static class SingleExtensions /// The nearest multiple to which should be rounded. /// rounded to the nearest multiple of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Round(this float value, float nearest) { return MathF.Round(value / nearest) * nearest; @@ -282,7 +340,11 @@ public static class SingleExtensions /// /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Sign(this float value) { return MathF.Sign(value); @@ -315,15 +377,14 @@ public static class SingleExtensions /// /// /// - /// - /// For negative input, this method returns . To receive a complex number, see - /// . - /// - /// /// SLenik https://stackoverflow.com/a/6755197/1467293 /// CC BY-SA 3.0 [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Sqrt(this float value) { switch (value) @@ -362,7 +423,11 @@ public static class SingleExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Sin(this float value) { return MathF.Sin(value); @@ -378,7 +443,11 @@ public static class SingleExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Sinh(this float value) { return MathF.Sinh(value); @@ -394,7 +463,11 @@ public static class SingleExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Tan(this float value) { return MathF.Sin(value); @@ -411,7 +484,11 @@ public static class SingleExtensions /// , this method returns . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static float Tanh(this float value) { return MathF.Tanh(value); diff --git a/X10D/src/Math/UInt16Extensions.cs b/X10D/src/Math/UInt16Extensions.cs index e781942..dca43d9 100644 --- a/X10D/src/Math/UInt16Extensions.cs +++ b/X10D/src/Math/UInt16Extensions.cs @@ -19,7 +19,11 @@ public static class UInt16Extensions /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ushort DigitalRoot(this ushort value) { var root = (ushort)(value % 9); @@ -32,7 +36,11 @@ public static class UInt16Extensions /// The value whose factorial to compute. /// The factorial of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ulong Factorial(this ushort value) { if (value == 0) @@ -58,7 +66,11 @@ public static class UInt16Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this ushort value) { return (value & 1) == 0; @@ -72,7 +84,11 @@ public static class UInt16Extensions /// if is prime; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsPrime(this ushort value) { return ((ulong)value).IsPrime(); @@ -87,7 +103,11 @@ public static class UInt16Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this ushort value) { return !value.IsEven(); @@ -102,7 +122,11 @@ public static class UInt16Extensions /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int MultiplicativePersistence(this ushort value) { return ((ulong)value).MultiplicativePersistence(); diff --git a/X10D/src/Math/UInt32Extensions.cs b/X10D/src/Math/UInt32Extensions.cs index 65217a4..8b1ffa5 100644 --- a/X10D/src/Math/UInt32Extensions.cs +++ b/X10D/src/Math/UInt32Extensions.cs @@ -19,7 +19,11 @@ public static class UInt32Extensions /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static uint DigitalRoot(this uint value) { uint root = value % 9; @@ -32,7 +36,11 @@ public static class UInt32Extensions /// The value whose factorial to compute. /// The factorial of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ulong Factorial(this uint value) { if (value == 0) @@ -58,7 +66,11 @@ public static class UInt32Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this uint value) { return (value & 1) == 0; @@ -72,7 +84,11 @@ public static class UInt32Extensions /// if is prime; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsPrime(this uint value) { return ((ulong)value).IsPrime(); @@ -87,7 +103,11 @@ public static class UInt32Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this uint value) { return !value.IsEven(); @@ -102,7 +122,11 @@ public static class UInt32Extensions /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int MultiplicativePersistence(this uint value) { return ((ulong)value).MultiplicativePersistence(); diff --git a/X10D/src/Math/UInt64Extensions.cs b/X10D/src/Math/UInt64Extensions.cs index 08f88ba..d0f78bd 100644 --- a/X10D/src/Math/UInt64Extensions.cs +++ b/X10D/src/Math/UInt64Extensions.cs @@ -19,7 +19,11 @@ public static class UInt64Extensions /// For example, the digital root of 239 is 5: 2 + 3 + 9 = 14, then 1 + 4 = 5. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ulong DigitalRoot(this ulong value) { ulong root = value % 9; @@ -32,7 +36,11 @@ public static class UInt64Extensions /// The value whose factorial to compute. /// The factorial of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ulong Factorial(this ulong value) { if (value == 0) @@ -58,7 +66,11 @@ public static class UInt64Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsEven(this ulong value) { return (value & 1) == 0; @@ -72,7 +84,11 @@ public static class UInt64Extensions /// if is prime; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsPrime(this ulong value) { switch (value) @@ -112,7 +128,11 @@ public static class UInt64Extensions /// otherwise. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsOdd(this ulong value) { return !value.IsEven(); @@ -127,7 +147,11 @@ public static class UInt64Extensions /// Multiplicative persistence is defined as the recursive digital product until that product is a single digit. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int MultiplicativePersistence(this ulong value) { var persistence = 0; diff --git a/X10D/src/Net/EndPointExtensions.cs b/X10D/src/Net/EndPointExtensions.cs index b7ef2d7..b10de62 100644 --- a/X10D/src/Net/EndPointExtensions.cs +++ b/X10D/src/Net/EndPointExtensions.cs @@ -22,13 +22,21 @@ public static class EndPointExtensions /// /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string GetHost(this EndPoint endPoint) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(endPoint); +#else if (endPoint is null) { throw new ArgumentNullException(nameof(endPoint)); } +#endif return endPoint switch { @@ -51,13 +59,21 @@ public static class EndPointExtensions /// /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int GetPort(this EndPoint endPoint) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(endPoint); +#else if (endPoint is null) { throw new ArgumentNullException(nameof(endPoint)); } +#endif return endPoint switch { diff --git a/X10D/src/Net/IPAddressExtensions.cs b/X10D/src/Net/IPAddressExtensions.cs index 0b8358d..8198b3b 100644 --- a/X10D/src/Net/IPAddressExtensions.cs +++ b/X10D/src/Net/IPAddressExtensions.cs @@ -17,10 +17,24 @@ public static class IPAddressExtensions /// /// if the specified IP address is a valid IPv4 address; otherwise, . /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsIPv4(this IPAddress address) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(address); +#else + if (address is null) + { + throw new ArgumentNullException(nameof(address)); + } +#endif + return address.AddressFamily == AddressFamily.InterNetwork; } @@ -31,10 +45,24 @@ public static class IPAddressExtensions /// /// if the specified IP address is a valid IPv6 address; otherwise, . /// + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsIPv6(this IPAddress address) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(address); +#else + if (address is null) + { + throw new ArgumentNullException(nameof(address)); + } +#endif + return address.AddressFamily == AddressFamily.InterNetworkV6; } } diff --git a/X10D/src/Net/Int16Extensions.cs b/X10D/src/Net/Int16Extensions.cs index 60b648b..699cef2 100644 --- a/X10D/src/Net/Int16Extensions.cs +++ b/X10D/src/Net/Int16Extensions.cs @@ -15,7 +15,11 @@ public static class Int16Extensions /// The value to convert, expressed in host byte order. /// An integer value, expressed in network byte order. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static short HostToNetworkOrder(this short value) { return IPAddress.HostToNetworkOrder(value); @@ -27,7 +31,11 @@ public static class Int16Extensions /// The value to convert, expressed in network byte order. /// An integer value, expressed in host byte order. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static short NetworkToHostOrder(this short value) { return IPAddress.NetworkToHostOrder(value); diff --git a/X10D/src/Net/Int32Extensions.cs b/X10D/src/Net/Int32Extensions.cs index 7c7acbe..8bf0f59 100644 --- a/X10D/src/Net/Int32Extensions.cs +++ b/X10D/src/Net/Int32Extensions.cs @@ -15,7 +15,11 @@ public static class Int32Extensions /// The value to convert, expressed in host byte order. /// An integer value, expressed in network byte order. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int HostToNetworkOrder(this int value) { return IPAddress.HostToNetworkOrder(value); @@ -27,7 +31,11 @@ public static class Int32Extensions /// The value to convert, expressed in network byte order. /// An integer value, expressed in host byte order. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int NetworkToHostOrder(this int value) { return IPAddress.NetworkToHostOrder(value); diff --git a/X10D/src/Net/Int64Extensions.cs b/X10D/src/Net/Int64Extensions.cs index a586ca8..ede22c4 100644 --- a/X10D/src/Net/Int64Extensions.cs +++ b/X10D/src/Net/Int64Extensions.cs @@ -15,7 +15,11 @@ public static class Int64Extensions /// The value to convert, expressed in host byte order. /// An integer value, expressed in network byte order. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long HostToNetworkOrder(this long value) { return IPAddress.HostToNetworkOrder(value); @@ -27,7 +31,11 @@ public static class Int64Extensions /// The value to convert, expressed in network byte order. /// An integer value, expressed in host byte order. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long NetworkToHostOrder(this long value) { return IPAddress.NetworkToHostOrder(value); diff --git a/X10D/src/Numerics/ByteExtensions.cs b/X10D/src/Numerics/ByteExtensions.cs index ccd97a3..02c6e74 100644 --- a/X10D/src/Numerics/ByteExtensions.cs +++ b/X10D/src/Numerics/ByteExtensions.cs @@ -18,7 +18,11 @@ public static class ByteExtensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static byte RotateLeft(this byte value, int count) { count = count.Mod(8); @@ -34,7 +38,11 @@ public static class ByteExtensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static byte RotateRight(this byte value, int count) { count = count.Mod(8); diff --git a/X10D/src/Numerics/Int16Extensions.cs b/X10D/src/Numerics/Int16Extensions.cs index 789eeb5..1a3656b 100644 --- a/X10D/src/Numerics/Int16Extensions.cs +++ b/X10D/src/Numerics/Int16Extensions.cs @@ -17,7 +17,11 @@ public static class Int16Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static short RotateLeft(this short value, int count) { var unsigned = unchecked((ushort)value); @@ -33,7 +37,11 @@ public static class Int16Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static short RotateRight(this short value, int count) { var unsigned = unchecked((ushort)value); diff --git a/X10D/src/Numerics/Int32Extensions.cs b/X10D/src/Numerics/Int32Extensions.cs index 75dfea8..3bf74b9 100644 --- a/X10D/src/Numerics/Int32Extensions.cs +++ b/X10D/src/Numerics/Int32Extensions.cs @@ -17,7 +17,11 @@ public static class Int32Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int RotateLeft(this int value, int count) { var unsigned = unchecked((uint)value); @@ -33,7 +37,11 @@ public static class Int32Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int RotateRight(this int value, int count) { var unsigned = unchecked((uint)value); diff --git a/X10D/src/Numerics/Int64Extensions.cs b/X10D/src/Numerics/Int64Extensions.cs index 5f25a59..695ed4b 100644 --- a/X10D/src/Numerics/Int64Extensions.cs +++ b/X10D/src/Numerics/Int64Extensions.cs @@ -17,7 +17,11 @@ public static class Int64Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long RotateLeft(this long value, int count) { var unsigned = unchecked((ulong)value); @@ -33,7 +37,11 @@ public static class Int64Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long RotateRight(this long value, int count) { var unsigned = unchecked((ulong)value); diff --git a/X10D/src/Numerics/RandomExtensions.cs b/X10D/src/Numerics/RandomExtensions.cs index b89a5e2..cdf464f 100644 --- a/X10D/src/Numerics/RandomExtensions.cs +++ b/X10D/src/Numerics/RandomExtensions.cs @@ -19,10 +19,14 @@ public static class RandomExtensions /// is . public static Quaternion NextRotation(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif int seed = random.Next(); var seededRandom = new Random(seed); @@ -42,10 +46,14 @@ public static class RandomExtensions /// is . public static Quaternion NextRotationUniform(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif int seed = random.Next(); var seededRandom = new Random(seed); @@ -74,10 +82,14 @@ public static class RandomExtensions /// public static Vector2 NextUnitVector2(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif // no need to construct a seeded random here, since we only call Next once @@ -98,10 +110,14 @@ public static class RandomExtensions /// public static Vector3 NextUnitVector3(this Random random) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(random); +#else if (random is null) { throw new ArgumentNullException(nameof(random)); } +#endif int seed = random.Next(); var seededRandom = new Random(seed); diff --git a/X10D/src/Numerics/SByteExtensions.cs b/X10D/src/Numerics/SByteExtensions.cs index e3d9d24..eb6ce07 100644 --- a/X10D/src/Numerics/SByteExtensions.cs +++ b/X10D/src/Numerics/SByteExtensions.cs @@ -18,7 +18,11 @@ public static class SByteExtensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static sbyte RotateLeft(this sbyte value, int count) { var signed = unchecked((byte)value); @@ -34,7 +38,11 @@ public static class SByteExtensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static sbyte RotateRight(this sbyte value, int count) { var signed = unchecked((byte)value); diff --git a/X10D/src/Numerics/UInt16Extensions.cs b/X10D/src/Numerics/UInt16Extensions.cs index 4798deb..54403c9 100644 --- a/X10D/src/Numerics/UInt16Extensions.cs +++ b/X10D/src/Numerics/UInt16Extensions.cs @@ -1,5 +1,4 @@ using System.Diagnostics.Contracts; -using System.Numerics; using System.Runtime.CompilerServices; namespace X10D.Numerics; @@ -19,7 +18,11 @@ public static class UInt16Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ushort RotateLeft(this ushort value, int count) { return (ushort)((ushort)(value << count) | (ushort)(value >> (16 - count))); @@ -34,7 +37,11 @@ public static class UInt16Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ushort RotateRight(this ushort value, int count) { return (ushort)((ushort)(value >> count) | (ushort)(value << (16 - count))); diff --git a/X10D/src/Numerics/UInt32Extensions.cs b/X10D/src/Numerics/UInt32Extensions.cs index d5b619c..7381b1b 100644 --- a/X10D/src/Numerics/UInt32Extensions.cs +++ b/X10D/src/Numerics/UInt32Extensions.cs @@ -1,5 +1,4 @@ using System.Diagnostics.Contracts; -using System.Numerics; using System.Runtime.CompilerServices; namespace X10D.Numerics; @@ -19,10 +18,14 @@ public static class UInt32Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static uint RotateLeft(this uint value, int count) { - return BitOperations.RotateLeft(value, count); + return (value << count) | (value >> (32 - count)); } /// @@ -34,9 +37,13 @@ public static class UInt32Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static uint RotateRight(this uint value, int count) { - return BitOperations.RotateRight(value, count); + return (value >> count) | (value << (32 - count)); } } diff --git a/X10D/src/Numerics/UInt64Extensions.cs b/X10D/src/Numerics/UInt64Extensions.cs index 709ca93..0f10aba 100644 --- a/X10D/src/Numerics/UInt64Extensions.cs +++ b/X10D/src/Numerics/UInt64Extensions.cs @@ -1,5 +1,4 @@ using System.Diagnostics.Contracts; -using System.Numerics; using System.Runtime.CompilerServices; namespace X10D.Numerics; @@ -19,10 +18,14 @@ public static class UInt64Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ulong RotateLeft(this ulong value, int count) { - return BitOperations.RotateLeft(value, count); + return (value << count) | (value >> (64 - count)); } /// @@ -34,9 +37,13 @@ public static class UInt64Extensions /// /// The rotated value. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static ulong RotateRight(this ulong value, int count) { - return BitOperations.RotateRight(value, count); + return (value >> count) | (value << (64 - count)); } } diff --git a/X10D/src/Numerics/Vector2Extensions.cs b/X10D/src/Numerics/Vector2Extensions.cs new file mode 100644 index 0000000..8831e2c --- /dev/null +++ b/X10D/src/Numerics/Vector2Extensions.cs @@ -0,0 +1,51 @@ +using System.Diagnostics.Contracts; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-extensions for . +/// +public static class Vector2Extensions +{ + /// + /// Returns a vector whose Y component is the same as the specified vector, and whose X component is a new value. + /// + /// The vector to copy. + /// The new X component value. + /// + /// A new instance of whose components is the same as that of + /// , and whose component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector2 WithX(this Vector2 vector, float x) + { + return vector with {X = x}; + } + + /// + /// Returns a vector whose X component is the same as the specified vector, and whose Y component is a new value. + /// + /// The vector to copy. + /// The new Y component value. + /// + /// A new instance of whose components is the same as that of + /// , and whose component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector2 WithY(this Vector2 vector, float y) + { + return vector with {Y = y}; + } +} diff --git a/X10D/src/Numerics/Vector3Extensions.cs b/X10D/src/Numerics/Vector3Extensions.cs new file mode 100644 index 0000000..0f906a9 --- /dev/null +++ b/X10D/src/Numerics/Vector3Extensions.cs @@ -0,0 +1,71 @@ +using System.Diagnostics.Contracts; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-extensions for . +/// +public static class Vector3Extensions +{ + /// + /// Returns a vector whose Y and Z components are the same as the specified vector, and whose X component is a new value. + /// + /// The vector to copy. + /// The new X component value. + /// + /// A new instance of whose and components are + /// the same as that of , and whose component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector3 WithX(this Vector3 vector, float x) + { + return vector with {X = x}; + } + + /// + /// Returns a vector whose X and Z components are the same as the specified vector, and whose Y component is a new value. + /// + /// The vector to copy. + /// The new Y component value. + /// + /// A new instance of whose and components are + /// the same as that of , and whose component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector3 WithY(this Vector3 vector, float y) + { + return vector with {Y = y}; + } + + /// + /// Returns a vector whose X and Y components are the same as the specified vector, and whose Z component is a new value. + /// + /// The vector to copy. + /// The new Z component value. + /// + /// A new instance of whose and components are + /// the same as that of , and whose component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector3 WithZ(this Vector3 vector, float z) + { + return vector with {Z = z}; + } +} diff --git a/X10D/src/Numerics/Vector4Extensions.cs b/X10D/src/Numerics/Vector4Extensions.cs new file mode 100644 index 0000000..20390bd --- /dev/null +++ b/X10D/src/Numerics/Vector4Extensions.cs @@ -0,0 +1,99 @@ +using System.Diagnostics.Contracts; +using System.Numerics; +using System.Runtime.CompilerServices; + +namespace X10D.Numerics; + +/// +/// Numeric-extensions for . +/// +public static class Vector4Extensions +{ + /// + /// Returns a vector whose Y, Z, and W components are the same as the specified vector, and whose X component is a new + /// value. + /// + /// The vector to copy. + /// The new X component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector4 WithX(this Vector4 vector, float x) + { + return vector with {X = x}; + } + + /// + /// Returns a vector whose X, Z, and W components are the same as the specified vector, and whose Y component is a new + /// value. + /// + /// The vector to copy. + /// The new Y component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector4 WithY(this Vector4 vector, float y) + { + return vector with {Y = y}; + } + + /// + /// Returns a vector whose X, Y, and W components are the same as the specified vector, and whose Z component is a new + /// value. + /// + /// The vector to copy. + /// The new Z component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector4 WithZ(this Vector4 vector, float z) + { + return vector with {Z = z}; + } + + /// + /// Returns a vector whose X, Y, and Z components are the same as the specified vector, and whose W component is a new + /// value. + /// + /// The vector to copy. + /// The new W component value. + /// + /// A new instance of whose , , and + /// components are the same as that of , and whose + /// component is . + /// + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static Vector4 WithW(this Vector4 vector, float w) + { + return vector with {W = w}; + } +} diff --git a/X10D/src/Reflection/MemberInfoExtensions.cs b/X10D/src/Reflection/MemberInfoExtensions.cs index 9fd389e..5c9bc7e 100644 --- a/X10D/src/Reflection/MemberInfoExtensions.cs +++ b/X10D/src/Reflection/MemberInfoExtensions.cs @@ -21,14 +21,22 @@ public static class MemberInfoExtensions /// /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool HasCustomAttribute(this MemberInfo member) where T : Attribute { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(member); +#else if (member is null) { throw new ArgumentNullException(nameof(member)); } +#endif return member.HasCustomAttribute(typeof(T)); } @@ -44,18 +52,29 @@ public static class MemberInfoExtensions /// /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool HasCustomAttribute(this MemberInfo member, Type attribute) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(member); +#else if (member is null) { throw new ArgumentNullException(nameof(member)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(attribute); +#else if (attribute is null) { throw new ArgumentNullException(nameof(attribute)); } +#endif if (!attribute.Inherits()) { @@ -85,6 +104,23 @@ public static class MemberInfoExtensions Func selector) where TAttribute : Attribute { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(member); +#else + if (member is null) + { + throw new ArgumentNullException(nameof(member)); + } +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(selector); +#else + if (selector is null) + { + throw new ArgumentNullException(nameof(selector)); + } +#endif + return member.SelectFromCustomAttribute(selector, default); } @@ -108,15 +144,22 @@ public static class MemberInfoExtensions Func selector, TReturn? defaultValue) where TAttribute : Attribute { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(member); +#else if (member is null) { throw new ArgumentNullException(nameof(member)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(selector); +#else if (selector is null) { throw new ArgumentNullException(nameof(selector)); } +#endif return member.GetCustomAttribute() is { } attribute ? selector(attribute) diff --git a/X10D/src/Reflection/TypeExtensions.cs b/X10D/src/Reflection/TypeExtensions.cs index 301d1d2..9d53c39 100644 --- a/X10D/src/Reflection/TypeExtensions.cs +++ b/X10D/src/Reflection/TypeExtensions.cs @@ -15,10 +15,24 @@ public static class TypeExtensions /// The type whose interface list to check. /// The interface type. /// if the current exists on the type; otherwise, . + /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool Implements(this Type value) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } +#endif + return value.Implements(typeof(T)); } @@ -28,19 +42,35 @@ public static class TypeExtensions /// The type whose interface list to check. /// The interface type. /// if the current exists on the type; otherwise, . + /// + /// is . + /// -or- + /// is . + /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool Implements(this Type value, Type interfaceType) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(interfaceType); +#else if (interfaceType is null) { throw new ArgumentNullException(nameof(interfaceType)); } +#endif if (!interfaceType.IsInterface) { @@ -62,11 +92,26 @@ public static class TypeExtensions /// if the current type inherits , or /// otherwise. /// + /// is . + /// is not a class. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool Inherits(this Type value) where T : class { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } +#endif + return value.Inherits(typeof(T)); } @@ -79,19 +124,40 @@ public static class TypeExtensions /// if the current type inherits , or /// otherwise. /// + /// + /// is . + /// -or- + /// is . + /// + /// + /// is not a class. + /// -or- + /// is not a class. + /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool Inherits(this Type value, Type type) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(type); +#else if (type is null) { throw new ArgumentNullException(nameof(type)); } +#endif if (!value.IsClass) { diff --git a/X10D/src/Text/CharExtensions.cs b/X10D/src/Text/CharExtensions.cs index 9d59738..1e6d9f6 100644 --- a/X10D/src/Text/CharExtensions.cs +++ b/X10D/src/Text/CharExtensions.cs @@ -8,6 +8,22 @@ namespace X10D.Text; /// public static class CharExtensions { + /// + /// Returns a value indicating whether this character constitutes an emoji. + /// + /// The character to check. + /// if this character is an emoji; otherwise, . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static bool IsEmoji(this char value) + { + return value.ToString().IsEmoji(); + } + /// /// Returns a string composed of the current character repeated a specified number of times. /// @@ -17,7 +33,11 @@ public static class CharExtensions /// A composed of repeated times. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string Repeat(this char value, int count) { return count switch diff --git a/X10D/src/Text/Extensions.cs b/X10D/src/Text/Extensions.cs index 574083c..97e434c 100644 --- a/X10D/src/Text/Extensions.cs +++ b/X10D/src/Text/Extensions.cs @@ -1,4 +1,5 @@ -using System.Diagnostics.Contracts; +#if NET5_0_OR_GREATER +using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Text.Json; @@ -23,3 +24,4 @@ public static class Extensions return JsonSerializer.Serialize(value, options); } } +#endif diff --git a/X10D/src/Text/RuneExtensions.cs b/X10D/src/Text/RuneExtensions.cs index 5c0b146..0249fa3 100644 --- a/X10D/src/Text/RuneExtensions.cs +++ b/X10D/src/Text/RuneExtensions.cs @@ -1,4 +1,5 @@ -using System.Diagnostics.Contracts; +#if NETCOREAPP3_0_OR_GREATER +using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Text; @@ -9,6 +10,18 @@ namespace X10D.Text; /// public static class RuneExtensions { + /// + /// Returns a value indicating whether this rune constitutes an emoji. + /// + /// The rune to check. + /// if this rune is an emoji; otherwise, . + [Pure] + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] + public static bool IsEmoji(this Rune value) + { + return value.ToString().IsEmoji(); + } + /// /// Returns a string composed of the current rune repeated a specified number of times. /// @@ -44,3 +57,4 @@ public static class RuneExtensions return Encoding.UTF8.GetString(buffer); } } +#endif diff --git a/X10D/src/Text/StringExtensions.cs b/X10D/src/Text/StringExtensions.cs index 2f83e3c..b7ffa57 100644 --- a/X10D/src/Text/StringExtensions.cs +++ b/X10D/src/Text/StringExtensions.cs @@ -2,7 +2,9 @@ using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; using System.Text; +#if NET5_0_OR_GREATER using System.Text.Json; +#endif using X10D.Collections; using X10D.Core; using X10D.IO; @@ -23,7 +25,11 @@ public static class StringExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif [return: NotNullIfNotNull("value")] public static string? AsNullIfEmpty(this string? value) { @@ -40,7 +46,11 @@ public static class StringExtensions /// whitespace; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif [return: NotNullIfNotNull("value")] public static string? AsNullIfWhiteSpace(this string? value) { @@ -54,13 +64,21 @@ public static class StringExtensions /// The plain text string representation of . /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string Base64Decode(this string value) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif return Convert.FromBase64String(value).ToString(Encoding.ASCII); } @@ -72,13 +90,21 @@ public static class StringExtensions /// The string representation, in base 64, of . /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string Base64Encode(this string value) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif return Convert.ToBase64String(value.GetBytes(Encoding.ASCII)); } @@ -101,23 +127,37 @@ public static class StringExtensions /// is . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string ChangeEncoding(this string value, Encoding sourceEncoding, Encoding destinationEncoding) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(sourceEncoding); +#else if (sourceEncoding is null) { throw new ArgumentNullException(nameof(sourceEncoding)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(destinationEncoding); +#else if (destinationEncoding is null) { throw new ArgumentNullException(nameof(destinationEncoding)); } +#endif return value.GetBytes(sourceEncoding).ToString(destinationEncoding); } @@ -133,7 +173,11 @@ public static class StringExtensions /// (http://geekswithblogs.net/sdorman/Default.aspx). /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static T EnumParse(this string value) where T : struct, Enum { @@ -152,14 +196,22 @@ public static class StringExtensions /// (http://geekswithblogs.net/sdorman/Default.aspx). /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static T EnumParse(this string value, bool ignoreCase) where T : struct, Enum { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif value = value.Trim(); @@ -171,6 +223,7 @@ public static class StringExtensions return Enum.Parse(value, ignoreCase); } +#if NET5_0_OR_GREATER /// /// Returns an object from the specified JSON string. /// @@ -181,11 +234,11 @@ public static class StringExtensions /// An object constructed from the JSON string, or if deserialization could not be performed. /// [Pure] - [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] public static T? FromJson(this string value, JsonSerializerOptions? options = null) { return JsonSerializer.Deserialize(value, options); } +#endif /// /// Gets a [] representing the value the with @@ -194,7 +247,11 @@ public static class StringExtensions /// The string to convert. /// Returns a []. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static byte[] GetBytes(this string value) { return value.GetBytes(Encoding.UTF8); @@ -211,22 +268,58 @@ public static class StringExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static byte[] GetBytes(this string value, Encoding encoding) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } - +#endif +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(encoding); +#else if (encoding is null) { throw new ArgumentNullException(nameof(encoding)); } +#endif return encoding.GetBytes(value); } + /// + /// Returns a value indicating whether this string constitutes an emoji. + /// + /// The input string. + /// if this string is an emoji; otherwise, . + [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else + [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif + public static bool IsEmoji(this string value) + { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else + if (value is null) + { + throw new ArgumentNullException(nameof(value)); + } +#endif + + return EmojiRegex.Value.IsMatch(value); + } + /// /// Determines if all alpha characters in this string are considered lowercase. /// @@ -235,16 +328,25 @@ public static class StringExtensions /// if all alpha characters in this string are lowercase; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLower(this string value) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif for (var index = 0; index < value.Length; index++) { +#if NETCOREAPP3_0_OR_GREATER var rune = new Rune(value[index]); if (!Rune.IsLetter(rune)) @@ -256,6 +358,19 @@ public static class StringExtensions { return false; } +#else + char current = value[index]; + + if (!char.IsLetter(current)) + { + continue; + } + + if (!char.IsLower(current)) + { + return false; + } +#endif } return true; @@ -272,13 +387,21 @@ public static class StringExtensions /// /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsPalindrome(this string value) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif if (string.IsNullOrWhiteSpace(value)) { @@ -288,6 +411,7 @@ public static class StringExtensions for (int index = 0, endIndex = value.Length - 1; index < value.Length; index++, endIndex--) { +#if NETCOREAPP3_0_OR_GREATER Rune startRune = new Rune(value[index]); Rune endRune = new Rune(value[endIndex]); @@ -307,6 +431,27 @@ public static class StringExtensions { return false; } +#else + char startChar = value[index]; + char endChar = value[endIndex]; + + if (!char.IsLetter(startChar) && !char.IsNumber(startChar)) + { + endIndex++; + continue; + } + + if (!char.IsLetter(endChar) && !char.IsNumber(endChar)) + { + index--; + continue; + } + + if (char.ToUpperInvariant(startChar) != char.ToUpperInvariant(endChar)) + { + return false; + } +#endif } return true; @@ -320,16 +465,25 @@ public static class StringExtensions /// if all alpha characters in this string are uppercase; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsUpper(this string value) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif for (var index = 0; index < value.Length; index++) { +#if NETCOREAPP3_0_OR_GREATER var rune = new Rune(value[index]); if (!Rune.IsLetter(rune)) @@ -341,6 +495,19 @@ public static class StringExtensions { return false; } +#else + char current = value[index]; + + if (!char.IsLetter(current)) + { + continue; + } + + if (!char.IsUpper(current)) + { + return false; + } +#endif } return true; @@ -355,13 +522,21 @@ public static class StringExtensions /// /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string Repeat(this string value, int count) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif switch (count) { @@ -396,13 +571,21 @@ public static class StringExtensions /// is . /// is less than 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string Randomize(this string source, int length, Random? random = null) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(source); +#else if (source is null) { throw new ArgumentNullException(nameof(source)); } +#endif if (length < 0) { @@ -414,7 +597,7 @@ public static class StringExtensions return string.Empty; } - random ??= Random.Shared; + random ??= RandomExtensions.GetShared(); char[] array = source.ToCharArray(); var builder = new StringBuilder(length); @@ -434,13 +617,21 @@ public static class StringExtensions /// The string to reverse. /// A whose characters are that of in reverse order. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string Reverse(this string value) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif if (value.Length < 2) { @@ -462,21 +653,29 @@ public static class StringExtensions /// /// The string to shuffle. /// - /// The instance to use for the shuffling. If is specified, - /// is used. + /// The instance to use for the shuffling. If is specified, a shared + /// instance is used. /// /// A new containing the characters in , rearranged. /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static string Shuffled(this string value, Random? random = null) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif - random ??= Random.Shared; + random ??= RandomExtensions.GetShared(); char[] array = value.ToCharArray(); array.Shuffle(random); @@ -494,13 +693,21 @@ public static class StringExtensions /// /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static IEnumerable Split(this string value, int chunkSize) { +#if NET6_0_OR_GREATER + ArgumentNullException.ThrowIfNull(value); +#else if (value is null) { throw new ArgumentNullException(nameof(value)); } +#endif if (chunkSize == 0) { @@ -524,7 +731,11 @@ public static class StringExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif [return: NotNullIfNotNull("alternative")] public static string? WithEmptyAlternative(this string? value, string? alternative) { @@ -542,7 +753,11 @@ public static class StringExtensions /// whitespace; otherwise, . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif [return: NotNullIfNotNull("alternative")] public static string? WithWhiteSpaceAlternative(this string? value, string? alternative) { diff --git a/X10D/src/Time/ByteExtensions.cs b/X10D/src/Time/ByteExtensions.cs index b15a91d..7273fce 100644 --- a/X10D/src/Time/ByteExtensions.cs +++ b/X10D/src/Time/ByteExtensions.cs @@ -17,7 +17,11 @@ public static class ByteExtensions /// /// is 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this byte value) { if (value == 0) @@ -43,7 +47,11 @@ public static class ByteExtensions /// is greater than 253,402,300,799,999. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeMilliseconds(this byte value) { return DateTimeOffset.FromUnixTimeMilliseconds(value); @@ -64,7 +72,11 @@ public static class ByteExtensions /// is greater than 253,402,300,799. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeSeconds(this byte value) { return DateTimeOffset.FromUnixTimeSeconds(value); @@ -76,7 +88,11 @@ public static class ByteExtensions /// The duration, in ticks. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Ticks(this byte value) { return TimeSpan.FromTicks(value); @@ -90,7 +106,11 @@ public static class ByteExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this byte value) { return TimeSpan.FromMilliseconds(value); @@ -104,7 +124,11 @@ public static class ByteExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this byte value) { return TimeSpan.FromSeconds(value); @@ -118,7 +142,11 @@ public static class ByteExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this byte value) { return TimeSpan.FromMinutes(value); @@ -132,7 +160,11 @@ public static class ByteExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this byte value) { return TimeSpan.FromHours(value); @@ -144,7 +176,11 @@ public static class ByteExtensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this byte value) { return TimeSpan.FromDays(value); @@ -158,7 +194,11 @@ public static class ByteExtensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this byte value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/DateTimeExtensions.cs b/X10D/src/Time/DateTimeExtensions.cs index b546722..f06a4f0 100644 --- a/X10D/src/Time/DateTimeExtensions.cs +++ b/X10D/src/Time/DateTimeExtensions.cs @@ -10,7 +10,11 @@ public static class DateTimeExtensions { /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Age(this DateTime value) { return value.Age(DateTime.Today); @@ -18,7 +22,11 @@ public static class DateTimeExtensions /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Age(this DateTime value, DateTime asOf) { return ((DateTimeOffset)value).Age(asOf); @@ -27,7 +35,11 @@ public static class DateTimeExtensions /// /// A representing the first occurence of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTime First(this DateTime value, DayOfWeek dayOfWeek) { return ((DateTimeOffset)value).First(dayOfWeek).DateTime; @@ -36,7 +48,11 @@ public static class DateTimeExtensions /// /// A representing the first day of the current month. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTime FirstDayOfMonth(this DateTime value) { return ((DateTimeOffset)value).FirstDayOfMonth().DateTime; @@ -51,7 +67,11 @@ public static class DateTimeExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this DateTime value) { return DateTime.IsLeapYear(value.Year); @@ -60,7 +80,11 @@ public static class DateTimeExtensions /// /// A representing the final occurence of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTime Last(this DateTime value, DayOfWeek dayOfWeek) { return ((DateTimeOffset)value).Last(dayOfWeek).DateTime; @@ -69,7 +93,11 @@ public static class DateTimeExtensions /// /// A representing the last day of the current month. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTime LastDayOfMonth(this DateTime value) { return ((DateTimeOffset)value).LastDayOfMonth().DateTime; @@ -78,7 +106,11 @@ public static class DateTimeExtensions /// /// A representing the next occurence of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTime Next(this DateTime value, DayOfWeek dayOfWeek) { return ((DateTimeOffset)value).Next(dayOfWeek).DateTime; @@ -90,7 +122,11 @@ public static class DateTimeExtensions /// The current date. /// The number of milliseconds that have elapsed since 1970-01-01T00:00:00.000Z. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long ToUnixTimeMilliseconds(this DateTime value) { return ((DateTimeOffset)value).ToUnixTimeMilliseconds(); @@ -102,7 +138,11 @@ public static class DateTimeExtensions /// The current date. /// The number of seconds that have elapsed since 1970-01-01T00:00:00.000Z. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static long ToUnixTimeSeconds(this DateTime value) { return ((DateTimeOffset)value).ToUnixTimeSeconds(); diff --git a/X10D/src/Time/DateTimeOffsetExtensions.cs b/X10D/src/Time/DateTimeOffsetExtensions.cs index ca06ec0..e30560b 100644 --- a/X10D/src/Time/DateTimeOffsetExtensions.cs +++ b/X10D/src/Time/DateTimeOffsetExtensions.cs @@ -14,7 +14,11 @@ public static class DateTimeOffsetExtensions /// The date from which to calculate. /// The rounded-down integer number of years since as of today. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Age(this DateTimeOffset value) { return value.Age(DateTime.Today); @@ -30,7 +34,11 @@ public static class DateTimeOffsetExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static int Age(this DateTimeOffset value, DateTimeOffset asOf) { return (int)(((asOf.Date - TimeSpan.FromDays(1) - value.Date).TotalDays + 1) / 365.2425); @@ -43,7 +51,11 @@ public static class DateTimeOffsetExtensions /// The day of the week. /// A representing the first occurence of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset First(this DateTimeOffset value, DayOfWeek dayOfWeek) { var first = value.FirstDayOfMonth(); @@ -62,7 +74,11 @@ public static class DateTimeOffsetExtensions /// The current date. /// A representing the first day of the current month. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FirstDayOfMonth(this DateTimeOffset value) { return value.AddDays(1 - value.Day); @@ -77,7 +93,11 @@ public static class DateTimeOffsetExtensions /// . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this DateTimeOffset value) { return DateTime.IsLeapYear(value.Year); @@ -90,7 +110,11 @@ public static class DateTimeOffsetExtensions /// The day of the week. /// A representing the final occurence of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset Last(this DateTimeOffset value, DayOfWeek dayOfWeek) { var last = value.LastDayOfMonth(); @@ -108,7 +132,11 @@ public static class DateTimeOffsetExtensions /// The current date. /// A representing the last day of the current month. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset LastDayOfMonth(this DateTimeOffset value) { int daysInMonth = DateTime.DaysInMonth(value.Year, value.Month); @@ -122,7 +150,11 @@ public static class DateTimeOffsetExtensions /// The day of the week. /// A representing the next occurence of . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset Next(this DateTimeOffset value, DayOfWeek dayOfWeek) { int offsetDays = dayOfWeek - value.DayOfWeek; diff --git a/X10D/src/Time/DecimalExtensions.cs b/X10D/src/Time/DecimalExtensions.cs index 880e1a9..ee1318f 100644 --- a/X10D/src/Time/DecimalExtensions.cs +++ b/X10D/src/Time/DecimalExtensions.cs @@ -16,7 +16,11 @@ public static class DecimalExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this decimal value) { return TimeSpan.FromMilliseconds((double)value); @@ -30,7 +34,11 @@ public static class DecimalExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this decimal value) { return TimeSpan.FromSeconds((double)value); @@ -44,7 +52,11 @@ public static class DecimalExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this decimal value) { return TimeSpan.FromMinutes((double)value); @@ -58,7 +70,11 @@ public static class DecimalExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this decimal value) { return TimeSpan.FromHours((double)value); @@ -70,7 +86,11 @@ public static class DecimalExtensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this decimal value) { return TimeSpan.FromDays((double)value); @@ -84,7 +104,11 @@ public static class DecimalExtensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this decimal value) { return TimeSpan.FromDays((double)value * 7); diff --git a/X10D/src/Time/DoubleExtensions.cs b/X10D/src/Time/DoubleExtensions.cs index 81d6b38..6b16e76 100644 --- a/X10D/src/Time/DoubleExtensions.cs +++ b/X10D/src/Time/DoubleExtensions.cs @@ -16,7 +16,11 @@ public static class DoubleExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this double value) { return TimeSpan.FromMilliseconds(value); @@ -30,7 +34,11 @@ public static class DoubleExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this double value) { return TimeSpan.FromSeconds(value); @@ -44,7 +52,11 @@ public static class DoubleExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this double value) { return TimeSpan.FromMinutes(value); @@ -58,7 +70,11 @@ public static class DoubleExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this double value) { return TimeSpan.FromHours(value); @@ -70,7 +86,11 @@ public static class DoubleExtensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this double value) { return TimeSpan.FromDays(value); @@ -84,7 +104,11 @@ public static class DoubleExtensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this double value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/HalfExtensions.cs b/X10D/src/Time/HalfExtensions.cs index 396fc68..e217ea9 100644 --- a/X10D/src/Time/HalfExtensions.cs +++ b/X10D/src/Time/HalfExtensions.cs @@ -1,4 +1,5 @@ -using System.Diagnostics.Contracts; +#if NET5_0_OR_GREATER +using System.Diagnostics.Contracts; using System.Runtime.CompilerServices; namespace X10D.Time; @@ -90,3 +91,4 @@ public static class HalfExtensions return TimeSpan.FromDays((float)value * 7); } } +#endif diff --git a/X10D/src/Time/Int16Extensions.cs b/X10D/src/Time/Int16Extensions.cs index bfc1605..a0fbb7d 100644 --- a/X10D/src/Time/Int16Extensions.cs +++ b/X10D/src/Time/Int16Extensions.cs @@ -18,7 +18,11 @@ public static class Int16Extensions /// /// is 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this short value) { if (value == 0) @@ -49,7 +53,11 @@ public static class Int16Extensions /// is greater than 253,402,300,799,999. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeMilliseconds(this short value) { return DateTimeOffset.FromUnixTimeMilliseconds(value); @@ -70,7 +78,11 @@ public static class Int16Extensions /// is greater than 253,402,300,799. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeSeconds(this short value) { return DateTimeOffset.FromUnixTimeSeconds(value); @@ -82,7 +94,11 @@ public static class Int16Extensions /// The duration, in ticks. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Ticks(this short value) { return TimeSpan.FromTicks(value); @@ -96,7 +112,11 @@ public static class Int16Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this short value) { return TimeSpan.FromMilliseconds(value); @@ -110,7 +130,11 @@ public static class Int16Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this short value) { return TimeSpan.FromSeconds(value); @@ -124,7 +148,11 @@ public static class Int16Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this short value) { return TimeSpan.FromMinutes(value); @@ -138,7 +166,11 @@ public static class Int16Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this short value) { return TimeSpan.FromHours(value); @@ -150,7 +182,11 @@ public static class Int16Extensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this short value) { return TimeSpan.FromDays(value); @@ -164,7 +200,11 @@ public static class Int16Extensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this short value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/Int32Extensions.cs b/X10D/src/Time/Int32Extensions.cs index 576f84f..6811b82 100644 --- a/X10D/src/Time/Int32Extensions.cs +++ b/X10D/src/Time/Int32Extensions.cs @@ -18,7 +18,11 @@ public static class Int32Extensions /// /// is 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this int value) { if (value == 0) @@ -49,7 +53,11 @@ public static class Int32Extensions /// is greater than 253,402,300,799,999. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeMilliseconds(this int value) { return DateTimeOffset.FromUnixTimeMilliseconds(value); @@ -70,7 +78,11 @@ public static class Int32Extensions /// is greater than 253,402,300,799. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeSeconds(this int value) { return DateTimeOffset.FromUnixTimeSeconds(value); @@ -82,7 +94,11 @@ public static class Int32Extensions /// The duration, in ticks. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Ticks(this int value) { return TimeSpan.FromTicks(value); @@ -96,7 +112,11 @@ public static class Int32Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this int value) { return TimeSpan.FromMilliseconds(value); @@ -110,7 +130,11 @@ public static class Int32Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this int value) { return TimeSpan.FromSeconds(value); @@ -124,7 +148,11 @@ public static class Int32Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this int value) { return TimeSpan.FromMinutes(value); @@ -138,7 +166,11 @@ public static class Int32Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this int value) { return TimeSpan.FromHours(value); @@ -150,7 +182,11 @@ public static class Int32Extensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this int value) { return TimeSpan.FromDays(value); @@ -164,7 +200,11 @@ public static class Int32Extensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this int value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/Int64Extensions.cs b/X10D/src/Time/Int64Extensions.cs index f07969c..8f6ea07 100644 --- a/X10D/src/Time/Int64Extensions.cs +++ b/X10D/src/Time/Int64Extensions.cs @@ -18,7 +18,11 @@ public static class Int64Extensions /// /// is 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this long value) { if (value == 0) @@ -49,7 +53,11 @@ public static class Int64Extensions /// is greater than 253,402,300,799,999. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeMilliseconds(this long value) { return DateTimeOffset.FromUnixTimeMilliseconds(value); @@ -70,7 +78,11 @@ public static class Int64Extensions /// is greater than 253,402,300,799. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeSeconds(this long value) { return DateTimeOffset.FromUnixTimeSeconds(value); @@ -82,7 +94,11 @@ public static class Int64Extensions /// The duration, in ticks. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Ticks(this long value) { return TimeSpan.FromTicks(value); @@ -96,7 +112,11 @@ public static class Int64Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this long value) { return TimeSpan.FromMilliseconds(value); @@ -110,7 +130,11 @@ public static class Int64Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this long value) { return TimeSpan.FromSeconds(value); @@ -124,7 +148,11 @@ public static class Int64Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this long value) { return TimeSpan.FromMinutes(value); @@ -138,7 +166,11 @@ public static class Int64Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this long value) { return TimeSpan.FromHours(value); @@ -150,7 +182,11 @@ public static class Int64Extensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this long value) { return TimeSpan.FromDays(value); @@ -164,7 +200,11 @@ public static class Int64Extensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this long value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/SByteExtensions.cs b/X10D/src/Time/SByteExtensions.cs index 606df12..926c894 100644 --- a/X10D/src/Time/SByteExtensions.cs +++ b/X10D/src/Time/SByteExtensions.cs @@ -19,7 +19,11 @@ public static class SByteExtensions /// /// is 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this sbyte value) { if (value == 0) @@ -50,7 +54,11 @@ public static class SByteExtensions /// is greater than 253,402,300,799,999. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeMilliseconds(this sbyte value) { return DateTimeOffset.FromUnixTimeMilliseconds(value); @@ -71,7 +79,11 @@ public static class SByteExtensions /// is greater than 253,402,300,799. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeSeconds(this sbyte value) { return DateTimeOffset.FromUnixTimeSeconds(value); @@ -83,7 +95,11 @@ public static class SByteExtensions /// The duration, in ticks. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Ticks(this sbyte value) { return TimeSpan.FromTicks(value); @@ -97,7 +113,11 @@ public static class SByteExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this sbyte value) { return TimeSpan.FromMilliseconds(value); @@ -111,7 +131,11 @@ public static class SByteExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this sbyte value) { return TimeSpan.FromSeconds(value); @@ -125,7 +149,11 @@ public static class SByteExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this sbyte value) { return TimeSpan.FromMinutes(value); @@ -139,7 +167,11 @@ public static class SByteExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this sbyte value) { return TimeSpan.FromHours(value); @@ -151,7 +183,11 @@ public static class SByteExtensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this sbyte value) { return TimeSpan.FromDays(value); @@ -165,7 +201,11 @@ public static class SByteExtensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this sbyte value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/SingleExtensions.cs b/X10D/src/Time/SingleExtensions.cs index f1d0546..f3e546c 100644 --- a/X10D/src/Time/SingleExtensions.cs +++ b/X10D/src/Time/SingleExtensions.cs @@ -16,7 +16,11 @@ public static class SingleExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this float value) { return TimeSpan.FromMilliseconds(value); @@ -30,7 +34,11 @@ public static class SingleExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this float value) { return TimeSpan.FromSeconds(value); @@ -44,7 +52,11 @@ public static class SingleExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this float value) { return TimeSpan.FromMinutes(value); @@ -58,7 +70,11 @@ public static class SingleExtensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this float value) { return TimeSpan.FromHours(value); @@ -70,7 +86,11 @@ public static class SingleExtensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this float value) { return TimeSpan.FromDays(value); @@ -84,7 +104,11 @@ public static class SingleExtensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this float value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/StringExtensions.cs b/X10D/src/Time/StringExtensions.cs index cf22f71..ea3eb77 100644 --- a/X10D/src/Time/StringExtensions.cs +++ b/X10D/src/Time/StringExtensions.cs @@ -57,7 +57,11 @@ public static class StringExtensions /// A new instance of . /// is . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan ToTimeSpan(this string input) { if (input is null) diff --git a/X10D/src/Time/TimeSpanExtensions.cs b/X10D/src/Time/TimeSpanExtensions.cs index d9424f1..1e3a500 100644 --- a/X10D/src/Time/TimeSpanExtensions.cs +++ b/X10D/src/Time/TimeSpanExtensions.cs @@ -16,7 +16,11 @@ public static class TimeSpanExtensions /// A that is a duration of in the past relative to the current time. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTime Ago(this TimeSpan value) { return DateTime.Now.Subtract(value); @@ -30,7 +34,11 @@ public static class TimeSpanExtensions /// A that is a duration of in the future relative to the current time. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTime FromNow(this TimeSpan value) { return DateTime.Now.Add(value); diff --git a/X10D/src/Time/UInt16Extensions.cs b/X10D/src/Time/UInt16Extensions.cs index b0ee2c9..d8eec67 100644 --- a/X10D/src/Time/UInt16Extensions.cs +++ b/X10D/src/Time/UInt16Extensions.cs @@ -24,7 +24,11 @@ public static class UInt16Extensions /// is greater than 253,402,300,799,999. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeMilliseconds(this ushort value) { return DateTimeOffset.FromUnixTimeMilliseconds(value); @@ -45,7 +49,11 @@ public static class UInt16Extensions /// is greater than 253,402,300,799. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeSeconds(this ushort value) { return DateTimeOffset.FromUnixTimeSeconds(value); @@ -60,7 +68,11 @@ public static class UInt16Extensions /// /// is 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this ushort value) { if (value == 0) @@ -77,7 +89,11 @@ public static class UInt16Extensions /// The duration, in ticks. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Ticks(this ushort value) { return TimeSpan.FromTicks(value); @@ -91,7 +107,11 @@ public static class UInt16Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this ushort value) { return TimeSpan.FromMilliseconds(value); @@ -105,7 +125,11 @@ public static class UInt16Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this ushort value) { return TimeSpan.FromSeconds(value); @@ -119,7 +143,11 @@ public static class UInt16Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this ushort value) { return TimeSpan.FromMinutes(value); @@ -133,7 +161,11 @@ public static class UInt16Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this ushort value) { return TimeSpan.FromHours(value); @@ -145,7 +177,11 @@ public static class UInt16Extensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this ushort value) { return TimeSpan.FromDays(value); @@ -159,7 +195,11 @@ public static class UInt16Extensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this ushort value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/UInt32Extensions.cs b/X10D/src/Time/UInt32Extensions.cs index 9a4b09f..2f6fb81 100644 --- a/X10D/src/Time/UInt32Extensions.cs +++ b/X10D/src/Time/UInt32Extensions.cs @@ -24,7 +24,11 @@ public static class UInt32Extensions /// is greater than 253,402,300,799,999. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeMilliseconds(this uint value) { return DateTimeOffset.FromUnixTimeMilliseconds(value); @@ -45,7 +49,11 @@ public static class UInt32Extensions /// is greater than 253,402,300,799. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeSeconds(this uint value) { return DateTimeOffset.FromUnixTimeSeconds(value); @@ -60,7 +68,11 @@ public static class UInt32Extensions /// /// is 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this uint value) { if (value == 0) @@ -77,7 +89,11 @@ public static class UInt32Extensions /// The duration, in ticks. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Ticks(this uint value) { return TimeSpan.FromTicks(value); @@ -91,7 +107,11 @@ public static class UInt32Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this uint value) { return TimeSpan.FromMilliseconds(value); @@ -105,7 +125,11 @@ public static class UInt32Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this uint value) { return TimeSpan.FromSeconds(value); @@ -119,7 +143,11 @@ public static class UInt32Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this uint value) { return TimeSpan.FromMinutes(value); @@ -133,7 +161,11 @@ public static class UInt32Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this uint value) { return TimeSpan.FromHours(value); @@ -145,7 +177,11 @@ public static class UInt32Extensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this uint value) { return TimeSpan.FromDays(value); @@ -159,7 +195,11 @@ public static class UInt32Extensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this uint value) { return TimeSpan.FromDays(value * 7); diff --git a/X10D/src/Time/UInt64Extensions.cs b/X10D/src/Time/UInt64Extensions.cs index 2dfb049..d415cbb 100644 --- a/X10D/src/Time/UInt64Extensions.cs +++ b/X10D/src/Time/UInt64Extensions.cs @@ -24,7 +24,11 @@ public static class UInt64Extensions /// is greater than 253,402,300,799,999. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeMilliseconds(this ulong value) { return DateTimeOffset.FromUnixTimeMilliseconds((long)value); @@ -45,7 +49,11 @@ public static class UInt64Extensions /// is greater than 253,402,300,799. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static DateTimeOffset FromUnixTimeSeconds(this ulong value) { return DateTimeOffset.FromUnixTimeSeconds((long)value); @@ -60,7 +68,11 @@ public static class UInt64Extensions /// /// is 0. [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static bool IsLeapYear(this ulong value) { if (value == 0) @@ -77,7 +89,11 @@ public static class UInt64Extensions /// The duration, in ticks. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Ticks(this ulong value) { return TimeSpan.FromTicks((long)value); @@ -91,7 +107,11 @@ public static class UInt64Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Milliseconds(this ulong value) { return TimeSpan.FromMilliseconds((long)value); @@ -105,7 +125,11 @@ public static class UInt64Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Seconds(this ulong value) { return TimeSpan.FromSeconds((long)value); @@ -119,7 +143,11 @@ public static class UInt64Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Minutes(this ulong value) { return TimeSpan.FromMinutes((long)value); @@ -133,7 +161,11 @@ public static class UInt64Extensions /// A whose will equal . /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Hours(this ulong value) { return TimeSpan.FromHours((long)value); @@ -145,7 +177,11 @@ public static class UInt64Extensions /// The duration, in days. /// A whose will equal . [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Days(this ulong value) { return TimeSpan.FromDays((long)value); @@ -159,7 +195,11 @@ public static class UInt64Extensions /// A whose will equal × 7. /// [Pure] +#if NETSTANDARD2_1 + [MethodImpl(MethodImplOptions.AggressiveInlining)] +#else [MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)] +#endif public static TimeSpan Weeks(this ulong value) { return TimeSpan.FromDays((long)value * 7);