diff --git a/Packages/ZLinq.Unity/Runtime.meta b/Packages/ZLinq.Unity/Runtime.meta new file mode 100644 index 0000000..dafaed3 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 7d73a4bba9206aa4da45149e38ba2ff5 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/External.meta b/Packages/ZLinq.Unity/Runtime/External.meta new file mode 100644 index 0000000..a03f66b --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/External.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: b8779dfc80070d04097029c66298253a +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/External/UnityCollections.meta b/Packages/ZLinq.Unity/Runtime/External/UnityCollections.meta new file mode 100644 index 0000000..5642456 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/External/UnityCollections.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 1318fb368be93d3438af62a7cafca0a2 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/External/UnityCollections/UnityCollectionsExtensions.cs b/Packages/ZLinq.Unity/Runtime/External/UnityCollections/UnityCollectionsExtensions.cs new file mode 100644 index 0000000..f975adf --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/External/UnityCollections/UnityCollectionsExtensions.cs @@ -0,0 +1,783 @@ +#if ZLINQ_UNITY_COLLECTIONS_SUPPORT + +#pragma warning disable CS9074 +#nullable enable + +using System; +using System.ComponentModel; +using System.Runtime.InteropServices; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using ZLinq.Internal; +using ZLinq.Linq; + +namespace ZLinq +{ + public static class UnityCollectionsExtensions + { + public static ValueEnumerable, T> AsValueEnumerable(this NativeList source) + where T : unmanaged + { + return new(new(source)); + } + + public static ValueEnumerable, T> AsValueEnumerable(this NativeQueue.ReadOnly source) + where T : unmanaged + { + return new(new(source)); + } + + public static ValueEnumerable, T> AsValueEnumerable(this NativeHashSet source) + where T : unmanaged, IEquatable + { + return new(new(source.AsReadOnly())); + } + + public static ValueEnumerable, T> AsValueEnumerable(this NativeHashSet.ReadOnly source) + where T : unmanaged, IEquatable + { + return new(new(source)); + } + + public static ValueEnumerable, KVPair> AsValueEnumerable(this NativeHashMap source) + where TKey : unmanaged, IEquatable + where TValue : unmanaged + { + return new(new(source.AsReadOnly())); + } + + public static ValueEnumerable, KVPair> AsValueEnumerable(this NativeHashMap.ReadOnly source) + where TKey : unmanaged, IEquatable + where TValue : unmanaged + { + return new(new(source)); + } + + public static ValueEnumerable AsValueEnumerable(this NativeText source) + { + return new(new(source.AsReadOnly())); + } + + public static ValueEnumerable AsValueEnumerable(this NativeText.ReadOnly source) + { + return new(new(source)); + } + + public static ValueEnumerable, T> AsValueEnumerable(this FixedList32Bytes source) + where T : unmanaged + { + return new(new(source)); + } + + public static ValueEnumerable, T> AsValueEnumerable(this FixedList64Bytes source) + where T : unmanaged + { + return new(new(source)); + } + + public static ValueEnumerable, T> AsValueEnumerable(this FixedList128Bytes source) + where T : unmanaged + { + return new(new(source)); + } + + public static ValueEnumerable, T> AsValueEnumerable(this FixedList512Bytes source) + where T : unmanaged + { + return new(new(source)); + } + + public static ValueEnumerable, T> AsValueEnumerable(this FixedList4096Bytes source) + where T : unmanaged + { + return new(new(source)); + } + + public static ValueEnumerable AsValueEnumerable(this FixedString32Bytes source) + { + return new(new(source)); + } + + public static ValueEnumerable AsValueEnumerable(this FixedString64Bytes source) + { + return new(new(source)); + } + + public static ValueEnumerable AsValueEnumerable(this FixedString128Bytes source) + { + return new(new(source)); + } + + public static ValueEnumerable AsValueEnumerable(this FixedString512Bytes source) + { + return new(new(source)); + } + + public static ValueEnumerable AsValueEnumerable(this FixedString4096Bytes source) + { + return new(new(source)); + } + } +} + +namespace ZLinq.Linq +{ + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromNativeList : IValueEnumerator + where T : unmanaged + { + NativeList source; + int index; + + public FromNativeList(NativeList source) + { + this.source = source; + this.index = 0; + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) + { + if (EnumeratorHelper.TryGetSlice(new ReadOnlySpan(source.GetUnsafePtr(), source.Length), offset, destination.Length, out var slice)) + { + slice.CopyTo(destination); + return true; + } + return false; + } + + public bool TryGetNext(out T current) + { + if ((uint)index < (uint)source.Length) + { + current = source[index++]; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Length; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = new ReadOnlySpan(source.GetUnsafePtr(), source.Length); + return true; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromNativeQueue : IValueEnumerator + where T : unmanaged + { + NativeQueue.ReadOnly source; + NativeQueue.Enumerator enumerator; + + public FromNativeQueue(NativeQueue.ReadOnly source) + { + this.source = source; + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out T current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Count; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromNativeHashSet : IValueEnumerator + where T : unmanaged, IEquatable + { + NativeHashSet.ReadOnly source; + NativeHashSet.Enumerator enumerator; + + public FromNativeHashSet(NativeHashSet.ReadOnly source) + { + this.source = source; + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out T current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Count; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromNativeHashMap : IValueEnumerator> + where TKey : unmanaged, IEquatable + where TValue : unmanaged + { + NativeHashMap.ReadOnly source; + NativeHashMap.Enumerator enumerator; + + public FromNativeHashMap(NativeHashMap.ReadOnly source) + { + this.source = source; + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span> destination, Index offset) => false; + + public bool TryGetNext(out KVPair current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Count; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan> span) + { + span = default; + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromNativeText : IValueEnumerator + { + NativeText.Enumerator enumerator; + + public FromNativeText(NativeText.ReadOnly source) + { + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out Unicode.Rune current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = default; + return false; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + public struct FromFixedList32Bytes : IValueEnumerator + where T : unmanaged + { + FixedList32Bytes source; + int index; + + public FromFixedList32Bytes(FixedList32Bytes source) + { + this.source = source; + this.index = 0; + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out T current) + { + if ((uint)index < (uint)source.Length) + { + current = source[index++]; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Length; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + public struct FromFixedList64Bytes : IValueEnumerator + where T : unmanaged + { + FixedList64Bytes source; + int index; + + public FromFixedList64Bytes(FixedList64Bytes source) + { + this.source = source; + this.index = 0; + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out T current) + { + if ((uint)index < (uint)source.Length) + { + current = source[index++]; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Length; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + public struct FromFixedList128Bytes : IValueEnumerator + where T : unmanaged + { + FixedList128Bytes source; + int index; + + public FromFixedList128Bytes(FixedList128Bytes source) + { + this.source = source; + this.index = 0; + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out T current) + { + if ((uint)index < (uint)source.Length) + { + current = source[index++]; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Length; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + public struct FromFixedList512Bytes : IValueEnumerator + where T : unmanaged + { + FixedList512Bytes source; + int index; + + public FromFixedList512Bytes(FixedList512Bytes source) + { + this.source = source; + this.index = 0; + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out T current) + { + if ((uint)index < (uint)source.Length) + { + current = source[index++]; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Length; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + public struct FromFixedList4096Bytes : IValueEnumerator + where T : unmanaged + { + FixedList4096Bytes source; + int index; + + public FromFixedList4096Bytes(FixedList4096Bytes source) + { + this.source = source; + this.index = 0; + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out T current) + { + if ((uint)index < (uint)source.Length) + { + current = source[index++]; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Length; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromFixedString32Bytes : IValueEnumerator + { + FixedString32Bytes.Enumerator enumerator; + + public FromFixedString32Bytes(FixedString32Bytes source) + { + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out Unicode.Rune current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = default; + return false; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromFixedString64Bytes : IValueEnumerator + { + FixedString64Bytes.Enumerator enumerator; + + public FromFixedString64Bytes(FixedString64Bytes source) + { + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out Unicode.Rune current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = default; + return false; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromFixedString128Bytes : IValueEnumerator + { + FixedString128Bytes.Enumerator enumerator; + + public FromFixedString128Bytes(FixedString128Bytes source) + { + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out Unicode.Rune current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = default; + return false; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromFixedString512Bytes : IValueEnumerator + { + FixedString512Bytes.Enumerator enumerator; + + public FromFixedString512Bytes(FixedString512Bytes source) + { + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out Unicode.Rune current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = default; + return false; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + [EditorBrowsable(EditorBrowsableState.Never)] + public struct FromFixedString4096Bytes : IValueEnumerator + { + FixedString4096Bytes.Enumerator enumerator; + + public FromFixedString4096Bytes(FixedString4096Bytes source) + { + this.enumerator = source.GetEnumerator(); + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) => false; + + public bool TryGetNext(out Unicode.Rune current) + { + if (enumerator.MoveNext()) + { + current = enumerator.Current; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = default; + return false; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + } +} + +#pragma warning restore CS9074 +#endif diff --git a/Packages/ZLinq.Unity/Runtime/External/UnityCollections/UnityCollectionsExtensions.cs.meta b/Packages/ZLinq.Unity/Runtime/External/UnityCollections/UnityCollectionsExtensions.cs.meta new file mode 100644 index 0000000..9c3cf8a --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/External/UnityCollections/UnityCollectionsExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: a9c42c82467624146b57ea3cd9602a24 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/External/UnityCollections/ZLinq.Unity.UnityCollections.asmdef b/Packages/ZLinq.Unity/Runtime/External/UnityCollections/ZLinq.Unity.UnityCollections.asmdef new file mode 100644 index 0000000..ba339ba --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/External/UnityCollections/ZLinq.Unity.UnityCollections.asmdef @@ -0,0 +1,24 @@ +{ + "name": "ZLinq.Unity.UnityCollectoins", + "rootNamespace": "ZLinq", + "references": [ + "Unity.Collections" + ], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": true, + "precompiledReferences": [ + "ZLinq.dll" + ], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.collections", + "expression": "2.1.1", + "define": "ZLINQ_UNITY_COLLECTIONS_SUPPORT" + } + ], + "noEngineReferences": false +} diff --git a/Packages/ZLinq.Unity/Runtime/External/UnityCollections/ZLinq.Unity.UnityCollections.asmdef.meta b/Packages/ZLinq.Unity/Runtime/External/UnityCollections/ZLinq.Unity.UnityCollections.asmdef.meta new file mode 100644 index 0000000..a26d8b3 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/External/UnityCollections/ZLinq.Unity.UnityCollections.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dd45bb705edc4cf47acd3a4ae20a9e23 +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/GameObjectTraverser.cs b/Packages/ZLinq.Unity/Runtime/GameObjectTraverser.cs new file mode 100644 index 0000000..366f945 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/GameObjectTraverser.cs @@ -0,0 +1,248 @@ +#nullable enable + +using System.Runtime.InteropServices; +using UnityEngine; +using ZLinq.Traversables; + +namespace ZLinq +{ + public static class GameObjectTraverserExtensions + { + public static GameObjectTraverser AsTraverser(this GameObject origin) => new(origin); + + // type inference helper + + public static ValueEnumerable, GameObject> Children(this GameObjectTraverser traverser) => traverser.Children(); + public static ValueEnumerable, GameObject> ChildrenAndSelf(this GameObjectTraverser traverser) => traverser.ChildrenAndSelf(); + public static ValueEnumerable, GameObject> Descendants(this GameObjectTraverser traverser) => traverser.Descendants(); + public static ValueEnumerable, GameObject> DescendantsAndSelf(this GameObjectTraverser traverser) => traverser.DescendantsAndSelf(); + public static ValueEnumerable, GameObject> Ancestors(this GameObjectTraverser traverser) => traverser.Ancestors(); + public static ValueEnumerable, GameObject> AncestorsAndSelf(this GameObjectTraverser traverser) => traverser.AncestorsAndSelf(); + public static ValueEnumerable, GameObject> BeforeSelf(this GameObjectTraverser traverser) => traverser.BeforeSelf(); + public static ValueEnumerable, GameObject> BeforeSelfAndSelf(this GameObjectTraverser traverser) => traverser.BeforeSelfAndSelf(); + public static ValueEnumerable, GameObject> AfterSelf(this GameObjectTraverser traverser) => traverser.AfterSelf(); + public static ValueEnumerable, GameObject> AfterSelfAndSelf(this GameObjectTraverser traverser) => traverser.AfterSelfAndSelf(); + + // direct shortcut + + public static ValueEnumerable, GameObject> Children(this GameObject origin) => origin.AsTraverser().Children(); + public static ValueEnumerable, GameObject> ChildrenAndSelf(this GameObject origin) => origin.AsTraverser().ChildrenAndSelf(); + public static ValueEnumerable, GameObject> Descendants(this GameObject origin) => origin.AsTraverser().Descendants(); + public static ValueEnumerable, GameObject> DescendantsAndSelf(this GameObject origin) => origin.AsTraverser().DescendantsAndSelf(); + public static ValueEnumerable, GameObject> Ancestors(this GameObject origin) => origin.AsTraverser().Ancestors(); + public static ValueEnumerable, GameObject> AncestorsAndSelf(this GameObject origin) => origin.AsTraverser().AncestorsAndSelf(); + public static ValueEnumerable, GameObject> BeforeSelf(this GameObject origin) => origin.AsTraverser().BeforeSelf(); + public static ValueEnumerable, GameObject> BeforeSelfAndSelf(this GameObject origin) => origin.AsTraverser().BeforeSelfAndSelf(); + public static ValueEnumerable, GameObject> AfterSelf(this GameObject origin) => origin.AsTraverser().AfterSelf(); + public static ValueEnumerable, GameObject> AfterSelfAndSelf(this GameObject origin) => origin.AsTraverser().AfterSelfAndSelf(); + + // OfComponent + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, GameObject> source) + where TComponent : Component => new(new(source.Enumerator)); + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, GameObject> source) + where TComponent : Component => new(new(source.Enumerator)); + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, GameObject> source) + where TComponent : Component => new(new(source.Enumerator)); + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, GameObject> source) + where TComponent : Component => new(new(source.Enumerator)); + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, GameObject> source) + where TComponent : Component => new(new(source.Enumerator)); + } + + [StructLayout(LayoutKind.Auto)] + public struct GameObjectTraverser : ITraverser + { + static readonly object CalledTryGetNextChild = new object(); + static readonly object ParentNotFound = new object(); + + readonly GameObject gameObject; + readonly Transform transform; // cache transform + object? initializedState; // CalledTryGetNext or Parent(for sibling operations) + int childCount; // self childCount(TryGetNextChild) or parent childCount(TryGetSibling) + int index; + + public GameObjectTraverser(GameObject origin) + { + this.gameObject = origin; + this.transform = gameObject.transform; + this.initializedState = null; + this.childCount = 0; + this.index = 0; + } + + public GameObject Origin => gameObject; + public GameObjectTraverser ConvertToTraverser(GameObject next) => new(next); + + public bool TryGetParent(out GameObject parent) + { + var tp = transform.parent; + if (tp != null) + { + parent = tp.gameObject; + return true; + } + + parent = default!; + return false; + } + + public bool TryGetChildCount(out int count) + { + count = transform.childCount; + return true; + } + + public bool TryGetHasChild(out bool hasChild) + { + hasChild = transform.childCount != 0; + return true; + } + + public bool TryGetNextChild(out GameObject child) + { + if (initializedState == null) + { + initializedState = CalledTryGetNextChild; + childCount = transform.childCount; + } + + if (index < childCount) + { + child = transform.GetChild(index++).gameObject; + return true; + } + + child = default!; + return false; + } + + public bool TryGetNextSibling(out GameObject next) + { + if (initializedState == null) + { + var tp = transform.parent; + if (tp == null) + { + var scene = transform.gameObject.scene; + // check is scene root object + if (scene.IsValid()) + { + initializedState = scene; + childCount = scene.rootCount; + index = transform.GetSiblingIndex() + 1; + } + else + { + initializedState = ParentNotFound; + next = default!; + return false; + } + } + else + { + // cache parent and childCount + initializedState = tp; + childCount = tp.childCount; // parent's childCount + index = transform.GetSiblingIndex() + 1; + } + } + else if (initializedState == ParentNotFound) + { + next = default!; + return false; + } + + if (initializedState is Transform parent) + { + if (index < childCount) + { + next = parent.GetChild(index++).gameObject; + return true; + } + } + else if (initializedState is UnityEngine.SceneManagement.Scene scene) + { + if (index < childCount) + { + var list = UnityEngine.Pool.ListPool.Get(); + scene.GetRootGameObjects(list); + next = list[index++]; + UnityEngine.Pool.ListPool.Release(list); + return true; + } + } + + + next = default!; + return false; + } + + public bool TryGetPreviousSibling(out GameObject previous) + { + if (initializedState == null) + { + var tp = transform.parent; + if (tp == null) + { + var scene = transform.gameObject.scene; + // check is scene root object + if (scene.IsValid()) + { + initializedState = scene; + childCount = transform.GetSiblingIndex(); + index = 0; + } + else + { + initializedState = ParentNotFound; + previous = default!; + return false; + } + } + else + { + initializedState = tp; + childCount = transform.GetSiblingIndex(); // not childCount but means `to` + index = 0; // 0 to siblingIndex + } + } + else if (initializedState == ParentNotFound) + { + previous = default!; + return false; + } + + if (initializedState is Transform parent) + { + if (index < childCount) + { + previous = parent.GetChild(index++).gameObject; + return true; + } + } + else if (initializedState is UnityEngine.SceneManagement.Scene scene) + { + if (index < childCount) + { + var list = UnityEngine.Pool.ListPool.Get(); + scene.GetRootGameObjects(list); + previous = list[index++]; + UnityEngine.Pool.ListPool.Release(list); + return true; + } + } + + previous = default!; + return false; + } + + public void Dispose() + { + } + } +} diff --git a/Packages/ZLinq.Unity/Runtime/GameObjectTraverser.cs.meta b/Packages/ZLinq.Unity/Runtime/GameObjectTraverser.cs.meta new file mode 100644 index 0000000..0910cd8 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/GameObjectTraverser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d7b9e09717ffc984e9c34ed6493db8a3 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/NativeArrayExtensions.cs b/Packages/ZLinq.Unity/Runtime/NativeArrayExtensions.cs new file mode 100644 index 0000000..37c24cb --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/NativeArrayExtensions.cs @@ -0,0 +1,161 @@ +#pragma warning disable CS9074 +#nullable enable + +using System; +using System.Runtime.InteropServices; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using ZLinq.Internal; +using ZLinq.Linq; + +namespace ZLinq +{ + public static class NativeArrayExtensions + { + public static ValueEnumerable, T> AsValueEnumerable(this NativeArray source) + where T : struct + { + return new(new(source.AsReadOnly())); + } + + public static ValueEnumerable, T> AsValueEnumerable(this NativeArray.ReadOnly source) + where T : struct + { + return new(new(source)); + } + + public static ValueEnumerable, T> AsValueEnumerable(this NativeSlice source) + where T : struct + { + return new(new(source)); + } + } +} + +namespace ZLinq.Linq +{ + [StructLayout(LayoutKind.Auto)] + public struct FromNativeArray : IValueEnumerator + where T : struct + { + public FromNativeArray(NativeArray.ReadOnly source) + { + this.source = source; + this.index = 0; + } + + NativeArray.ReadOnly source; + int index; + + public void Dispose() + { + } + + public bool TryCopyTo(Span destination, Index offset) + { +#if UNITY_2022_1_OR_NEWER + if (EnumeratorHelper.TryGetSlice(source, offset, destination.Length, out var slice)) + { + slice.CopyTo(destination); + return true; + } +#else + unsafe + { + if (EnumeratorHelper.TryGetSlice(new ReadOnlySpan(source.GetUnsafeReadOnlyPtr(), source.Length), offset, destination.Length, out var slice)) + { + slice.CopyTo(destination); + return true; + } + } +#endif + return false; + } + + public bool TryGetNext(out T current) + { + if ((uint)index < (uint)source.Length) + { + current = source[index++]; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Length; + return true; + } + + public bool TryGetSpan(out ReadOnlySpan span) + { +#if UNITY_2022_1_OR_NEWER + span = source; + return true; +#else + unsafe + { + span = new ReadOnlySpan(source.GetUnsafeReadOnlyPtr(), source.Length); + } + return true; +#endif + } + } + + [StructLayout(LayoutKind.Auto)] + public struct FromNativeSlice : IValueEnumerator + where T : struct + { + NativeSlice source; + int index; + + public FromNativeSlice(NativeSlice source) + { + this.source = source; + this.index = 0; + } + + public void Dispose() + { + } + + public unsafe bool TryCopyTo(Span destination, Index offset) + { + if (EnumeratorHelper.TryGetSlice(new ReadOnlySpan(source.GetUnsafePtr(), source.Length), offset, destination.Length, out var slice)) + { + slice.CopyTo(destination); + return true; + } + return false; + } + + public bool TryGetNext(out T current) + { + if ((uint)index < (uint)source.Length) + { + current = source[index++]; + return true; + } + + current = default!; + return false; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = source.Length; + return true; + } + + public unsafe bool TryGetSpan(out ReadOnlySpan span) + { + span = new ReadOnlySpan(source.GetUnsafePtr(), source.Length); + return true; + } + } +} + +#pragma warning restore CS9074 diff --git a/Packages/ZLinq.Unity/Runtime/NativeArrayExtensions.cs.meta b/Packages/ZLinq.Unity/Runtime/NativeArrayExtensions.cs.meta new file mode 100644 index 0000000..91863f0 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/NativeArrayExtensions.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 35026e77d3aeba64f8b30ecd6e38f184 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/OfComponent.cs b/Packages/ZLinq.Unity/Runtime/OfComponent.cs new file mode 100644 index 0000000..98e6d3b --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/OfComponent.cs @@ -0,0 +1,110 @@ +#nullable enable + +using System; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace ZLinq +{ + [StructLayout(LayoutKind.Auto)] + public struct OfComponentT : IValueEnumerator + where TEnumerable : struct, IValueEnumerator + where TComponent : Component + { + TEnumerable source; + + internal OfComponentT(TEnumerable source) + { + this.source = source; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = 0; + return false; + } + + public bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + + public bool TryGetNext(out TComponent current) + { + while (source.TryGetNext(out var value)) + { + var component = value.GetComponent(); + if (component != null) + { + current = component; + return true; + } + } + + current = default!; + return false; + } + + public void Dispose() + { + source.Dispose(); + } + + public bool TryCopyTo(Span destination, Index offset) + { + return false; + } + } + + [StructLayout(LayoutKind.Auto)] + public struct OfComponentG : IValueEnumerator + where TEnumerable : struct, IValueEnumerator + where TComponent : Component + { + TEnumerable source; + + internal OfComponentG(TEnumerable source) + { + this.source = source; + } + + public bool TryGetNonEnumeratedCount(out int count) + { + count = 0; + return false; + } + + public bool TryGetSpan(out ReadOnlySpan span) + { + span = default; + return false; + } + + public bool TryGetNext(out TComponent current) + { + while (source.TryGetNext(out var value)) + { + var component = value.GetComponent(); + if (component != null) + { + current = component; + return true; + } + } + + current = default!; + return false; + } + + public void Dispose() + { + source.Dispose(); + } + + public bool TryCopyTo(Span destination, Index offset) + { + return false; + } + } +} diff --git a/Packages/ZLinq.Unity/Runtime/OfComponent.cs.meta b/Packages/ZLinq.Unity/Runtime/OfComponent.cs.meta new file mode 100644 index 0000000..ce58549 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/OfComponent.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ee3894e6d711f444b9a7e010477569ac +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins.meta b/Packages/ZLinq.Unity/Runtime/Plugins.meta new file mode 100644 index 0000000..0dd395b --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 54b5701e205c3534b92ec040b9da16af +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net10.0.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0.meta new file mode 100644 index 0000000..8bf47ba --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 0507c8a03b8325b4fb17b04e0abc22c8 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.dll b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.dll new file mode 100644 index 0000000..1f0d1aa Binary files /dev/null and b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.dll differ diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.dll.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.dll.meta new file mode 100644 index 0000000..9e07849 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.dll.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0aecf6d6cbdd3d84e9f71e77acdb0ee3 \ No newline at end of file diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.xml b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.xml new file mode 100644 index 0000000..9998754 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.xml @@ -0,0 +1,110 @@ + + + + ZLinq + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + Returns the number of elements copied. + + + + + List is cleared and then filled with the elements of the source. Destination size is list.Count. + + + + + Converts to an array borrowed from ArrayPool<T>.Shared. + For performance considerations, PooledArray is a struct, so + copying or boxing it risks returning to the ArrayPool multiple times. + Always use it simply with using and do not keep it for long periods. + + + + + Holds an array borrowed from ArrayPool<T>.Shared.Rent. + When Disposed, it will Return the array to ArrayPool<T>.Shared. + If boxed or passed by copy, there's a risk of multiple Returns. + Please use it as is and avoid long-term retention. + + + + + Equivalent of IEnumerator.MoveNext + Current. + + + + + Returns the length when processing time is not necessary. + Always returns true if TryGetSpan or TryCopyTo returns true. + + + + + Returns true if it can return a Span. + Used for SIMD and loop processing optimization. + If copying the entire value is acceptable, prioritize TryGetNonEnumeratedCount -> TryCopyTo instead. + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + This serves as a TryGet function as well, e.g. single-span and ^1 is TryGetLast. + + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets the types of collections for which LINQ implementations should be generated. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + + Gets or sets the conditional compilation symbols to wrap the generated code with #if directives. + If specified, the generated code will be wrapped in #if/#endif directives using these symbols. + + + + + Gets or sets whether to disable source generation in emitted code. + When true, the source code comments will not be included in the generated code. + When false (default), source code comments will be included in the generated code. + + + + + Initializes a new instance of the class. + + The namespace where the generated LINQ implementations will be placed. If empty, place to global. + The types of collections for which LINQ implementations should be generated. + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.xml.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.xml.meta new file mode 100644 index 0000000..b837176 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net10.0/ZLinq.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: a51b392d39f260b47838faf4c1b7deb5 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net8.0.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0.meta new file mode 100644 index 0000000..6d23495 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 23e0b4015072efc42b0c43f706109d82 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.dll b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.dll new file mode 100644 index 0000000..3752134 Binary files /dev/null and b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.dll differ diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.dll.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.dll.meta new file mode 100644 index 0000000..ded7e9c --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.dll.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9dd85473e7e8ad64285831ce8ed0b7c2 \ No newline at end of file diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.xml b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.xml new file mode 100644 index 0000000..9998754 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.xml @@ -0,0 +1,110 @@ + + + + ZLinq + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + Returns the number of elements copied. + + + + + List is cleared and then filled with the elements of the source. Destination size is list.Count. + + + + + Converts to an array borrowed from ArrayPool<T>.Shared. + For performance considerations, PooledArray is a struct, so + copying or boxing it risks returning to the ArrayPool multiple times. + Always use it simply with using and do not keep it for long periods. + + + + + Holds an array borrowed from ArrayPool<T>.Shared.Rent. + When Disposed, it will Return the array to ArrayPool<T>.Shared. + If boxed or passed by copy, there's a risk of multiple Returns. + Please use it as is and avoid long-term retention. + + + + + Equivalent of IEnumerator.MoveNext + Current. + + + + + Returns the length when processing time is not necessary. + Always returns true if TryGetSpan or TryCopyTo returns true. + + + + + Returns true if it can return a Span. + Used for SIMD and loop processing optimization. + If copying the entire value is acceptable, prioritize TryGetNonEnumeratedCount -> TryCopyTo instead. + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + This serves as a TryGet function as well, e.g. single-span and ^1 is TryGetLast. + + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets the types of collections for which LINQ implementations should be generated. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + + Gets or sets the conditional compilation symbols to wrap the generated code with #if directives. + If specified, the generated code will be wrapped in #if/#endif directives using these symbols. + + + + + Gets or sets whether to disable source generation in emitted code. + When true, the source code comments will not be included in the generated code. + When false (default), source code comments will be included in the generated code. + + + + + Initializes a new instance of the class. + + The namespace where the generated LINQ implementations will be placed. If empty, place to global. + The types of collections for which LINQ implementations should be generated. + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.xml.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.xml.meta new file mode 100644 index 0000000..d429b46 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net8.0/ZLinq.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: dbbb8995ef7d07e4f8481b4e723bbaff +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net9.0.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0.meta new file mode 100644 index 0000000..6e15ba7 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 376a4bea30efe974bb5718aec77fd1c7 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.dll b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.dll new file mode 100644 index 0000000..d46c3f7 Binary files /dev/null and b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.dll differ diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.dll.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.dll.meta new file mode 100644 index 0000000..e34e773 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.dll.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 9068534393c548742b51dbb1b5d1bdec \ No newline at end of file diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.xml b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.xml new file mode 100644 index 0000000..9998754 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.xml @@ -0,0 +1,110 @@ + + + + ZLinq + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + Returns the number of elements copied. + + + + + List is cleared and then filled with the elements of the source. Destination size is list.Count. + + + + + Converts to an array borrowed from ArrayPool<T>.Shared. + For performance considerations, PooledArray is a struct, so + copying or boxing it risks returning to the ArrayPool multiple times. + Always use it simply with using and do not keep it for long periods. + + + + + Holds an array borrowed from ArrayPool<T>.Shared.Rent. + When Disposed, it will Return the array to ArrayPool<T>.Shared. + If boxed or passed by copy, there's a risk of multiple Returns. + Please use it as is and avoid long-term retention. + + + + + Equivalent of IEnumerator.MoveNext + Current. + + + + + Returns the length when processing time is not necessary. + Always returns true if TryGetSpan or TryCopyTo returns true. + + + + + Returns true if it can return a Span. + Used for SIMD and loop processing optimization. + If copying the entire value is acceptable, prioritize TryGetNonEnumeratedCount -> TryCopyTo instead. + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + This serves as a TryGet function as well, e.g. single-span and ^1 is TryGetLast. + + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets the types of collections for which LINQ implementations should be generated. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + + Gets or sets the conditional compilation symbols to wrap the generated code with #if directives. + If specified, the generated code will be wrapped in #if/#endif directives using these symbols. + + + + + Gets or sets whether to disable source generation in emitted code. + When true, the source code comments will not be included in the generated code. + When false (default), source code comments will be included in the generated code. + + + + + Initializes a new instance of the class. + + The namespace where the generated LINQ implementations will be placed. If empty, place to global. + The types of collections for which LINQ implementations should be generated. + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.xml.meta b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.xml.meta new file mode 100644 index 0000000..b756217 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/net9.0/ZLinq.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 706f266cc51bbf94e82403eb02e79a37 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0.meta b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0.meta new file mode 100644 index 0000000..1cd7646 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: d4968ccf14414e0469f83161e59648af +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.dll b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.dll new file mode 100644 index 0000000..1ab0e80 Binary files /dev/null and b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.dll differ diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.dll.meta b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.dll.meta new file mode 100644 index 0000000..bd5043a --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.dll.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: cf90099a8f165094da8b17bd2626a2b8 \ No newline at end of file diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.xml b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.xml new file mode 100644 index 0000000..aea529c --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.xml @@ -0,0 +1,598 @@ + + + + ZLinq + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + Returns the number of elements copied. + + + + + List is cleared and then filled with the elements of the source. Destination size is list.Count. + + + + + Converts to an array borrowed from ArrayPool<T>.Shared. + For performance considerations, PooledArray is a struct, so + copying or boxing it risks returning to the ArrayPool multiple times. + Always use it simply with using and do not keep it for long periods. + + + + + Holds an array borrowed from ArrayPool<T>.Shared.Rent. + When Disposed, it will Return the array to ArrayPool<T>.Shared. + If boxed or passed by copy, there's a risk of multiple Returns. + Please use it as is and avoid long-term retention. + + + + + Equivalent of IEnumerator.MoveNext + Current. + + + + + Returns the length when processing time is not necessary. + Always returns true if TryGetSpan or TryCopyTo returns true. + + + + + Returns true if it can return a Span. + Used for SIMD and loop processing optimization. + If copying the entire value is acceptable, prioritize TryGetNonEnumeratedCount -> TryCopyTo instead. + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + This serves as a TryGet function as well, e.g. single-span and ^1 is TryGetLast. + + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets the types of collections for which LINQ implementations should be generated. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + + Gets or sets the conditional compilation symbols to wrap the generated code with #if directives. + If specified, the generated code will be wrapped in #if/#endif directives using these symbols. + + + + + Gets or sets whether to disable source generation in emitted code. + When true, the source code comments will not be included in the generated code. + When false (default), source code comments will be included in the generated code. + + + + + Initializes a new instance of the class. + + The namespace where the generated LINQ implementations will be placed. If empty, place to global. + The types of collections for which LINQ implementations should be generated. + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + + Indicates the type of the async method builder that should be used by a language compiler to + build the attributed async method or to build the attributed type when used as the return type + of an async method. + + + + Initializes the . + The of the associated builder. + + + Gets the of the associated builder. + + + + An attribute that allows parameters to receive the expression of other parameters. + + + + + Initializes a new instance of the class. + + The condition parameter value. + + + + Gets the parameter name the expression is retrieved from. + + + + + Initialize the attribute to refer to the method on the type. + + The type of the builder to use to construct the collection. + The name of the method on the builder to use to construct the collection. + + must refer to a static method that accepts a single parameter of + type and returns an instance of the collection being built containing + a copy of the data from that span. In future releases of .NET, additional patterns may be supported. + + + + + Gets the type of the builder to use to construct the collection. + + + + + Gets the name of the method on the builder to use to construct the collection. + + + This should match the metadata name of the target method. + For example, this might be ".ctor" if targeting the type's constructor. + + + + + Indicates that compiler support for a particular feature is required for the location where this attribute is applied. + + + + + Creates a new instance of the type. + + The name of the feature to indicate. + + + + The name of the compiler feature. + + + + + If true, the compiler can choose to allow access to the location where this attribute is applied if it does not understand . + + + + + The used for the ref structs C# feature. + + + + + The used for the required members C# feature. + + + + + Indicates which arguments to a method involving an interpolated string handler should be passed to that handler. + + + + + Initializes a new instance of the class. + + The name of the argument that should be passed to the handler. + may be used as the name of the receiver in an instance method. + + + + Initializes a new instance of the class. + + The names of the arguments that should be passed to the handler. + may be used as the name of the receiver in an instance method. + + + + Gets the names of the arguments that should be passed to the handler. + + may be used as the name of the receiver in an instance method. + + + + Indicates the attributed type is to be used as an interpolated string handler. + + + + + Reserved to be used by the compiler for tracking metadata. + This class should not be used by developers in source code. + + + + + Used to indicate to the compiler that a method should be called + in its containing module's initializer. + + + When one or more valid methods + with this attribute are found in a compilation, the compiler will + emit a module initializer which calls each of the attributed methods. + + Certain requirements are imposed on any method targeted with this attribute: + - The method must be `static`. + - The method must be an ordinary member method, as opposed to a property accessor, constructor, local function, etc. + - The method must be parameterless. + - The method must return `void`. + - The method must not be generic or be contained in a generic type. + - The method's effective accessibility must be `internal` or `public`. + + The specification for module initializers in the .NET runtime can be found here: + https://github.com/dotnet/runtime/blob/main/docs/design/specs/Ecma-335-Augments.md#module-initializer + + + + + Specifies the priority of a member in overload resolution. When unspecified, the default priority is 0. + + + + + Initializes a new instance of the class. + + The priority of the attributed member. Higher numbers are prioritized, lower numbers are deprioritized. 0 is the default if no attribute is present. + + + + The priority of the member. + + + + + Indicates that a method will allow a variable number of arguments in its invocation. + + + + + Specifies that a type has required members or that a member is required. + + + + + Reserved for use by a compiler for tracking metadata. + This attribute should not be used by developers in source code. + + + + + Used to indicate to the compiler that the .locals init flag should not be set in method headers. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified message. + + An optional message associated with this attribute instance. + + + + Returns the optional message associated with this attribute instance. + + + + + Returns the optional URL associated with this attribute instance. + + + + + Specifies that null is allowed as an input even if the corresponding type disallows it. + + + + + Indicates that the specified method parameter expects a constant. + + + This can be used to inform tooling that a constant should be used as an argument for the annotated parameter. + + + + + Indicates the minimum bound of the expected constant, inclusive. + + + + + Indicates the maximum bound of the expected constant, inclusive. + + + + + Specifies that null is disallowed as an input even if the corresponding type allows it. + + + + + Applied to a method that will never return under any circumstance. + + + + + Specifies that the method will not return if the associated Boolean parameter is passed the specified value. + + + + + Initializes the attribute with the specified parameter value. + + + The condition parameter value. Code after the method will be considered unreachable + by diagnostics if the argument to the associated parameter matches this value. + + + + + Gets the condition parameter value. + + + + + Indicates that an API is experimental and it may change in the future. + + + This attribute allows call sites to be flagged with a diagnostic that indicates that an experimental + feature is used. Authors can use this attribute to ship preview features in their assemblies. + + + + + Initializes a new instance of the class, + specifying the ID that the compiler will use when reporting a use of the API the attribute applies to. + + The ID that the compiler will use when reporting a use of the API the attribute applies to. + + + + Gets the ID that the compiler will use when reporting a use of the API the attribute applies to. + + The unique diagnostic ID. + + The diagnostic ID is shown in build output for warnings and errors. + This property represents the unique ID that can be used to suppress the warnings or errors, if needed. + + + + + Gets or sets the URL for corresponding documentation. + The API accepts a format string instead of an actual URL, creating a generic URL that includes the diagnostic ID. + + The format string that represents a URL to corresponding documentation. + An example format string is https://contoso.com/obsoletion-warnings/{0}. + + + + Specifies that an output may be null even if the corresponding type disallows it. + + + + + Specifies that when a method returns , the parameter may be null even if the corresponding type disallows it. + + + + + Initializes the attribute with the specified return value condition. + + The return value condition. If the method returns this value, the associated parameter may be null. + + + + Gets the return value condition. + + + + + Specifies that the method or property will ensure that the listed field and property members have not-null values. + + + + + Initializes the attribute with a field or property member. + + The field or property member that is promised to be not-null. + + + + Initializes the attribute with the list of field and property members. + + The list of field and property members that are promised to be not-null. + + + + Gets field or property member names. + + + + + Specifies that the method or property will ensure that the listed field and property + members have not-null values when returning with the specified return value condition. + + + + + Initializes the attribute with the specified return value condition and a field or property member. + + The return value condition. If the method returns this value, the associated parameter will not be null. + The field or property member that is promised to be not-null. + + + + Initializes the attribute with the specified return value condition and list of field and property members. + + The return value condition. If the method returns this value, the associated parameter will not be null. + The list of field and property members that are promised to be not-null. + + + + Gets the return value condition. + + + + + Gets field or property member names. + + + + + Specifies that an output will not be null even if the corresponding type allows it. + Specifies that an input argument was not null when the call returns. + + + + + Specifies that the output will be non-null if the named parameter is non-null. + + + + + Initializes the attribute with the associated parameter name. + + The associated parameter name. The output will be non-null if the argument to the parameter specified is non-null. + + + + Gets the associated parameter name. + + + + + Specifies that when a method returns , the parameter will not be null even if the corresponding type allows it. + + + + + Initializes the attribute with the specified return value condition. + + The return value condition. If the method returns this value, the associated parameter will not be null. + + + Gets the return value condition. + + + + Specifies that this constructor sets all required members for the current type, + and callers do not need to set any required members themselves. + + + + + Specifies the syntax used in a string. + + + + + Initializes the with the identifier of the syntax used. + + The syntax identifier. + + + Initializes the with the identifier of the syntax used. + The syntax identifier. + Optional arguments associated with the specific syntax employed. + + + Gets the identifier of the syntax used. + + + Optional arguments associated with the specific syntax employed. + + + The syntax identifier for strings containing composite formats for string formatting. + + + The syntax identifier for strings containing date format specifiers. + + + The syntax identifier for strings containing date and time format specifiers. + + + The syntax identifier for strings containing format specifiers. + + + The syntax identifier for strings containing format specifiers. + + + The syntax identifier for strings containing JavaScript Object Notation (JSON). + + + The syntax identifier for strings containing numeric format specifiers. + + + The syntax identifier for strings containing regular expressions. + + + The syntax identifier for strings containing time format specifiers. + + + The syntax identifier for strings containing format specifiers. + + + The syntax identifier for strings containing URIs. + + + The syntax identifier for strings containing XML. + + + + Used to indicate a byref escapes and is not scoped. + + + + There are several cases where the C# compiler treats a as implicitly + - where the compiler does not allow the to escape the method. + + + For example: + + for instance methods. + parameters that refer to types. + parameters. + + + + This attribute is used in those instances where the should be allowed to escape. + + + Applying this attribute, in any form, has impact on consumers of the applicable API. It is necessary for + API authors to understand the lifetime implications of applying this attribute and how it may impact their users. + + + + + diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.xml.meta b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.xml.meta new file mode 100644 index 0000000..856d8a0 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.0/ZLinq.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: fdcd340e8238cc54c879b5a74bc78aab +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1.meta b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1.meta new file mode 100644 index 0000000..fd03503 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: cad4af5fcf3e9854a955c7e365dc3032 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.dll b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.dll new file mode 100644 index 0000000..3cc8b61 Binary files /dev/null and b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.dll differ diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.dll.meta b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.dll.meta new file mode 100644 index 0000000..6ca1cb5 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.dll.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 7a77196d63d1f224888cec4efc9b92c8 \ No newline at end of file diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.xml b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.xml new file mode 100644 index 0000000..a42a27b --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.xml @@ -0,0 +1,493 @@ + + + + ZLinq + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + Returns the number of elements copied. + + + + + List is cleared and then filled with the elements of the source. Destination size is list.Count. + + + + + Converts to an array borrowed from ArrayPool<T>.Shared. + For performance considerations, PooledArray is a struct, so + copying or boxing it risks returning to the ArrayPool multiple times. + Always use it simply with using and do not keep it for long periods. + + + + + Holds an array borrowed from ArrayPool<T>.Shared.Rent. + When Disposed, it will Return the array to ArrayPool<T>.Shared. + If boxed or passed by copy, there's a risk of multiple Returns. + Please use it as is and avoid long-term retention. + + + + + Equivalent of IEnumerator.MoveNext + Current. + + + + + Returns the length when processing time is not necessary. + Always returns true if TryGetSpan or TryCopyTo returns true. + + + + + Returns true if it can return a Span. + Used for SIMD and loop processing optimization. + If copying the entire value is acceptable, prioritize TryGetNonEnumeratedCount -> TryCopyTo instead. + + + + + Unlike the semantics of normal CopyTo, this allows the destination to be smaller than the source. + This serves as a TryGet function as well, e.g. single-span and ^1 is TryGetLast. + + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets the types of collections for which LINQ implementations should be generated. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + + Gets or sets the conditional compilation symbols to wrap the generated code with #if directives. + If specified, the generated code will be wrapped in #if/#endif directives using these symbols. + + + + + Gets or sets whether to disable source generation in emitted code. + When true, the source code comments will not be included in the generated code. + When false (default), source code comments will be included in the generated code. + + + + + Initializes a new instance of the class. + + The namespace where the generated LINQ implementations will be placed. If empty, place to global. + The types of collections for which LINQ implementations should be generated. + + + + Gets the namespace where the generated LINQ implementations will be placed. + If empty, the implementations will be generated in the global namespace. + + + + + Gets whether the generated LINQ implementations should be public. + When true, the implementations will be generated with public visibility. + When false (default), the implementations will be generated with internal visibility. + + + + + An attribute that allows parameters to receive the expression of other parameters. + + + + + Initializes a new instance of the class. + + The condition parameter value. + + + + Gets the parameter name the expression is retrieved from. + + + + + Initialize the attribute to refer to the method on the type. + + The type of the builder to use to construct the collection. + The name of the method on the builder to use to construct the collection. + + must refer to a static method that accepts a single parameter of + type and returns an instance of the collection being built containing + a copy of the data from that span. In future releases of .NET, additional patterns may be supported. + + + + + Gets the type of the builder to use to construct the collection. + + + + + Gets the name of the method on the builder to use to construct the collection. + + + This should match the metadata name of the target method. + For example, this might be ".ctor" if targeting the type's constructor. + + + + + Indicates that compiler support for a particular feature is required for the location where this attribute is applied. + + + + + Creates a new instance of the type. + + The name of the feature to indicate. + + + + The name of the compiler feature. + + + + + If true, the compiler can choose to allow access to the location where this attribute is applied if it does not understand . + + + + + The used for the ref structs C# feature. + + + + + The used for the required members C# feature. + + + + + Indicates which arguments to a method involving an interpolated string handler should be passed to that handler. + + + + + Initializes a new instance of the class. + + The name of the argument that should be passed to the handler. + may be used as the name of the receiver in an instance method. + + + + Initializes a new instance of the class. + + The names of the arguments that should be passed to the handler. + may be used as the name of the receiver in an instance method. + + + + Gets the names of the arguments that should be passed to the handler. + + may be used as the name of the receiver in an instance method. + + + + Indicates the attributed type is to be used as an interpolated string handler. + + + + + Reserved to be used by the compiler for tracking metadata. + This class should not be used by developers in source code. + + + + + Used to indicate to the compiler that a method should be called + in its containing module's initializer. + + + When one or more valid methods + with this attribute are found in a compilation, the compiler will + emit a module initializer which calls each of the attributed methods. + + Certain requirements are imposed on any method targeted with this attribute: + - The method must be `static`. + - The method must be an ordinary member method, as opposed to a property accessor, constructor, local function, etc. + - The method must be parameterless. + - The method must return `void`. + - The method must not be generic or be contained in a generic type. + - The method's effective accessibility must be `internal` or `public`. + + The specification for module initializers in the .NET runtime can be found here: + https://github.com/dotnet/runtime/blob/main/docs/design/specs/Ecma-335-Augments.md#module-initializer + + + + + Specifies the priority of a member in overload resolution. When unspecified, the default priority is 0. + + + + + Initializes a new instance of the class. + + The priority of the attributed member. Higher numbers are prioritized, lower numbers are deprioritized. 0 is the default if no attribute is present. + + + + The priority of the member. + + + + + Indicates that a method will allow a variable number of arguments in its invocation. + + + + + Specifies that a type has required members or that a member is required. + + + + + Reserved for use by a compiler for tracking metadata. + This attribute should not be used by developers in source code. + + + + + Used to indicate to the compiler that the .locals init flag should not be set in method headers. + + + + + Initializes a new instance of the class. + + + + + Initializes a new instance of the class with the specified message. + + An optional message associated with this attribute instance. + + + + Returns the optional message associated with this attribute instance. + + + + + Returns the optional URL associated with this attribute instance. + + + + + Indicates that the specified method parameter expects a constant. + + + This can be used to inform tooling that a constant should be used as an argument for the annotated parameter. + + + + + Indicates the minimum bound of the expected constant, inclusive. + + + + + Indicates the maximum bound of the expected constant, inclusive. + + + + + Indicates that an API is experimental and it may change in the future. + + + This attribute allows call sites to be flagged with a diagnostic that indicates that an experimental + feature is used. Authors can use this attribute to ship preview features in their assemblies. + + + + + Initializes a new instance of the class, + specifying the ID that the compiler will use when reporting a use of the API the attribute applies to. + + The ID that the compiler will use when reporting a use of the API the attribute applies to. + + + + Gets the ID that the compiler will use when reporting a use of the API the attribute applies to. + + The unique diagnostic ID. + + The diagnostic ID is shown in build output for warnings and errors. + This property represents the unique ID that can be used to suppress the warnings or errors, if needed. + + + + + Gets or sets the URL for corresponding documentation. + The API accepts a format string instead of an actual URL, creating a generic URL that includes the diagnostic ID. + + The format string that represents a URL to corresponding documentation. + An example format string is https://contoso.com/obsoletion-warnings/{0}. + + + + Specifies that the method or property will ensure that the listed field and property members have not-null values. + + + + + Initializes the attribute with a field or property member. + + The field or property member that is promised to be not-null. + + + + Initializes the attribute with the list of field and property members. + + The list of field and property members that are promised to be not-null. + + + + Gets field or property member names. + + + + + Specifies that the method or property will ensure that the listed field and property + members have not-null values when returning with the specified return value condition. + + + + + Initializes the attribute with the specified return value condition and a field or property member. + + The return value condition. If the method returns this value, the associated parameter will not be null. + The field or property member that is promised to be not-null. + + + + Initializes the attribute with the specified return value condition and list of field and property members. + + The return value condition. If the method returns this value, the associated parameter will not be null. + The list of field and property members that are promised to be not-null. + + + + Gets the return value condition. + + + + + Gets field or property member names. + + + + + Specifies that this constructor sets all required members for the current type, + and callers do not need to set any required members themselves. + + + + + Specifies the syntax used in a string. + + + + + Initializes the with the identifier of the syntax used. + + The syntax identifier. + + + Initializes the with the identifier of the syntax used. + The syntax identifier. + Optional arguments associated with the specific syntax employed. + + + Gets the identifier of the syntax used. + + + Optional arguments associated with the specific syntax employed. + + + The syntax identifier for strings containing composite formats for string formatting. + + + The syntax identifier for strings containing date format specifiers. + + + The syntax identifier for strings containing date and time format specifiers. + + + The syntax identifier for strings containing format specifiers. + + + The syntax identifier for strings containing format specifiers. + + + The syntax identifier for strings containing JavaScript Object Notation (JSON). + + + The syntax identifier for strings containing numeric format specifiers. + + + The syntax identifier for strings containing regular expressions. + + + The syntax identifier for strings containing time format specifiers. + + + The syntax identifier for strings containing format specifiers. + + + The syntax identifier for strings containing URIs. + + + The syntax identifier for strings containing XML. + + + + Used to indicate a byref escapes and is not scoped. + + + + There are several cases where the C# compiler treats a as implicitly + - where the compiler does not allow the to escape the method. + + + For example: + + for instance methods. + parameters that refer to types. + parameters. + + + + This attribute is used in those instances where the should be allowed to escape. + + + Applying this attribute, in any form, has impact on consumers of the applicable API. It is necessary for + API authors to understand the lifetime implications of applying this attribute and how it may impact their users. + + + + + diff --git a/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.xml.meta b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.xml.meta new file mode 100644 index 0000000..ea64e16 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/Plugins/netstandard2.1/ZLinq.xml.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d7a605d1d0408a541922b9b6ef98187d +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/TransformTraverser.cs b/Packages/ZLinq.Unity/Runtime/TransformTraverser.cs new file mode 100644 index 0000000..ec0ac9e --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/TransformTraverser.cs @@ -0,0 +1,246 @@ +#nullable enable + +using System.Runtime.InteropServices; +using UnityEngine; +using ZLinq.Traversables; + +namespace ZLinq +{ + public static class TransformTraverserExtensions + { + public static TransformTraverser AsTraverser(this Transform origin) => new(origin); + + // type inference helper + + public static ValueEnumerable, Transform> Children(this TransformTraverser traverser) => traverser.Children(); + public static ValueEnumerable, Transform> ChildrenAndSelf(this TransformTraverser traverser) => traverser.ChildrenAndSelf(); + public static ValueEnumerable, Transform> Descendants(this TransformTraverser traverser) => traverser.Descendants(); + public static ValueEnumerable, Transform> DescendantsAndSelf(this TransformTraverser traverser) => traverser.DescendantsAndSelf(); + public static ValueEnumerable, Transform> Ancestors(this TransformTraverser traverser) => traverser.Ancestors(); + public static ValueEnumerable, Transform> AncestorsAndSelf(this TransformTraverser traverser) => traverser.AncestorsAndSelf(); + public static ValueEnumerable, Transform> BeforeSelf(this TransformTraverser traverser) => traverser.BeforeSelf(); + public static ValueEnumerable, Transform> BeforeSelfAndSelf(this TransformTraverser traverser) => traverser.BeforeSelfAndSelf(); + public static ValueEnumerable, Transform> AfterSelf(this TransformTraverser traverser) => traverser.AfterSelf(); + public static ValueEnumerable, Transform> AfterSelfAndSelf(this TransformTraverser traverser) => traverser.AfterSelfAndSelf(); + + // direct shortcut + + public static ValueEnumerable, Transform> Children(this Transform origin) => origin.AsTraverser().Children(); + public static ValueEnumerable, Transform> ChildrenAndSelf(this Transform origin) => origin.AsTraverser().ChildrenAndSelf(); + public static ValueEnumerable, Transform> Descendants(this Transform origin) => origin.AsTraverser().Descendants(); + public static ValueEnumerable, Transform> DescendantsAndSelf(this Transform origin) => origin.AsTraverser().DescendantsAndSelf(); + public static ValueEnumerable, Transform> Ancestors(this Transform origin) => origin.AsTraverser().Ancestors(); + public static ValueEnumerable, Transform> AncestorsAndSelf(this Transform origin) => origin.AsTraverser().AncestorsAndSelf(); + public static ValueEnumerable, Transform> BeforeSelf(this Transform origin) => origin.AsTraverser().BeforeSelf(); + public static ValueEnumerable, Transform> BeforeSelfAndSelf(this Transform origin) => origin.AsTraverser().BeforeSelfAndSelf(); + public static ValueEnumerable, Transform> AfterSelf(this Transform origin) => origin.AsTraverser().AfterSelf(); + public static ValueEnumerable, Transform> AfterSelfAndSelf(this Transform origin) => origin.AsTraverser().AfterSelfAndSelf(); + + // OfComponent + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, Transform> source) + where TComponent : Component => new(new(source.Enumerator)); + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, Transform> source) + where TComponent : Component => new(new(source.Enumerator)); + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, Transform> source) + where TComponent : Component => new(new(source.Enumerator)); + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, Transform> source) + where TComponent : Component => new(new(source.Enumerator)); + + public static ValueEnumerable, TComponent>, TComponent> OfComponent(this ValueEnumerable, Transform> source) + where TComponent : Component => new(new(source.Enumerator)); + } + + [StructLayout(LayoutKind.Auto)] + public struct TransformTraverser : ITraverser + { + static readonly object CalledTryGetNextChild = new object(); + static readonly object ParentNotFound = new object(); + + readonly Transform transform; + object? initializedState; // CalledTryGetNext or Parent(for sibling operations) + int childCount; // self childCount(TryGetNextChild) or parent childCount(TryGetSibling) + int index; + + public TransformTraverser(Transform origin) + { + this.transform = origin; + this.initializedState = null; + this.childCount = 0; + this.index = 0; + } + + public Transform Origin => transform; + public TransformTraverser ConvertToTraverser(Transform next) => new(next); + + public bool TryGetParent(out Transform parent) + { + var tp = transform.parent; + if (tp != null) + { + parent = tp; + return true; + } + + parent = default!; + return false; + } + + public bool TryGetChildCount(out int count) + { + count = transform.childCount; + return true; + } + + public bool TryGetHasChild(out bool hasChild) + { + hasChild = transform.childCount != 0; + return true; + } + + public bool TryGetNextChild(out Transform child) + { + if (initializedState == null) + { + initializedState = CalledTryGetNextChild; + childCount = transform.childCount; + } + + if (index < childCount) + { + child = transform.GetChild(index++); + return true; + } + + child = default!; + return false; + } + + public bool TryGetNextSibling(out Transform next) + { + if (initializedState == null) + { + var tp = transform.parent; + if (tp == null) + { + var scene = transform.gameObject.scene; + // check is scene root object + if (scene.IsValid()) + { + initializedState = scene; + childCount = scene.rootCount; + index = transform.GetSiblingIndex() + 1; + } + else + { + initializedState = ParentNotFound; + next = default!; + return false; + } + } + else + { + // cache parent and childCount + initializedState = tp; + childCount = tp.childCount; // parent's childCount + index = transform.GetSiblingIndex() + 1; + } + } + else if (initializedState == ParentNotFound) + { + next = default!; + return false; + } + + if (initializedState is Transform parent) + { + if (index < childCount) + { + next = parent.GetChild(index++); + return true; + } + } + else if (initializedState is UnityEngine.SceneManagement.Scene scene) + { + if (index < childCount) + { + var list = UnityEngine.Pool.ListPool.Get(); + scene.GetRootGameObjects(list); + next = list[index++].transform; + UnityEngine.Pool.ListPool.Release(list); + return true; + } + } + + next = default!; + return false; + } + + public bool TryGetPreviousSibling(out Transform previous) + { + if (initializedState == null) + { + var tp = transform.parent; + if (tp == null) + { + var scene = transform.gameObject.scene; + // check is scene root object + if (scene.IsValid()) + { + initializedState = scene; + childCount = transform.GetSiblingIndex(); + index = 0; + } + else + { + initializedState = ParentNotFound; + previous = default!; + return false; + } + } + else + { + initializedState = tp; + childCount = transform.GetSiblingIndex(); // not childCount but means `to` + index = 0; // 0 to siblingIndex + } + + } + else if (initializedState == ParentNotFound) + { + previous = default!; + return false; + } + + if (initializedState is Transform parent) + { + if (index < childCount) + { + previous = parent.GetChild(index++); + return true; + } + } + else if (initializedState is UnityEngine.SceneManagement.Scene scene) + { + if (index < childCount) + { + var list = UnityEngine.Pool.ListPool.Get(); + scene.GetRootGameObjects(list); + previous = list[index++].transform; + UnityEngine.Pool.ListPool.Release(list); + return true; + } + } + + previous = default!; + return false; + } + + public void Dispose() + { + } + } +} diff --git a/Packages/ZLinq.Unity/Runtime/TransformTraverser.cs.meta b/Packages/ZLinq.Unity/Runtime/TransformTraverser.cs.meta new file mode 100644 index 0000000..999f5f9 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/TransformTraverser.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: baafa2101b17837489b25922da59f758 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/Runtime/VisualElementTraverser.cs b/Packages/ZLinq.Unity/Runtime/VisualElementTraverser.cs new file mode 100644 index 0000000..9717102 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/VisualElementTraverser.cs @@ -0,0 +1,181 @@ +#if ZLINQ_UNITY_UIELEMENTS_SUPPORT + +#nullable enable + +using System.Runtime.InteropServices; +using UnityEngine.UIElements; +using ZLinq.Traversables; + +namespace ZLinq +{ + public static class VisualTraverserExtensions + { + public static VisualElementTraverser AsTraverser(this VisualElement origin) => new(origin); + + // type inference helper + + public static ValueEnumerable, VisualElement> Children(this VisualElementTraverser traverser) => traverser.Children(); + public static ValueEnumerable, VisualElement> ChildrenAndSelf(this VisualElementTraverser traverser) => traverser.ChildrenAndSelf(); + public static ValueEnumerable, VisualElement> Descendants(this VisualElementTraverser traverser) => traverser.Descendants(); + public static ValueEnumerable, VisualElement> DescendantsAndSelf(this VisualElementTraverser traverser) => traverser.DescendantsAndSelf(); + public static ValueEnumerable, VisualElement> Ancestors(this VisualElementTraverser traverser) => traverser.Ancestors(); + public static ValueEnumerable, VisualElement> AncestorsAndSelf(this VisualElementTraverser traverser) => traverser.AncestorsAndSelf(); + public static ValueEnumerable, VisualElement> BeforeSelf(this VisualElementTraverser traverser) => traverser.BeforeSelf(); + public static ValueEnumerable, VisualElement> BeforeSelfAndSelf(this VisualElementTraverser traverser) => traverser.BeforeSelfAndSelf(); + public static ValueEnumerable, VisualElement> AfterSelf(this VisualElementTraverser traverser) => traverser.AfterSelf(); + public static ValueEnumerable, VisualElement> AfterSelfAndSelf(this VisualElementTraverser traverser) => traverser.AfterSelfAndSelf(); + + // direct shortcut + + public static ValueEnumerable, VisualElement> Children(this VisualElement origin) => origin.AsTraverser().Children(); + public static ValueEnumerable, VisualElement> ChildrenAndSelf(this VisualElement origin) => origin.AsTraverser().ChildrenAndSelf(); + public static ValueEnumerable, VisualElement> Descendants(this VisualElement origin) => origin.AsTraverser().Descendants(); + public static ValueEnumerable, VisualElement> DescendantsAndSelf(this VisualElement origin) => origin.AsTraverser().DescendantsAndSelf(); + public static ValueEnumerable, VisualElement> Ancestors(this VisualElement origin) => origin.AsTraverser().Ancestors(); + public static ValueEnumerable, VisualElement> AncestorsAndSelf(this VisualElement origin) => origin.AsTraverser().AncestorsAndSelf(); + public static ValueEnumerable, VisualElement> BeforeSelf(this VisualElement origin) => origin.AsTraverser().BeforeSelf(); + public static ValueEnumerable, VisualElement> BeforeSelfAndSelf(this VisualElement origin) => origin.AsTraverser().BeforeSelfAndSelf(); + public static ValueEnumerable, VisualElement> AfterSelf(this VisualElement origin) => origin.AsTraverser().AfterSelf(); + public static ValueEnumerable, VisualElement> AfterSelfAndSelf(this VisualElement origin) => origin.AsTraverser().AfterSelfAndSelf(); + + } + + [StructLayout(LayoutKind.Auto)] + public struct VisualElementTraverser : ITraverser + { + static readonly object CalledTryGetNextChild = new object(); + static readonly object ParentNotFound = new object(); + + readonly VisualElement visualElement; + object? initializedState; // CalledTryGetNext or Parent(for sibling operations) + int childCount; // self childCount(TryGetNextChild) or parent childCount(TryGetSibling) + int index; + + public VisualElementTraverser(VisualElement origin) + { + this.visualElement = origin; + this.initializedState = null; + this.childCount = 0; + this.index = 0; + } + + public VisualElement Origin => visualElement; + public VisualElementTraverser ConvertToTraverser(VisualElement next) => new(next); + + public bool TryGetParent(out VisualElement parent) + { + var veParent = visualElement.parent; + if (veParent != null) + { + parent = veParent; + return true; + } + + parent = default!; + return false; + } + + public bool TryGetChildCount(out int count) + { + count = visualElement.childCount; + return true; + } + + public bool TryGetHasChild(out bool hasChild) + { + hasChild = visualElement.childCount != 0; + return true; + } + + public bool TryGetNextChild(out VisualElement child) + { + if (initializedState == null) + { + initializedState = CalledTryGetNextChild; + childCount = visualElement.childCount; + } + + if (index < childCount) + { + child = visualElement[index++]; + return true; + } + + child = default!; + return false; + } + + public bool TryGetNextSibling(out VisualElement next) + { + if (initializedState == null) + { + var veParent = visualElement.parent; + if (veParent == null) + { + initializedState = ParentNotFound; + next = default!; + return false; + } + + // cache parent and childCount + initializedState = veParent; + childCount = veParent.childCount; // parent's childCount + index = veParent.IndexOf(visualElement) + 1; + } + else if (initializedState == ParentNotFound) + { + next = default!; + return false; + } + + var parent = (VisualElement)initializedState; + if (index < childCount) + { + next = parent[index++]; + return true; + } + + next = default!; + return false; + } + + public bool TryGetPreviousSibling(out VisualElement previous) + { + if (initializedState == null) + { + var veParent = visualElement.parent; + if (veParent == null) + { + initializedState = ParentNotFound; + previous = default!; + return false; + } + + initializedState = veParent; + childCount = veParent.IndexOf(visualElement); // not childCount but means `to` + index = 0; // 0 to siblingIndex + } + else if (initializedState == ParentNotFound) + { + previous = default!; + return false; + } + + var parent = (VisualElement)initializedState; + if (index < childCount) + { + previous = parent[index++]; + return true; + } + + previous = default!; + return false; + } + + public void Dispose() + { + } + } +} + +#endif diff --git a/Packages/ZLinq.Unity/Runtime/VisualElementTraverser.cs.meta b/Packages/ZLinq.Unity/Runtime/VisualElementTraverser.cs.meta new file mode 100644 index 0000000..55aab28 --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/VisualElementTraverser.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 14298ef73943e428da8cae7f81b28e47 \ No newline at end of file diff --git a/Packages/ZLinq.Unity/Runtime/ZLinq.Unity.asmdef b/Packages/ZLinq.Unity/Runtime/ZLinq.Unity.asmdef new file mode 100644 index 0000000..68697cd --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/ZLinq.Unity.asmdef @@ -0,0 +1,27 @@ +{ + "name": "ZLinq.Unity", + "rootNamespace": "ZLinq", + "references": [], + "includePlatforms": [], + "excludePlatforms": [], + "allowUnsafeCode": true, + "overrideReferences": true, + "precompiledReferences": [ + "ZLinq.dll" + ], + "autoReferenced": true, + "defineConstraints": [], + "versionDefines": [ + { + "name": "com.unity.modules.uielements", + "expression": "", + "define": "ZLINQ_UNITY_UIELEMENTS_SUPPORT" + }, + { + "name": "com.unity.collections", + "expression": "", + "define": "ZLINQ_UNITY_COLLECTIONS_SUPPORT" + } + ], + "noEngineReferences": false +} diff --git a/Packages/ZLinq.Unity/Runtime/ZLinq.Unity.asmdef.meta b/Packages/ZLinq.Unity/Runtime/ZLinq.Unity.asmdef.meta new file mode 100644 index 0000000..cc342ce --- /dev/null +++ b/Packages/ZLinq.Unity/Runtime/ZLinq.Unity.asmdef.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: c71612acbe346a344abbc0dcfdf4f0bd +AssemblyDefinitionImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/ZLinq.Unity/package.json b/Packages/ZLinq.Unity/package.json new file mode 100644 index 0000000..9e1161a --- /dev/null +++ b/Packages/ZLinq.Unity/package.json @@ -0,0 +1,11 @@ +{ + "name": "com.cysharp.zlinq", + "displayName": "ZLinq", + "author": { "name": "Cysharp, Inc.", "url": "https://cysharp.co.jp/en/" }, + "version": "1.5.5", + "unity": "2021.3", + "description": "Zero allocation LINQ with Span and LINQ to SIMD, LINQ to Tree(FileSystem, GameObject, etc...) for all .NET platforms and Unity.", + "keywords": [ "LINQ" ], + "license": "MIT", + "category": "Scripting" +} diff --git a/Packages/ZLinq.Unity/package.json.meta b/Packages/ZLinq.Unity/package.json.meta new file mode 100644 index 0000000..85b3228 --- /dev/null +++ b/Packages/ZLinq.Unity/package.json.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 5b6e5bc3013c2ae49837f6b3aaf0a230 +TextScriptImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/com.jovian.assets-history/Editor/RecentAssetsMenu.cs b/Packages/com.jovian.assets-history/Editor/RecentAssetsMenu.cs index 3177506..262d832 100644 --- a/Packages/com.jovian.assets-history/Editor/RecentAssetsMenu.cs +++ b/Packages/com.jovian.assets-history/Editor/RecentAssetsMenu.cs @@ -109,7 +109,7 @@ namespace Jovian.Recents { private PrefabStage prefabStage; private GUIStyle guiStyle; - [MenuItem("Jovian/Assets History...", false, 20)] + [MenuItem("Jovian/Utilities/Assets History...", false, 20)] private static void Init() { var window = GetWindow(false, "Assets History"); window.minSize = new Vector2(100f, 100f); diff --git a/Packages/com.jovian.logger/Editor/CustomConsole.cs b/Packages/com.jovian.logger/Editor/CustomConsole.cs index 832ca9a..1db8e5e 100644 --- a/Packages/com.jovian.logger/Editor/CustomConsole.cs +++ b/Packages/com.jovian.logger/Editor/CustomConsole.cs @@ -424,7 +424,7 @@ namespace Jovian.Logger { return LogTypeFilterValues[newIndex]; } - [MenuItem("Fidelit&y/&Utility/Custom Logger/Custom Console", false, 2)] + [MenuItem("Jovian/Utilities/Custom Console", false, 2)] public static void ShowWindow() { window = GetWindow("Custom Console"); window.Show(); diff --git a/Packages/com.jovian.unitypackagesync/Editor/PackageSyncWindow.cs b/Packages/com.jovian.unitypackagesync/Editor/PackageSyncWindow.cs index ce16918..89abe10 100644 --- a/Packages/com.jovian.unitypackagesync/Editor/PackageSyncWindow.cs +++ b/Packages/com.jovian.unitypackagesync/Editor/PackageSyncWindow.cs @@ -26,7 +26,7 @@ namespace Jovian.PackageSync { private bool syncEnabled; private PackageMapping[] currentPackages = Array.Empty(); - [MenuItem("Jovian/Package Sync")] + [MenuItem("Jovian/Utilities/Package Sync")] private static void ShowWindow() { var window = GetWindow("Package Sync"); window.minSize = new Vector2(400, 300); diff --git a/Packages/com.jovian.utilities/Runtime/GameObjectUtilities.cs b/Packages/com.jovian.utilities/Runtime/GameObjectUtilities.cs index 07ef926..0a9ba95 100644 --- a/Packages/com.jovian.utilities/Runtime/GameObjectUtilities.cs +++ b/Packages/com.jovian.utilities/Runtime/GameObjectUtilities.cs @@ -5,26 +5,26 @@ using Object = UnityEngine.Object; namespace Jovian.Utilities { public static class GameObjectUtilities { public static void DestroyGameObjectsOfType() where T : MonoBehaviour { - T[] objects = Object.FindObjectsOfType(); - for (int i = 0; i < objects.Length; ++i) { - Object.Destroy(objects[i].gameObject); + var objects = Object.FindObjectsByType(FindObjectsInactive.Include, FindObjectsSortMode.None); + foreach(var t in objects) { + Object.Destroy(t.gameObject); } } public static bool IsGameObjectAChildOfGameObject(this GameObject targetGameObject, GameObject potentialParentGameObject) { - if (targetGameObject == null) { + if(!targetGameObject) { return false; } - Transform potentialParentTransform = potentialParentGameObject.transform; - Transform checkTransform = targetGameObject.transform; + var potentialParentTransform = potentialParentGameObject.transform; + var checkTransform = targetGameObject.transform; do { - if (checkTransform == potentialParentTransform) { + if(checkTransform == potentialParentTransform) { return true; } checkTransform = checkTransform.parent; - } while (checkTransform != null); + } while(checkTransform); return false; } @@ -36,18 +36,18 @@ namespace Jovian.Utilities { bool allowPartialMatch = false, StringComparison stringComparison = StringComparison.Ordinal) { childGameObject = null; - if (gameObject == null) { + if(!gameObject) { return false; } - Transform[] children = gameObject.GetComponentsInChildren(includeInactive); - foreach (Transform child in children) { - if (allowPartialMatch && child.name.Contains(name, stringComparison)) { + var children = gameObject.GetComponentsInChildren(includeInactive); + foreach(var child in children) { + if(allowPartialMatch && child.name.Contains(name, stringComparison)) { childGameObject = child.gameObject; return true; } - if (!allowPartialMatch && child.name.Equals(name, stringComparison)) { + if(!allowPartialMatch && child.name.Equals(name, stringComparison)) { childGameObject = child.gameObject; return true; } @@ -56,4 +56,4 @@ namespace Jovian.Utilities { return false; } } -} \ No newline at end of file +} diff --git a/Packages/packages-lock.json b/Packages/packages-lock.json index 02f5f86..6dd3ac5 100644 --- a/Packages/packages-lock.json +++ b/Packages/packages-lock.json @@ -6,6 +6,12 @@ "source": "embedded", "dependencies": {} }, + "com.cysharp.zlinq": { + "version": "file:ZLinq.Unity", + "depth": 0, + "source": "embedded", + "dependencies": {} + }, "com.jovian.assets-history": { "version": "file:com.jovian.assets-history", "depth": 0,