diff --git a/src/Builtin/BaseProcesses.cs b/src/Builtin/BaseProcesses.cs index f6fc777..532c490 100644 --- a/src/Builtin/BaseProcesses.cs +++ b/src/Builtin/BaseProcesses.cs @@ -35,8 +35,9 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG for (int i = 0; i < targets.Length && targets.Length <= _markers.Length; i++) { - using (_markers[i].Auto()) - targets[i].PreInit(pipeline); + _markers[i].Begin(); + targets[i].PreInit(pipeline); + _markers[i].End(); } #else foreach (var item in targets) item.PreInit(pipeline); @@ -64,8 +65,9 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG for (int i = 0; i < targets.Length && targets.Length <= _markers.Length; i++) { - using (_markers[i].Auto()) - targets[i].Init(pipeline); + _markers[i].Begin(); + targets[i].Init(pipeline); + _markers[i].End(); } #else foreach (var item in targets) item.Init(pipeline); @@ -93,9 +95,9 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG for (int i = 0; i < targets.Length && targets.Length <= _markers.Length; i++) { - using (_markers[i].Auto()) - targets[i].Run(pipeline); - + _markers[i].Begin(); + targets[i].Run(pipeline); + _markers[i].End(); } #else foreach (var item in targets) item.Run(pipeline); @@ -123,8 +125,9 @@ namespace DCFApixels.DragonECS #if DEBUG && !DISABLE_DEBUG for (int i = 0; i < targets.Length && targets.Length <= _markers.Length; i++) { - using (_markers[i].Auto()) - targets[i].Destroy(pipeline); + _markers[i].Begin(); + targets[i].Destroy(pipeline); + _markers[i].End(); } #else foreach (var item in targets) item.Destroy(pipeline); diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index ab5815d..62b5140 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -468,7 +469,7 @@ namespace DCFApixels.DragonECS #endregion #region Object - public override string ToString() => string.Join(", ", _dense.AsSpan(1, _count).ToArray()); + public override string ToString() => string.Join(", ", _dense.Cast(), 0, _count); public override bool Equals(object obj) => obj is EcsGroup group && Equals(group); public bool Equals(EcsReadonlyGroup other) => Equals(other.GetGroupInternal()); public bool Equals(EcsGroup other) diff --git a/src/EcsSubject.cs b/src/EcsSubject.cs index 37e063c..eabcb21 100644 --- a/src/EcsSubject.cs +++ b/src/EcsSubject.cs @@ -45,8 +45,8 @@ namespace DCFApixels.DragonECS { _world = world; _subjects = new List(); - _inc = new HashSet(8); - _exc = new HashSet(4); + _inc = new HashSet(); + _exc = new HashSet(); } internal static TSubject Build(EcsWorld world) where TSubject : EcsSubject { diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index 73c0b7a..4b63300 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -33,15 +33,14 @@ public EcsReadonlyGroup ExecuteFor(EcsReadonlyGroup sourceGroup) { #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS - using (_executeWhere.Auto()) + _executeWhere.Begin(); + if (sourceGroup.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения. #endif - { + _subject.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); #if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS - if (sourceGroup.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения. + _executeWhere.End(); #endif - _subject.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); - return _filteredGroup.Readonly; - } + return _filteredGroup.Readonly; } #endregion } diff --git a/src/Utils/ReadOnlySpanDummy.cs b/src/Utils/ReadOnlySpanDummy.cs new file mode 100644 index 0000000..74ddd8b --- /dev/null +++ b/src/Utils/ReadOnlySpanDummy.cs @@ -0,0 +1,187 @@ +#if ENABLE_DUMMY_SPAN +using System; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using EditorBrowsableAttribute = System.ComponentModel.EditorBrowsableAttribute; +using EditorBrowsableState = System.ComponentModel.EditorBrowsableState; + +namespace DCFApixels.DragonECS +{ + internal static class ThrowHelper + { + public static void ThrowIndexOutOfRangeException() => throw new IndexOutOfRangeException(); + public static void ThrowArgumentOutOfRangeException() => throw new ArgumentOutOfRangeException(); + public static void ThrowInvalidOperationException() => throw new InvalidOperationException(); + } + [DebuggerDisplay("{ToString(),raw}")] + public readonly ref struct ReadOnlySpan + { + public static ReadOnlySpan Empty => new ReadOnlySpan(null); + + internal readonly T[] _array; + private readonly int _start; + private readonly int _length; + + #region Properties + public int Length => _length; + public bool IsEmpty => _length == 0; + public ref readonly T this[int index] + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get + { + if ((uint)index >= (uint)_length || (uint)index < 0) + ThrowHelper.ThrowIndexOutOfRangeException(); + return ref _array[index + _start]; + } + } + #endregion + + #region Constructors + public ReadOnlySpan(T[] array) + { + _array = array ?? Array.Empty(); + _start = 0; + _length = array.Length; + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan(T[] array, int start, int length) + { + if (array == null) + { + if (start != 0 || length != 0) + ThrowHelper.ThrowArgumentOutOfRangeException(); + _array = Array.Empty(); + _start = 0; + _length = 0; + return; + } + + if ((uint)start > (uint)array.Length || (uint)length > (uint)(array.Length - start)) + ThrowHelper.ThrowArgumentOutOfRangeException(); + + _array = array; + _start = start; + _length = length; + } + #endregion + + #region Object + [Obsolete("Equals() on ReadOnlySpan 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 ReadOnlySpan will always throw an exception.")] + [EditorBrowsable(EditorBrowsableState.Never)] + public override int GetHashCode() => throw new NotSupportedException(); + public override string ToString() + { + //if (typeof(T) == typeof(char)) + // return new string(new ReadOnlySpan(ref Unsafe.As(ref _reference), _length)); + return $"System.ReadOnlySpan<{typeof(T).Name}>[{_length}]"; + } + #endregion + + #region operators + public static bool operator !=(ReadOnlySpan left, ReadOnlySpan right) => !(left == right); + + public static implicit operator ReadOnlySpan(T[] array) => new ReadOnlySpan(array); + + public static implicit operator ReadOnlySpan(ArraySegment segment) => new ReadOnlySpan(segment.Array, segment.Offset, segment.Count); + public static bool operator ==(ReadOnlySpan left, ReadOnlySpan right) => left._length == right._length && left._array == right._array; + #endregion + + #region Enumerator + public Enumerator GetEnumerator() => new Enumerator(this); + public ref struct Enumerator + { + private readonly ReadOnlySpan _span; + private int _index; + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal Enumerator(ReadOnlySpan span) + { + _span = span; + _index = span._start - 1; + } + public ref readonly T Current + { + [MethodImpl(MethodImplOptions.AggressiveInlining)] + get => ref _span[_index]; + } + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public bool MoveNext() + { + int index = _index + 1; + if (index < _span.Length) + { + _index = index; + return true; + } + return false; + } + } + #endregion + + #region Other + [EditorBrowsable(EditorBrowsableState.Never)] + public ref readonly T GetPinnableReference() + { + if (_length != 0) ThrowHelper.ThrowInvalidOperationException(); + return ref _array[0]; + } + + //[MethodImpl(MethodImplOptions.AggressiveInlining)] + //public void CopyTo(Span destination) + //{ + // if ((uint)_length <= (uint)destination.Length) + // { + // Buffer.Memmove(ref destination._reference, ref _reference, (uint)_length); + // } + // else + // { + // ThrowHelper.ThrowArgumentException_DestinationTooShort(); + // } + //} + + //public bool TryCopyTo(Span destination) + //{ + // bool retVal = false; + // if ((uint)_length <= (uint)destination.Length) + // { + // Buffer.Memmove(ref destination._reference, ref _reference, (uint)_length); + // retVal = true; + // } + // return retVal; + //} + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan Slice(int start) + { + if ((uint)start > (uint)_length) + ThrowHelper.ThrowArgumentOutOfRangeException(); + + return new ReadOnlySpan(_array, _start + start, _length - start); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public ReadOnlySpan Slice(int start, int length) + { + if ((uint)start > (uint)_length || (uint)length > (uint)(_length - start)) + ThrowHelper.ThrowArgumentOutOfRangeException(); + + return new ReadOnlySpan(_array, _start + start, length); + } + + public T[] ToArray() + { + if (_length == 0) + return Array.Empty(); + var result = new T[_length]; + Array.Copy(_array, _start, result, 0, _length); + return result; + } + #endregion + } +} +#endif \ No newline at end of file diff --git a/src/Utils/ReadOnlySpanDummy.cs.meta b/src/Utils/ReadOnlySpanDummy.cs.meta new file mode 100644 index 0000000..40c53b3 --- /dev/null +++ b/src/Utils/ReadOnlySpanDummy.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: bfb00ad58c175a84388c316daf9b03ae +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: