DragonECS/src/Collections/EcsSpan.cs

305 lines
11 KiB
C#
Raw Normal View History

2024-02-07 22:16:41 +08:00
using DCFApixels.DragonECS.Internal;
2024-01-05 23:49:29 +08:00
using System;
using System.Collections.Generic;
2023-12-24 15:40:19 +08:00
using System.ComponentModel;
2024-01-05 22:16:48 +08:00
using System.Diagnostics;
2023-12-24 15:40:19 +08:00
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
2024-04-28 19:43:10 +08:00
#if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices;
[Il2CppSetOption (Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
2024-01-05 22:16:48 +08:00
[DebuggerTypeProxy(typeof(DebuggerProxy))]
2023-12-24 15:40:19 +08:00
public readonly ref struct EcsSpan
{
private readonly ReadOnlySpan<int> _values;
2024-04-16 12:46:09 +08:00
private readonly short _worldID;
2023-12-24 15:40:19 +08:00
#region Properties
2024-03-02 04:20:34 +08:00
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _worldID == 0; }
}
public int WorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 04:20:34 +08:00
get { return _worldID; }
}
public EcsWorld World
{
2024-03-02 04:20:34 +08:00
get { return EcsWorld.GetWorld(_worldID); }
}
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 04:20:34 +08:00
get { return _values.Length; }
}
2024-03-02 06:07:50 +08:00
public EcsLongsSpan Longs
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return new EcsLongsSpan(this); }
}
2024-04-28 19:43:10 +08:00
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.ArrayBoundsChecks, true)]
#endif
2024-01-08 13:39:38 +08:00
public int this[int index]
2023-12-24 15:40:19 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 04:20:34 +08:00
get { return _values[index]; }
2024-01-07 19:32:16 +08:00
}
2023-12-24 15:40:19 +08:00
#endregion
#region Constructors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-04-16 12:46:09 +08:00
internal EcsSpan(short worldID, ReadOnlySpan<int> span)
2023-12-24 15:40:19 +08:00
{
_worldID = worldID;
_values = span;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-04-16 12:46:09 +08:00
internal EcsSpan(short worldID, int[] array)
2023-12-24 15:40:19 +08:00
{
_worldID = worldID;
2024-03-02 04:20:34 +08:00
_values = new ReadOnlySpan<int>(array);
2023-12-24 15:40:19 +08:00
}
2024-04-16 12:46:09 +08:00
internal EcsSpan(short worldID, int[] array, int length)
2023-12-24 15:40:19 +08:00
{
_worldID = worldID;
_values = new ReadOnlySpan<int>(array, 0, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-04-16 12:46:09 +08:00
internal EcsSpan(short worldID, int[] array, int start, int length)
2023-12-24 15:40:19 +08:00
{
_worldID = worldID;
_values = new ReadOnlySpan<int>(array, start, length);
}
#endregion
#region Slice/ToArray
2024-03-02 06:07:50 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Slice(int start) { return new EcsSpan(_worldID, _values.Slice(start)); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan Slice(int start, int length) { return new EcsSpan(_worldID, _values.Slice(start, length)); }
public int[] ToArray() { return _values.ToArray(); }
public int ToArray(ref int[] dynamicBuffer)
{
if (dynamicBuffer.Length < _values.Length)
{
Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_values.Length));
}
int i = 0;
foreach (var e in this)
{
dynamicBuffer[i++] = e;
}
return i;
}
public void ToCollection(ICollection<int> collection)
{
foreach (var e in this)
{
collection.Add(e);
}
}
2023-12-31 17:33:48 +08:00
#endregion
2023-12-24 15:40:19 +08:00
#region operators
2024-03-02 04:20:34 +08:00
public static bool operator ==(EcsSpan left, EcsSpan right) { return left._values == right._values; }
public static bool operator !=(EcsSpan left, EcsSpan right) { return left._values != right._values; }
2023-12-24 15:40:19 +08:00
#endregion
#region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 04:20:34 +08:00
public ReadOnlySpan<int>.Enumerator GetEnumerator() { return _values.GetEnumerator(); }
2023-12-24 15:40:19 +08:00
#endregion
#region Other
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 06:07:50 +08:00
public int First() { return _values[0]; }
2023-12-24 15:40:19 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 06:07:50 +08:00
public int Last() { return _values[_values.Length - 1]; }
2024-03-02 04:20:34 +08:00
public override string ToString()
{
return CollectionUtility.EntitiesToString(_values.ToArray(), "span");
}
2024-01-05 22:16:48 +08:00
#pragma warning disable CS0809 // Устаревший член переопределяет неустаревший член
[Obsolete("Equals() on EcsSpan will always throw an exception. Use the equality operator instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
2024-03-02 04:20:34 +08:00
public override bool Equals(object obj) { throw new NotSupportedException(); }
2024-01-05 22:16:48 +08:00
[Obsolete("GetHashCode() on EcsSpan will always throw an exception.")]
[EditorBrowsable(EditorBrowsableState.Never)]
2024-03-02 04:20:34 +08:00
public override int GetHashCode() { throw new NotSupportedException(); }
2024-01-05 22:16:48 +08:00
#pragma warning restore CS0809 // Устаревший член переопределяет неустаревший член
internal class DebuggerProxy
{
private int[] _values;
2024-04-16 12:46:09 +08:00
private short _worldID;
2024-03-02 04:20:34 +08:00
public EcsWorld World { get { return EcsWorld.GetWorld(_worldID); } }
2024-02-29 22:42:33 +08:00
public EntitySlotInfo[] Entities
2024-01-05 22:16:48 +08:00
{
get
{
2024-02-29 22:42:33 +08:00
EntitySlotInfo[] result = new EntitySlotInfo[_values.Length];
2024-01-05 22:16:48 +08:00
int i = 0;
foreach (var e in _values)
2024-02-29 22:42:33 +08:00
{
result[i++] = World.GetEntitySlotInfoDebug(e);
}
2024-01-05 22:16:48 +08:00
return result;
}
}
2024-03-02 04:20:34 +08:00
public int Count { get { return _values.Length; } }
2024-01-05 22:16:48 +08:00
public DebuggerProxy(EcsSpan span)
{
_values = new int[span.Count];
2024-01-05 22:16:48 +08:00
span._values.CopyTo(_values);
_worldID = span._worldID;
}
2024-03-02 06:07:50 +08:00
public DebuggerProxy(EcsLongsSpan span) : this(span.ToSpan()) { }
2024-01-05 22:16:48 +08:00
}
2023-12-24 15:40:19 +08:00
#endregion
}
2024-03-02 06:07:50 +08:00
2024-04-28 19:43:10 +08:00
#if ENABLE_IL2CPP
[Il2CppSetOption (Option.NullChecks, false)]
[Il2CppSetOption(Option.ArrayBoundsChecks, false)]
#endif
2024-03-02 06:07:50 +08:00
[DebuggerTypeProxy(typeof(EcsSpan.DebuggerProxy))]
public readonly ref struct EcsLongsSpan
{
private readonly EcsSpan _source;
#region Properties
public bool IsNull
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source.IsNull; }
}
public int WorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source.WorldID; }
}
public EcsWorld World
{
get { return _source.World; }
}
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source.Count; }
}
2024-04-28 19:43:10 +08:00
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.ArrayBoundsChecks, true)]
#endif
2024-03-02 17:12:41 +08:00
public entlong this[int index]
2024-03-02 06:07:50 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 17:12:41 +08:00
get { return World.GetEntityLong(_source[index]); }
2024-03-02 06:07:50 +08:00
}
#endregion
#region Constructors
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal EcsLongsSpan(EcsSpan span)
{
_source = span;
}
#endregion
2024-03-02 20:51:18 +08:00
#region Slice/ToSpan/ToArry
2024-03-02 06:07:50 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsLongsSpan Slice(int start) { return new EcsLongsSpan(_source.Slice(start)); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsLongsSpan Slice(int start, int length) { return new EcsLongsSpan(_source.Slice(start, length)); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsSpan ToSpan() { return _source; }
public entlong[] ToArray()
{
entlong[] result = new entlong[_source.Count];
int i = 0;
foreach (var e in this)
{
result[i++] = e;
}
return result;
}
public int ToArray(ref entlong[] dynamicBuffer)
{
if (dynamicBuffer.Length < _source.Count)
{
Array.Resize(ref dynamicBuffer, ArrayUtility.NormalizeSizeToPowerOfTwo(_source.Count));
}
int i = 0;
foreach (var e in this)
{
dynamicBuffer[i++] = e;
}
return i;
}
public void ToCollection(ICollection<entlong> collection)
{
foreach (var e in this)
{
collection.Add(e);
}
}
2024-03-02 06:07:50 +08:00
#endregion
#region operators
2024-10-05 18:05:33 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 06:07:50 +08:00
public static bool operator ==(EcsLongsSpan left, EcsLongsSpan right) { return left._source == right._source; }
2024-10-05 18:05:33 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 06:07:50 +08:00
public static bool operator !=(EcsLongsSpan left, EcsLongsSpan right) { return left._source != right._source; }
2024-10-05 18:05:33 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator EcsSpan(EcsLongsSpan a) { return a.ToSpan(); }
2024-03-02 06:07:50 +08:00
#endregion
#region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator GetEnumerator() { return new Enumerator(_source.World, _source.GetEnumerator()); }
public ref struct Enumerator
{
private readonly EcsWorld _world;
private ReadOnlySpan<int>.Enumerator _enumerator;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Enumerator(EcsWorld world, ReadOnlySpan<int>.Enumerator enumerator)
{
_world = world;
_enumerator = enumerator;
}
public entlong Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _world.GetEntityLong(_enumerator.Current); }
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool MoveNext() { return _enumerator.MoveNext(); }
}
#endregion
#region Other
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public entlong First() { return _source.World.GetEntityLong(_source.First()); }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public entlong Last() { return _source.World.GetEntityLong(_source.Last()); }
public override string ToString()
{
return CollectionUtility.EntitiesToString(_source.ToArray(), "longs_span");
}
#pragma warning disable CS0809 // Устаревший член переопределяет неустаревший член
[Obsolete("Equals() on EcsLongSpan will always throw an exception. Use the equality operator instead.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public override bool Equals(object obj) { throw new NotSupportedException(); }
[Obsolete("GetHashCode() on EcsLongSpan will always throw an exception.")]
[EditorBrowsable(EditorBrowsableState.Never)]
public override int GetHashCode() { throw new NotSupportedException(); }
#pragma warning restore CS0809 // Устаревший член переопределяет неустаревший член
#endregion
}
}