123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829 |
- using System;
- using System.Collections.Generic;
- using System.Collections;
- using System.Diagnostics.CodeAnalysis;
- using System.Runtime.CompilerServices;
- using Godot.NativeInterop;
- namespace Godot.Collections
- {
- /// <summary>
- /// Wrapper around Godot's Array class, an array of Variant
- /// typed elements allocated in the engine in C++. Useful when
- /// interfacing with the engine. Otherwise prefer .NET collections
- /// such as <see cref="System.Array"/> or <see cref="List{T}"/>.
- /// </summary>
- public sealed class Array :
- IList<Variant>,
- IReadOnlyList<Variant>,
- ICollection,
- IDisposable
- {
- internal godot_array.movable NativeValue;
- private WeakReference<IDisposable> _weakReferenceToSelf;
- /// <summary>
- /// Constructs a new empty <see cref="Array"/>.
- /// </summary>
- public Array()
- {
- NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
- _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
- }
- /// <summary>
- /// Constructs a new <see cref="Array"/> from the given collection's elements.
- /// </summary>
- /// <param name="collection">The collection of elements to construct from.</param>
- /// <returns>A new Godot Array.</returns>
- public Array(IEnumerable<Variant> collection) : this()
- {
- if (collection == null)
- throw new ArgumentNullException(nameof(collection));
- foreach (Variant element in collection)
- Add(element);
- }
- /// <summary>
- /// Constructs a new <see cref="Array"/> from the given objects.
- /// </summary>
- /// <param name="array">The objects to put in the new array.</param>
- /// <returns>A new Godot Array.</returns>
- public Array(Variant[] array) : this()
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
- NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
- _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
- int length = array.Length;
- Resize(length);
- for (int i = 0; i < length; i++)
- this[i] = array[i];
- }
- public Array(Span<StringName> array) : this()
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
- NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
- _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
- int length = array.Length;
- Resize(length);
- for (int i = 0; i < length; i++)
- this[i] = array[i];
- }
- public Array(Span<NodePath> array) : this()
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
- NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
- _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
- int length = array.Length;
- Resize(length);
- for (int i = 0; i < length; i++)
- this[i] = array[i];
- }
- public Array(Span<RID> array) : this()
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
- NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
- _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
- int length = array.Length;
- Resize(length);
- for (int i = 0; i < length; i++)
- this[i] = array[i];
- }
- // We must use ReadOnlySpan instead of Span here as this can accept implicit conversions
- // from derived types (e.g.: Node[]). Implicit conversion from Derived[] to Base[] are
- // fine as long as the array is not mutated. However, Span does this type checking at
- // instantiation, so it's not possible to use it even when not mutating anything.
- // ReSharper disable once RedundantNameQualifier
- public Array(ReadOnlySpan<Godot.Object> array) : this()
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array));
- NativeValue = (godot_array.movable)NativeFuncs.godotsharp_array_new();
- _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
- int length = array.Length;
- Resize(length);
- for (int i = 0; i < length; i++)
- this[i] = array[i];
- }
- private Array(godot_array nativeValueToOwn)
- {
- NativeValue = (godot_array.movable)(nativeValueToOwn.IsAllocated ?
- nativeValueToOwn :
- NativeFuncs.godotsharp_array_new());
- _weakReferenceToSelf = DisposablesTracker.RegisterDisposable(this);
- }
- // Explicit name to make it very clear
- internal static Array CreateTakingOwnershipOfDisposableValue(godot_array nativeValueToOwn)
- => new Array(nativeValueToOwn);
- ~Array()
- {
- Dispose(false);
- }
- /// <summary>
- /// Disposes of this <see cref="Array"/>.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- public void Dispose(bool disposing)
- {
- // Always dispose `NativeValue` even if disposing is true
- NativeValue.DangerousSelfRef.Dispose();
- if (_weakReferenceToSelf != null)
- {
- DisposablesTracker.UnregisterDisposable(_weakReferenceToSelf);
- }
- }
- /// <summary>
- /// Duplicates this <see cref="Array"/>.
- /// </summary>
- /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param>
- /// <returns>A new Godot Array.</returns>
- public Array Duplicate(bool deep = false)
- {
- godot_array newArray;
- var self = (godot_array)NativeValue;
- NativeFuncs.godotsharp_array_duplicate(ref self, deep.ToGodotBool(), out newArray);
- return CreateTakingOwnershipOfDisposableValue(newArray);
- }
- /// <summary>
- /// Resizes this <see cref="Array"/> to the given size.
- /// </summary>
- /// <param name="newSize">The new size of the array.</param>
- /// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns>
- public Error Resize(int newSize)
- {
- var self = (godot_array)NativeValue;
- return NativeFuncs.godotsharp_array_resize(ref self, newSize);
- }
- /// <summary>
- /// Shuffles the contents of this <see cref="Array"/> into a random order.
- /// </summary>
- public void Shuffle()
- {
- var self = (godot_array)NativeValue;
- NativeFuncs.godotsharp_array_shuffle(ref self);
- }
- /// <summary>
- /// Concatenates these two <see cref="Array"/>s.
- /// </summary>
- /// <param name="left">The first array.</param>
- /// <param name="right">The second array.</param>
- /// <returns>A new Godot Array with the contents of both arrays.</returns>
- public static Array operator +(Array left, Array right)
- {
- if (left == null)
- {
- if (right == null)
- return new Array();
- return right.Duplicate(deep: false);
- }
- if (right == null)
- return left.Duplicate(deep: false);
- int leftCount = left.Count;
- int rightCount = right.Count;
- Array newArray = left.Duplicate(deep: false);
- newArray.Resize(leftCount + rightCount);
- for (int i = 0; i < rightCount; i++)
- newArray[i + leftCount] = right[i];
- return newArray;
- }
- /// <summary>
- /// Returns the item at the given <paramref name="index"/>.
- /// </summary>
- /// <value>The <see cref="Variant"/> item at the given <paramref name="index"/>.</value>
- public unsafe Variant this[int index]
- {
- get
- {
- GetVariantBorrowElementAt(index, out godot_variant borrowElem);
- return Variant.CreateCopyingBorrowed(borrowElem);
- }
- set
- {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index));
- var self = (godot_array)NativeValue;
- godot_variant* ptrw = NativeFuncs.godotsharp_array_ptrw(ref self);
- godot_variant* itemPtr = &ptrw[index];
- (*itemPtr).Dispose();
- *itemPtr = value.CopyNativeVariant();
- }
- }
- /// <summary>
- /// Adds an item to the end of this <see cref="Array"/>.
- /// This is the same as <c>append</c> or <c>push_back</c> in GDScript.
- /// </summary>
- /// <param name="item">The <see cref="Variant"/> item to add.</param>
- public void Add(Variant item)
- {
- godot_variant variantValue = (godot_variant)item.NativeVar;
- var self = (godot_array)NativeValue;
- _ = NativeFuncs.godotsharp_array_add(ref self, variantValue);
- }
- /// <summary>
- /// Checks if this <see cref="Array"/> contains the given item.
- /// </summary>
- /// <param name="item">The <see cref="Variant"/> item to look for.</param>
- /// <returns>Whether or not this array contains the given item.</returns>
- public bool Contains(Variant item) => IndexOf(item) != -1;
- /// <summary>
- /// Erases all items from this <see cref="Array"/>.
- /// </summary>
- public void Clear() => Resize(0);
- /// <summary>
- /// Searches this <see cref="Array"/> for an item
- /// and returns its index or -1 if not found.
- /// </summary>
- /// <param name="item">The <see cref="Variant"/> item to search for.</param>
- /// <returns>The index of the item, or -1 if not found.</returns>
- public int IndexOf(Variant item)
- {
- godot_variant variantValue = (godot_variant)item.NativeVar;
- var self = (godot_array)NativeValue;
- return NativeFuncs.godotsharp_array_index_of(ref self, variantValue);
- }
- /// <summary>
- /// Inserts a new item at a given position in the array.
- /// The position must be a valid position of an existing item,
- /// or the position at the end of the array.
- /// Existing items will be moved to the right.
- /// </summary>
- /// <param name="index">The index to insert at.</param>
- /// <param name="item">The <see cref="Variant"/> item to insert.</param>
- public void Insert(int index, Variant item)
- {
- if (index < 0 || index > Count)
- throw new ArgumentOutOfRangeException(nameof(index));
- godot_variant variantValue = (godot_variant)item.NativeVar;
- var self = (godot_array)NativeValue;
- NativeFuncs.godotsharp_array_insert(ref self, index, variantValue);
- }
- /// <summary>
- /// Removes the first occurrence of the specified <paramref name="item"/>
- /// from this <see cref="Array"/>.
- /// </summary>
- /// <param name="item">The value to remove.</param>
- public bool Remove(Variant item)
- {
- int index = IndexOf(item);
- if (index >= 0)
- {
- RemoveAt(index);
- return true;
- }
- return false;
- }
- /// <summary>
- /// Removes an element from this <see cref="Array"/> by index.
- /// </summary>
- /// <param name="index">The index of the element to remove.</param>
- public void RemoveAt(int index)
- {
- if (index < 0 || index > Count)
- throw new ArgumentOutOfRangeException(nameof(index));
- var self = (godot_array)NativeValue;
- NativeFuncs.godotsharp_array_remove_at(ref self, index);
- }
- // ICollection
- /// <summary>
- /// Returns the number of elements in this <see cref="Array"/>.
- /// This is also known as the size or length of the array.
- /// </summary>
- /// <returns>The number of elements.</returns>
- public int Count => NativeValue.DangerousSelfRef.Size;
- bool ICollection.IsSynchronized => false;
- object ICollection.SyncRoot => false;
- bool ICollection<Variant>.IsReadOnly => false;
- /// <summary>
- /// Copies the elements of this <see cref="Array"/> to the given
- /// <see cref="Variant"/> C# array, starting at the given index.
- /// </summary>
- /// <param name="array">The array to copy to.</param>
- /// <param name="arrayIndex">The index to start at.</param>
- public void CopyTo(Variant[] array, int arrayIndex)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array), "Value cannot be null.");
- if (arrayIndex < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(arrayIndex),
- "Number was less than the array's lower bound in the first dimension.");
- }
- int count = Count;
- if (array.Length < (arrayIndex + count))
- {
- throw new ArgumentException(
- "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
- }
- unsafe
- {
- for (int i = 0; i < count; i++)
- {
- array[arrayIndex] = Variant.CreateCopyingBorrowed(NativeValue.DangerousSelfRef.Elements[i]);
- arrayIndex++;
- }
- }
- }
- void ICollection.CopyTo(System.Array array, int index)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array), "Value cannot be null.");
- if (index < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(index),
- "Number was less than the array's lower bound in the first dimension.");
- }
- int count = Count;
- if (array.Length < (index + count))
- {
- throw new ArgumentException(
- "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
- }
- unsafe
- {
- for (int i = 0; i < count; i++)
- {
- object obj = Marshaling.ConvertVariantToManagedObject(NativeValue.DangerousSelfRef.Elements[i]);
- array.SetValue(obj, index);
- index++;
- }
- }
- }
- // IEnumerable
- /// <summary>
- /// Gets an enumerator for this <see cref="Array"/>.
- /// </summary>
- /// <returns>An enumerator.</returns>
- public IEnumerator<Variant> GetEnumerator()
- {
- int count = Count;
- for (int i = 0; i < count; i++)
- {
- yield return this[i];
- }
- }
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
- /// <summary>
- /// Converts this <see cref="Array"/> to a string.
- /// </summary>
- /// <returns>A string representation of this array.</returns>
- public override string ToString()
- {
- var self = (godot_array)NativeValue;
- NativeFuncs.godotsharp_array_to_string(ref self, out godot_string str);
- using (str)
- return Marshaling.ConvertStringToManaged(str);
- }
- /// <summary>
- /// The variant returned via the <paramref name="elem"/> parameter is owned by the Array and must not be disposed.
- /// </summary>
- internal void GetVariantBorrowElementAt(int index, out godot_variant elem)
- {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index));
- GetVariantBorrowElementAtUnchecked(index, out elem);
- }
- /// <summary>
- /// The variant returned via the <paramref name="elem"/> parameter is owned by the Array and must not be disposed.
- /// </summary>
- internal unsafe void GetVariantBorrowElementAtUnchecked(int index, out godot_variant elem)
- {
- elem = NativeValue.DangerousSelfRef.Elements[index];
- }
- }
- /// <summary>
- /// Typed wrapper around Godot's Array class, an array of Variant
- /// typed elements allocated in the engine in C++. Useful when
- /// interfacing with the engine. Otherwise prefer .NET collections
- /// such as arrays or <see cref="List{T}"/>.
- /// </summary>
- /// <typeparam name="T">The type of the array.</typeparam>
- [SuppressMessage("ReSharper", "RedundantExtendsListEntry")]
- [SuppressMessage("Naming", "CA1710", MessageId = "Identifiers should have correct suffix")]
- public sealed class Array<[MustBeVariant] T> :
- IList<T>,
- IReadOnlyList<T>,
- ICollection<T>,
- IEnumerable<T>
- {
- // ReSharper disable StaticMemberInGenericType
- // Warning is about unique static fields being created for each generic type combination:
- // https://www.jetbrains.com/help/resharper/StaticMemberInGenericType.html
- // In our case this is exactly what we want.
- private static unsafe delegate* managed<in T, godot_variant> _convertToVariantCallback;
- private static unsafe delegate* managed<in godot_variant, T> _convertToManagedCallback;
- // ReSharper restore StaticMemberInGenericType
- static unsafe Array()
- {
- _convertToVariantCallback = VariantConversionCallbacks.GetToVariantCallback<T>();
- _convertToManagedCallback = VariantConversionCallbacks.GetToManagedCallback<T>();
- }
- private static unsafe void ValidateVariantConversionCallbacks()
- {
- if (_convertToVariantCallback == null || _convertToManagedCallback == null)
- {
- throw new InvalidOperationException(
- $"The array element type is not supported for conversion to Variant: '{typeof(T).FullName}'.");
- }
- }
- private readonly Array _underlyingArray;
- internal ref godot_array.movable NativeValue
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get => ref _underlyingArray.NativeValue;
- }
- /// <summary>
- /// Constructs a new empty <see cref="Array{T}"/>.
- /// </summary>
- public Array()
- {
- ValidateVariantConversionCallbacks();
- _underlyingArray = new Array();
- }
- /// <summary>
- /// Constructs a new <see cref="Array{T}"/> from the given collection's elements.
- /// </summary>
- /// <param name="collection">The collection of elements to construct from.</param>
- /// <returns>A new Godot Array.</returns>
- public Array(IEnumerable<T> collection)
- {
- ValidateVariantConversionCallbacks();
- if (collection == null)
- throw new ArgumentNullException(nameof(collection));
- _underlyingArray = new Array();
- foreach (T element in collection)
- Add(element);
- }
- /// <summary>
- /// Constructs a new <see cref="Array{T}"/> from the given items.
- /// </summary>
- /// <param name="array">The items to put in the new array.</param>
- /// <returns>A new Godot Array.</returns>
- public Array(T[] array) : this()
- {
- ValidateVariantConversionCallbacks();
- if (array == null)
- throw new ArgumentNullException(nameof(array));
- _underlyingArray = new Array();
- foreach (T element in array)
- Add(element);
- }
- /// <summary>
- /// Constructs a typed <see cref="Array{T}"/> from an untyped <see cref="Array"/>.
- /// </summary>
- /// <param name="array">The untyped array to construct from.</param>
- public Array(Array array)
- {
- ValidateVariantConversionCallbacks();
- _underlyingArray = array;
- }
- // Explicit name to make it very clear
- internal static Array<T> CreateTakingOwnershipOfDisposableValue(godot_array nativeValueToOwn)
- => new Array<T>(Array.CreateTakingOwnershipOfDisposableValue(nativeValueToOwn));
- /// <summary>
- /// Converts this typed <see cref="Array{T}"/> to an untyped <see cref="Array"/>.
- /// </summary>
- /// <param name="from">The typed array to convert.</param>
- public static explicit operator Array(Array<T> from)
- {
- return from?._underlyingArray;
- }
- /// <summary>
- /// Duplicates this <see cref="Array{T}"/>.
- /// </summary>
- /// <param name="deep">If <see langword="true"/>, performs a deep copy.</param>
- /// <returns>A new Godot Array.</returns>
- public Array<T> Duplicate(bool deep = false)
- {
- return new Array<T>(_underlyingArray.Duplicate(deep));
- }
- /// <summary>
- /// Resizes this <see cref="Array{T}"/> to the given size.
- /// </summary>
- /// <param name="newSize">The new size of the array.</param>
- /// <returns><see cref="Error.Ok"/> if successful, or an error code.</returns>
- public Error Resize(int newSize)
- {
- return _underlyingArray.Resize(newSize);
- }
- /// <summary>
- /// Shuffles the contents of this <see cref="Array{T}"/> into a random order.
- /// </summary>
- public void Shuffle()
- {
- _underlyingArray.Shuffle();
- }
- /// <summary>
- /// Concatenates these two <see cref="Array{T}"/>s.
- /// </summary>
- /// <param name="left">The first array.</param>
- /// <param name="right">The second array.</param>
- /// <returns>A new Godot Array with the contents of both arrays.</returns>
- public static Array<T> operator +(Array<T> left, Array<T> right)
- {
- if (left == null)
- {
- if (right == null)
- return new Array<T>();
- return right.Duplicate(deep: false);
- }
- if (right == null)
- return left.Duplicate(deep: false);
- return new Array<T>(left._underlyingArray + right._underlyingArray);
- }
- // IList<T>
- /// <summary>
- /// Returns the value at the given <paramref name="index"/>.
- /// </summary>
- /// <value>The value at the given <paramref name="index"/>.</value>
- public unsafe T this[int index]
- {
- get
- {
- _underlyingArray.GetVariantBorrowElementAt(index, out godot_variant borrowElem);
- return _convertToManagedCallback(borrowElem);
- }
- set
- {
- if (index < 0 || index >= Count)
- throw new ArgumentOutOfRangeException(nameof(index));
- var self = (godot_array)_underlyingArray.NativeValue;
- godot_variant* ptrw = NativeFuncs.godotsharp_array_ptrw(ref self);
- godot_variant* itemPtr = &ptrw[index];
- (*itemPtr).Dispose();
- *itemPtr = _convertToVariantCallback(value);
- }
- }
- /// <summary>
- /// Searches this <see cref="Array{T}"/> for an item
- /// and returns its index or -1 if not found.
- /// </summary>
- /// <param name="item">The item to search for.</param>
- /// <returns>The index of the item, or -1 if not found.</returns>
- public unsafe int IndexOf(T item)
- {
- using var variantValue = _convertToVariantCallback(item);
- var self = (godot_array)_underlyingArray.NativeValue;
- return NativeFuncs.godotsharp_array_index_of(ref self, variantValue);
- }
- /// <summary>
- /// Inserts a new item at a given position in the <see cref="Array{T}"/>.
- /// The position must be a valid position of an existing item,
- /// or the position at the end of the array.
- /// Existing items will be moved to the right.
- /// </summary>
- /// <param name="index">The index to insert at.</param>
- /// <param name="item">The item to insert.</param>
- public unsafe void Insert(int index, T item)
- {
- if (index < 0 || index > Count)
- throw new ArgumentOutOfRangeException(nameof(index));
- using var variantValue = _convertToVariantCallback(item);
- var self = (godot_array)_underlyingArray.NativeValue;
- NativeFuncs.godotsharp_array_insert(ref self, index, variantValue);
- }
- /// <summary>
- /// Removes an element from this <see cref="Array{T}"/> by index.
- /// </summary>
- /// <param name="index">The index of the element to remove.</param>
- public void RemoveAt(int index)
- {
- _underlyingArray.RemoveAt(index);
- }
- // ICollection<T>
- /// <summary>
- /// Returns the number of elements in this <see cref="Array{T}"/>.
- /// This is also known as the size or length of the array.
- /// </summary>
- /// <returns>The number of elements.</returns>
- public int Count => _underlyingArray.Count;
- bool ICollection<T>.IsReadOnly => false;
- /// <summary>
- /// Adds an item to the end of this <see cref="Array{T}"/>.
- /// This is the same as <c>append</c> or <c>push_back</c> in GDScript.
- /// </summary>
- /// <param name="item">The item to add.</param>
- /// <returns>The new size after adding the item.</returns>
- public unsafe void Add(T item)
- {
- using var variantValue = _convertToVariantCallback(item);
- var self = (godot_array)_underlyingArray.NativeValue;
- _ = NativeFuncs.godotsharp_array_add(ref self, variantValue);
- }
- /// <summary>
- /// Erases all items from this <see cref="Array{T}"/>.
- /// </summary>
- public void Clear()
- {
- _underlyingArray.Clear();
- }
- /// <summary>
- /// Checks if this <see cref="Array{T}"/> contains the given item.
- /// </summary>
- /// <param name="item">The item to look for.</param>
- /// <returns>Whether or not this array contains the given item.</returns>
- public bool Contains(T item) => IndexOf(item) != -1;
- /// <summary>
- /// Copies the elements of this <see cref="Array{T}"/> to the given
- /// C# array, starting at the given index.
- /// </summary>
- /// <param name="array">The C# array to copy to.</param>
- /// <param name="arrayIndex">The index to start at.</param>
- public void CopyTo(T[] array, int arrayIndex)
- {
- if (array == null)
- throw new ArgumentNullException(nameof(array), "Value cannot be null.");
- if (arrayIndex < 0)
- {
- throw new ArgumentOutOfRangeException(nameof(arrayIndex),
- "Number was less than the array's lower bound in the first dimension.");
- }
- int count = Count;
- if (array.Length < (arrayIndex + count))
- {
- throw new ArgumentException(
- "Destination array was not long enough. Check destIndex and length, and the array's lower bounds.");
- }
- for (int i = 0; i < count; i++)
- {
- array[arrayIndex] = this[i];
- arrayIndex++;
- }
- }
- /// <summary>
- /// Removes the first occurrence of the specified value
- /// from this <see cref="Array{T}"/>.
- /// </summary>
- /// <param name="item">The value to remove.</param>
- /// <returns>A <see langword="bool"/> indicating success or failure.</returns>
- public bool Remove(T item)
- {
- int index = IndexOf(item);
- if (index >= 0)
- {
- RemoveAt(index);
- return true;
- }
- return false;
- }
- // IEnumerable<T>
- /// <summary>
- /// Gets an enumerator for this <see cref="Array{T}"/>.
- /// </summary>
- /// <returns>An enumerator.</returns>
- public IEnumerator<T> GetEnumerator()
- {
- int count = _underlyingArray.Count;
- for (int i = 0; i < count; i++)
- {
- yield return this[i];
- }
- }
- IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
- /// <summary>
- /// Converts this <see cref="Array{T}"/> to a string.
- /// </summary>
- /// <returns>A string representation of this array.</returns>
- public override string ToString() => _underlyingArray.ToString();
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static implicit operator Variant(Array<T> from) => Variant.CreateFrom(from);
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- public static explicit operator Array<T>(Variant from) => from.AsGodotArray<T>();
- }
- }
|