From fda8419dbfbd7c414a7f72ed60969f3efc3c89ca Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 2 Mar 2024 06:07:50 +0800 Subject: [PATCH] update collections, add EcsLongsSpan --- src/Collections/EcsGroup.cs | 125 +++++++++++------------------ src/Collections/EcsSpan.cs | 154 +++++++++++++++++++++++++++++++++--- 2 files changed, 188 insertions(+), 91 deletions(-) diff --git a/src/Collections/EcsGroup.cs b/src/Collections/EcsGroup.cs index 37c3656..8d7d697 100644 --- a/src/Collections/EcsGroup.cs +++ b/src/Collections/EcsGroup.cs @@ -44,6 +44,11 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _source.CapacityDense; } } + public EcsLongsSpan Longs + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _source.Longs; } + } public bool IsReleazed { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -70,19 +75,21 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] public int IndexOf(int entityID) { return _source.IndexOf(entityID); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EcsGroup.Enumerator GetEnumerator() { return _source.GetEnumerator(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public EcsGroup Clone() { return _source.Clone(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int[] Bake() { return _source.Bake(); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] public int Bake(ref int[] entities) { return _source.Bake(ref entities); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Bake(List entities) { _source.Bake(entities); } [MethodImpl(MethodImplOptions.AggressiveInlining)] + public EcsSpan Slice(int start) { return _source.Slice(start); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public EcsSpan Slice(int start, int length) { return _source.Slice(start, length); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public EcsSpan ToSpan() { return _source.ToSpan(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EcsSpan ToSpan(int start, int length) { return _source.ToSpan(start, length); } + public int[] ToArray() { return _source.ToArray(); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public EcsGroup.Enumerator GetEnumerator() { return _source.GetEnumerator(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] public EcsGroup.LongsIterator GetLongs() { return _source.GetLongs(); } @@ -118,7 +125,7 @@ namespace DCFApixels.DragonECS #region Internal [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal EcsGroup GetSource_Internal() => _source; + internal EcsGroup GetSource_Internal() { return _source; } #endregion #region Other @@ -174,6 +181,11 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return new EcsReadonlyGroup(this); } } + public EcsLongsSpan Longs + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return new EcsLongsSpan(this); } + } public bool IsReleased { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -291,7 +303,7 @@ namespace DCFApixels.DragonECS #region Clear public void Clear() { - if(_count == 0) + if (_count == 0) { return; } @@ -303,7 +315,7 @@ namespace DCFApixels.DragonECS } #endregion - #region CopyFrom/Clone/Bake/ToSpan + #region CopyFrom/Clone/Bake/Slice/ToSpan/ToArray public void CopyFrom(EcsGroup group) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS @@ -335,18 +347,14 @@ namespace DCFApixels.DragonECS Add_Internal(span[i]); } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public EcsGroup Clone() { EcsGroup result = _source.GetFreeGroup(); result.CopyFrom(this); return result; } - public int[] Bake() - { - int[] result = new int[_count]; - Array.Copy(_dense, 1, result, 0, _count); - return result; - } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public int Bake(ref int[] entities) { if (entities.Length < _count) @@ -356,6 +364,7 @@ namespace DCFApixels.DragonECS Array.Copy(_dense, 1, entities, 0, _count); return _count; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public void Bake(List entities) { entities.Clear(); @@ -364,17 +373,31 @@ namespace DCFApixels.DragonECS entities.Add(e); } } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public EcsSpan Slice(int start) + { + return Slice(start, _count - start + 1); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public EcsSpan Slice(int start, int length) + { + start++; +#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS + if (start < 1 || start + length > _count) { Throw.ArgumentOutOfRange(); } +#endif + return new EcsSpan(WorldID, _dense, start, length); + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] public EcsSpan ToSpan() { return new EcsSpan(WorldID, _dense, 1, _count); } - public EcsSpan ToSpan(int start, int length) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int[] ToArray() { - start -= 1; -#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS - if (start < 0 || start + length > _count) { Throw.ArgumentOutOfRange(); } -#endif - return new EcsSpan(WorldID, _dense, start, length); + int[] result = new int[_count]; + Array.Copy(_dense, 1, result, 0, _count); + return result; } #endregion @@ -848,16 +871,16 @@ namespace DCFApixels.DragonECS #endregion #region Other - public override string ToString() - { - return CollectionUtility.EntitiesToString(_dense.Skip(1).Take(_count), "group"); - } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int First() { return _dense[1]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public int Last() { return _dense[_count]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] internal void OnWorldResize(int newSize) { Array.Resize(ref _sparse, newSize); } + public override string ToString() + { + return CollectionUtility.EntitiesToString(_dense.Skip(1).Take(_count), "group"); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator EcsReadonlyGroup(EcsGroup a) { return a.Readonly; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -888,58 +911,4 @@ namespace DCFApixels.DragonECS } #endregion } - -#if false - public static class EcsGroupAliases - { - /// Alias for UnionWith - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Add(this EcsGroup self, EcsGroup group) - { - self.UnionWith(group); - } - /// Alias for UnionWith - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Add(this EcsGroup self, EcsReadonlyGroup group) - { - self.UnionWith(group); - } - /// Alias for ExceptWith - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Remove(this EcsGroup self, EcsGroup group) - { - self.ExceptWith(group); - } - /// Alias for ExceptWith - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Remove(this EcsGroup self, EcsReadonlyGroup group) - { - self.ExceptWith(group); - } - /// Alias for SymmetricExceptWith - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Xor(this EcsGroup self, EcsGroup group) - { - self.SymmetricExceptWith(group); - } - /// Alias for SymmetricExceptWith - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Xor(this EcsGroup self, EcsReadonlyGroup group) - { - self.SymmetricExceptWith(group); - } - /// Alias for IntersectWith - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void And(this EcsGroup self, EcsGroup group) - { - self.IntersectWith(group); - } - /// Alias for IntersectWith - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void And(this EcsGroup self, EcsReadonlyGroup group) - { - self.IntersectWith(group); - } - } -#endif } \ No newline at end of file diff --git a/src/Collections/EcsSpan.cs b/src/Collections/EcsSpan.cs index 7494ea0..f248471 100644 --- a/src/Collections/EcsSpan.cs +++ b/src/Collections/EcsSpan.cs @@ -33,6 +33,11 @@ namespace DCFApixels.DragonECS [MethodImpl(MethodImplOptions.AggressiveInlining)] get { return _values.Length; } } + public EcsLongsSpan Longs + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return new EcsLongsSpan(this); } + } public int this[int index] { [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -66,12 +71,7 @@ namespace DCFApixels.DragonECS } #endregion - #region Methdos - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int[] Bake() - { - return _values.ToArray(); - } + #region Bake/Slice/ToArry [MethodImpl(MethodImplOptions.AggressiveInlining)] public int Bake(ref int[] entities) { @@ -79,8 +79,7 @@ namespace DCFApixels.DragonECS { Array.Resize(ref entities, _values.Length); } - int[] result = new int[_values.Length]; - _values.CopyTo(result); + _values.CopyTo(entities); return _values.Length; } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -92,6 +91,12 @@ namespace DCFApixels.DragonECS entities.Add(e); } } + [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)); } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int[] ToArray() { return _values.ToArray(); } #endregion #region operators @@ -106,11 +111,9 @@ namespace DCFApixels.DragonECS #region Other [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EcsSpan Slice(int start) { return new EcsSpan(_worldID, _values.Slice(start)); } + public int First() { return _values[0]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public EcsSpan Slice(int start, int length) { return new EcsSpan(_worldID, _values.Slice(start, length)); } - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public int[] ToArray() { return _values.ToArray(); } + public int Last() { return _values[_values.Length - 1]; } public override string ToString() { return CollectionUtility.EntitiesToString(_values.ToArray(), "span"); @@ -149,7 +152,132 @@ namespace DCFApixels.DragonECS span._values.CopyTo(_values); _worldID = span._worldID; } + public DebuggerProxy(EcsLongsSpan span) : this(span.ToSpan()) { } } #endregion } -} + + [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; } + } + public int this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get { return _source[index]; } + } + #endregion + + #region Constructors + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal EcsLongsSpan(EcsSpan span) + { + _source = span; + } + #endregion + + #region Bake/Slice/ToArry + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int Bake(ref entlong[] entities) + { + EcsWorld world = World; + if (entities.Length < _source.Count) + { + Array.Resize(ref entities, _source.Count); + } + for (int i = 0; i < _source.Count; i++) + { + entities[i] = world.GetEntityLong(_source[i]); + } + return _source.Count; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public void Bake(List entities) + { + entities.Clear(); + foreach (var e in this) + { + entities.Add(e); + } + } + [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; } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public int[] ToArray() { return _source.ToArray(); } + #endregion + + #region operators + public static bool operator ==(EcsLongsSpan left, EcsLongsSpan right) { return left._source == right._source; } + public static bool operator !=(EcsLongsSpan left, EcsLongsSpan right) { return left._source != right._source; } + #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.Enumerator _enumerator; + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public Enumerator(EcsWorld world, ReadOnlySpan.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 // Устаревший член переопределяет неустаревший член + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static implicit operator EcsSpan(EcsLongsSpan a) { return a.ToSpan(); } + #endregion + } +} \ No newline at end of file