2023-02-13 21:11:54 +08:00
using System ;
using System.Runtime.CompilerServices ;
2023-03-30 20:47:39 +08:00
using System.Runtime.InteropServices ;
2023-02-13 21:11:54 +08:00
namespace DCFApixels.DragonECS
{
2023-05-07 00:50:02 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
using static EcsGroup . ThrowHalper ;
#endif
2023-03-30 20:47:39 +08:00
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
public readonly ref struct EcsReadonlyGroup
2023-02-14 03:26:34 +08:00
{
2023-03-30 20:47:39 +08:00
private readonly EcsGroup _source ;
2023-04-24 00:19:07 +08:00
2023-04-01 22:29:34 +08:00
#region Constructors
2023-03-30 20:47:39 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsReadonlyGroup ( EcsGroup source ) = > _source = source ;
2023-04-01 22:29:34 +08:00
#endregion
#region Properties
2023-05-07 00:50:02 +08:00
public bool IsNull = > _source = = null ;
2023-04-24 00:31:03 +08:00
public EcsWorld World
2023-04-09 02:52:39 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > _source . World ;
}
2023-03-30 20:47:39 +08:00
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > _source . Count ;
}
2023-04-01 20:45:37 +08:00
public int CapacityDense
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > _source . CapacityDense ;
}
public int CapacitySparce
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > _source . CapacitySparce ;
}
2023-04-15 00:23:46 +08:00
public bool IsReleazed
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-05-26 00:24:38 +08:00
get = > _source . IsReleased ;
2023-04-15 00:23:46 +08:00
}
2023-05-07 00:50:02 +08:00
public int this [ int index ]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > _source [ index ] ;
}
2023-04-01 22:29:34 +08:00
#endregion
#region Methods
2023-03-30 20:47:39 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-05-07 00:50:02 +08:00
public bool Has ( int entityID ) = > _source . Has ( entityID ) ;
2023-03-30 20:47:39 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public EcsGroup . Enumerator GetEnumerator ( ) = > _source . GetEnumerator ( ) ;
2023-04-15 00:23:46 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-17 22:58:52 +08:00
public EcsGroup Clone ( ) = > _source . Clone ( ) ;
2023-05-07 00:50:02 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int First ( ) = > _source . First ( ) ;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Last ( ) = > _source . Last ( ) ;
2023-04-01 22:29:34 +08:00
#endregion
2023-04-08 23:01:10 +08:00
#region Object
public override string ToString ( )
{
if ( _source ! = null )
return _source . ToString ( ) ;
return "NULL" ;
}
2023-04-15 00:23:46 +08:00
public override int GetHashCode ( ) = > _source . GetHashCode ( ) ;
public override bool Equals ( object obj ) = > obj is EcsGroup group & & group = = this ;
public bool Equals ( EcsReadonlyGroup other ) = > _source = = other . _source ;
2023-04-08 23:01:10 +08:00
#endregion
#region Internal
2023-04-09 02:52:39 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-08 23:01:10 +08:00
internal EcsGroup GetGroupInternal ( ) = > _source ;
#endregion
2023-04-15 00:23:46 +08:00
#region operators
public static bool operator = = ( EcsReadonlyGroup a , EcsReadonlyGroup b ) = > a . Equals ( b ) ;
public static bool operator = = ( EcsReadonlyGroup a , EcsGroup b ) = > a . Equals ( b ) ;
public static bool operator ! = ( EcsReadonlyGroup a , EcsReadonlyGroup b ) = > ! a . Equals ( b ) ;
public static bool operator ! = ( EcsReadonlyGroup a , EcsGroup b ) = > ! a . Equals ( b ) ;
#endregion
2023-02-14 03:26:34 +08:00
}
2023-04-15 00:23:46 +08:00
public unsafe class EcsGroup : IDisposable , IEquatable < EcsGroup >
2023-02-13 21:11:54 +08:00
{
2023-04-20 20:03:26 +08:00
private EcsWorld _source ;
2023-03-30 10:46:57 +08:00
private int [ ] _dense ;
private int [ ] _sparse ;
private int _count ;
2023-05-26 00:24:38 +08:00
private bool _isReleased = true ;
2023-04-15 00:23:46 +08:00
2023-02-13 21:11:54 +08:00
#region Properties
2023-04-20 20:03:26 +08:00
public EcsWorld World = > _source ;
2023-03-30 10:46:57 +08:00
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > _count ;
}
2023-04-01 20:45:37 +08:00
public int CapacityDense
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > _dense . Length ;
}
public int CapacitySparce
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > _sparse . Length ;
}
2023-03-30 20:47:39 +08:00
public EcsReadonlyGroup Readonly
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get = > new EcsReadonlyGroup ( this ) ;
}
2023-05-26 00:24:38 +08:00
public bool IsReleased
2023-04-15 00:23:46 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-05-26 00:24:38 +08:00
get = > _isReleased ;
2023-04-15 00:23:46 +08:00
}
2023-05-07 00:50:02 +08:00
public int this [ int index ]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
if ( index < 0 | | index > = Count ) ThrowArgumentOutOfRange ( ) ;
#endif
return _dense [ index ] ;
}
}
2023-02-13 21:11:54 +08:00
#endregion
2023-04-17 22:58:52 +08:00
#region Constrcutors / Finalizer
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-20 20:03:26 +08:00
public static EcsGroup New ( EcsWorld world )
2023-04-01 20:45:37 +08:00
{
2023-04-15 00:23:46 +08:00
return world . GetGroupFromPool ( ) ;
2023-04-08 21:29:18 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-05-26 00:24:38 +08:00
internal EcsGroup ( EcsWorld world , int denseCapacity = 64 )
2023-04-08 21:29:18 +08:00
{
2023-04-15 00:23:46 +08:00
_source = world ;
2023-04-08 21:29:18 +08:00
_source . RegisterGroup ( this ) ;
2023-04-15 00:23:46 +08:00
_dense = new int [ denseCapacity ] ;
2023-04-18 19:35:42 +08:00
_sparse = new int [ world . Capacity ] ;
2023-04-08 21:29:18 +08:00
2023-03-30 10:46:57 +08:00
_count = 0 ;
2023-02-13 21:11:54 +08:00
}
#endregion
2023-04-24 16:48:18 +08:00
#region Has
//TODO переименовать в Has
2023-03-30 10:46:57 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-24 16:48:18 +08:00
public bool Has ( int entityID )
2023-03-30 10:46:57 +08:00
{
2023-04-15 00:23:46 +08:00
return _sparse [ entityID ] > 0 ;
2023-04-01 20:45:37 +08:00
}
#endregion
#region IndexOf
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int IndexOf ( int entityID )
{
return _sparse [ entityID ] ;
2023-03-30 10:46:57 +08:00
}
#endregion
2023-04-08 21:29:18 +08:00
#region Add / Remove
2023-04-01 20:45:37 +08:00
public void UncheckedAdd ( int entityID ) = > AddInternal ( entityID ) ;
2023-02-13 21:11:54 +08:00
public void Add ( int entityID )
{
2023-04-24 16:48:18 +08:00
if ( Has ( entityID ) ) return ;
2023-04-01 22:18:40 +08:00
AddInternal ( entityID ) ;
2023-04-01 20:45:37 +08:00
}
2023-04-01 22:18:40 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void AddInternal ( int entityID )
2023-04-01 20:45:37 +08:00
{
2023-05-07 00:50:02 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
if ( Has ( entityID ) ) ThrowAlreadyContains ( entityID ) ;
#endif
2023-04-01 20:45:37 +08:00
if ( + + _count > = _dense . Length )
2023-03-30 10:46:57 +08:00
Array . Resize ( ref _dense , _dense . Length < < 1 ) ;
_dense [ _count ] = entityID ;
_sparse [ entityID ] = _count ;
2023-02-13 21:11:54 +08:00
}
2023-04-01 20:45:37 +08:00
public void UncheckedRemove ( int entityID ) = > RemoveInternal ( entityID ) ;
2023-02-13 21:11:54 +08:00
public void Remove ( int entityID )
2023-04-01 20:45:37 +08:00
{
2023-04-24 16:48:18 +08:00
if ( ! Has ( entityID ) ) return ;
2023-04-01 20:45:37 +08:00
RemoveInternal ( entityID ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-01 22:18:40 +08:00
internal void RemoveInternal ( int entityID )
2023-02-13 21:11:54 +08:00
{
2023-05-07 00:50:02 +08:00
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
if ( ! Has ( entityID ) ) ThrowDoesNotContain ( entityID ) ;
#endif
2023-03-30 10:46:57 +08:00
_dense [ _sparse [ entityID ] ] = _dense [ _count ] ;
_sparse [ _dense [ _count - - ] ] = _sparse [ entityID ] ;
_sparse [ entityID ] = 0 ;
2023-02-13 21:11:54 +08:00
}
2023-04-24 16:48:18 +08:00
public void RemoveUnusedEntityIDs ( )
{
foreach ( var e in this )
{
if ( ! _source . IsUsed ( e ) )
2023-05-26 00:24:38 +08:00
RemoveInternal ( e ) ;
2023-04-24 16:48:18 +08:00
}
}
2023-02-13 21:11:54 +08:00
#endregion
2023-04-15 00:23:46 +08:00
#region Sort / Clear
2023-05-07 00:50:02 +08:00
//public void Sort() { } //TODO прошлай реализация сортировки не удачная, так как в dense могут храниться занчения больше чем dense.Length
2023-04-15 00:23:46 +08:00
public void Clear ( )
{
_count = 0 ;
2023-04-17 22:58:52 +08:00
//массив _dense нет смысла очищать, испольщуется только область от 1 до _count
2023-04-15 00:23:46 +08:00
for ( int i = 0 ; i < _sparse . Length ; i + + )
_sparse [ i ] = 0 ;
}
#endregion
#region CopyFrom / Clone
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void CopyFrom ( EcsReadonlyGroup group ) = > CopyFrom ( group . GetGroupInternal ( ) ) ;
2023-04-08 23:01:10 +08:00
public void CopyFrom ( EcsGroup group )
2023-04-08 21:29:18 +08:00
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
2023-04-20 18:23:23 +08:00
if ( group . World ! = _source ) throw new ArgumentException ( "groupFilter.WorldIndex != WorldIndex" ) ;
2023-04-09 02:52:39 +08:00
#endif
2023-04-17 22:58:52 +08:00
if ( _count > 0 )
Clear ( ) ;
2023-04-09 02:52:39 +08:00
foreach ( var item in group )
2023-05-26 00:24:38 +08:00
AddInternal ( item ) ;
2023-04-09 02:52:39 +08:00
}
2023-04-15 00:23:46 +08:00
public EcsGroup Clone ( )
2023-04-09 02:52:39 +08:00
{
2023-04-15 00:23:46 +08:00
EcsGroup result = _source . GetGroupFromPool ( ) ;
result . CopyFrom ( this ) ;
return result ;
2023-04-08 23:01:10 +08:00
}
2023-04-15 00:23:46 +08:00
#endregion
2023-04-01 21:16:08 +08:00
2023-04-08 23:01:10 +08:00
#region Set operations
/// <summary>as Union sets</summary>
2023-04-15 00:23:46 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void UnionWith ( EcsReadonlyGroup group ) = > UnionWith ( group . GetGroupInternal ( ) ) ;
2023-04-09 02:52:39 +08:00
/// <summary>as Union sets</summary>
2023-04-15 00:23:46 +08:00
public void UnionWith ( EcsGroup group )
2023-04-09 02:52:39 +08:00
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
2023-04-20 18:23:23 +08:00
if ( _source ! = group . World ) throw new ArgumentException ( "WorldIndex != groupFilter.WorldIndex" ) ;
2023-04-08 23:01:10 +08:00
#endif
foreach ( var item in group )
2023-04-24 16:48:18 +08:00
if ( ! Has ( item ) )
2023-05-26 00:24:38 +08:00
AddInternal ( item ) ;
2023-04-08 21:29:18 +08:00
}
2023-04-15 00:23:46 +08:00
2023-04-08 23:01:10 +08:00
/// <summary>as Except sets</summary>
2023-04-15 00:23:46 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void ExceptWith ( EcsReadonlyGroup group ) = > ExceptWith ( group . GetGroupInternal ( ) ) ;
/// <summary>as Except sets</summary>
public void ExceptWith ( EcsGroup group )
2023-04-08 21:29:18 +08:00
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
2023-04-20 18:23:23 +08:00
if ( _source ! = group . World ) throw new ArgumentException ( "WorldIndex != groupFilter.WorldIndex" ) ;
2023-04-09 02:52:39 +08:00
#endif
2023-04-10 22:22:17 +08:00
foreach ( var item in this )
2023-04-24 16:48:18 +08:00
if ( group . Has ( item ) )
2023-05-26 00:24:38 +08:00
RemoveInternal ( item ) ;
2023-04-09 02:52:39 +08:00
}
2023-04-15 00:23:46 +08:00
2023-04-08 23:01:10 +08:00
/// <summary>as Intersect sets</summary>
2023-04-15 00:23:46 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AndWith ( EcsReadonlyGroup group ) = > AndWith ( group . GetGroupInternal ( ) ) ;
2023-04-09 02:52:39 +08:00
/// <summary>as Intersect sets</summary>
2023-04-15 00:23:46 +08:00
public void AndWith ( EcsGroup group )
2023-04-09 02:52:39 +08:00
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
2023-04-20 18:23:23 +08:00
if ( World ! = group . World ) throw new ArgumentException ( "WorldIndex != groupFilter.WorldIndex" ) ;
2023-04-08 21:29:18 +08:00
#endif
2023-04-08 23:01:10 +08:00
foreach ( var item in this )
2023-04-24 16:48:18 +08:00
if ( ! group . Has ( item ) )
2023-05-26 00:24:38 +08:00
RemoveInternal ( item ) ;
2023-04-08 21:29:18 +08:00
}
2023-04-15 00:23:46 +08:00
2023-04-08 23:01:10 +08:00
/// <summary>as Symmetric Except sets</summary>
2023-04-15 00:23:46 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void XorWith ( EcsReadonlyGroup group ) = > XorWith ( group . GetGroupInternal ( ) ) ;
2023-04-09 02:52:39 +08:00
/// <summary>as Symmetric Except sets</summary>
2023-04-15 00:23:46 +08:00
public void XorWith ( EcsGroup group )
2023-04-09 02:52:39 +08:00
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
2023-04-20 18:23:23 +08:00
if ( _source ! = group . World ) throw new ArgumentException ( "WorldIndex != groupFilter.WorldIndex" ) ;
2023-04-08 21:29:18 +08:00
#endif
2023-04-08 23:01:10 +08:00
foreach ( var item in group )
2023-04-24 16:48:18 +08:00
if ( Has ( item ) )
2023-05-26 00:24:38 +08:00
RemoveInternal ( item ) ;
2023-04-08 23:01:10 +08:00
else
2023-05-26 00:24:38 +08:00
AddInternal ( item ) ;
2023-04-08 21:29:18 +08:00
}
2023-02-14 03:26:34 +08:00
#endregion
2023-04-10 22:22:17 +08:00
#region Static Set operations
/// <summary>as Except sets</summary>
2023-04-15 00:23:46 +08:00
/// <returns>new group from pool</returns>
public static EcsGroup Except ( EcsGroup a , EcsGroup b )
2023-04-10 22:22:17 +08:00
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
2023-04-20 18:23:23 +08:00
if ( a . _source ! = b . _source ) throw new ArgumentException ( "a.WorldIndex != b.WorldIndex" ) ;
2023-04-10 22:22:17 +08:00
#endif
EcsGroup result = a . _source . GetGroupFromPool ( ) ;
foreach ( var item in a )
2023-04-24 16:48:18 +08:00
if ( ! b . Has ( item ) )
2023-05-26 00:24:38 +08:00
result . AddInternal ( item ) ;
2023-04-10 22:22:17 +08:00
a . _source . ReleaseGroup ( a ) ;
2023-04-15 00:23:46 +08:00
return result ;
2023-04-10 22:22:17 +08:00
}
/// <summary>as Intersect sets</summary>
2023-04-15 00:23:46 +08:00
/// <returns>new group from pool</returns>
public static EcsGroup And ( EcsGroup a , EcsGroup b )
2023-04-10 22:22:17 +08:00
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
2023-04-20 18:23:23 +08:00
if ( a . _source ! = b . _source ) throw new ArgumentException ( "a.WorldIndex != b.WorldIndex" ) ;
2023-04-10 22:22:17 +08:00
#endif
EcsGroup result = a . _source . GetGroupFromPool ( ) ;
foreach ( var item in a )
2023-04-24 16:48:18 +08:00
if ( b . Has ( item ) )
2023-05-26 00:24:38 +08:00
result . AddInternal ( item ) ;
2023-04-10 22:22:17 +08:00
a . _source . ReleaseGroup ( a ) ;
2023-04-15 00:23:46 +08:00
return result ;
}
/// <summary>as Intersect sets</summary>
/// <returns>new group from pool</returns>
public static EcsGroup Union ( EcsGroup a , EcsGroup b )
{
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
2023-04-20 18:23:23 +08:00
if ( a . _source ! = b . _source ) throw new ArgumentException ( "a.WorldIndex != b.WorldIndex" ) ;
2023-04-15 00:23:46 +08:00
#endif
EcsGroup result = a . _source . GetGroupFromPool ( ) ;
foreach ( var item in a )
2023-05-26 00:24:38 +08:00
result . AddInternal ( item ) ;
2023-04-15 00:23:46 +08:00
foreach ( var item in a )
2023-04-23 15:57:35 +08:00
result . Add ( item ) ;
2023-04-15 00:23:46 +08:00
return result ;
2023-04-10 22:22:17 +08:00
}
#endregion
2023-02-13 21:11:54 +08:00
#region GetEnumerator
2023-03-30 10:46:57 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-02-13 21:11:54 +08:00
public Enumerator GetEnumerator ( )
{
return new Enumerator ( this ) ;
}
#endregion
2023-03-30 20:47:39 +08:00
#region Enumerator
2023-04-10 22:22:17 +08:00
public ref struct Enumerator // : IDisposable
2023-02-13 21:11:54 +08:00
{
2023-04-17 22:58:52 +08:00
// private readonly EcsGroup source;
2023-04-01 21:16:08 +08:00
private readonly int [ ] _dense ;
private readonly int _count ;
2023-04-06 23:40:47 +08:00
private int _index ;
2023-03-30 10:46:57 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-02-13 21:11:54 +08:00
public Enumerator ( EcsGroup group )
{
2023-04-17 22:58:52 +08:00
// source = group;
2023-04-01 21:16:08 +08:00
_dense = group . _dense ;
2023-04-23 22:55:13 +08:00
_count = group . _count ;
2023-04-06 23:40:47 +08:00
_index = 0 ;
2023-02-13 21:11:54 +08:00
}
2023-04-23 15:57:35 +08:00
public int Current
2023-02-13 21:11:54 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-23 15:57:35 +08:00
get = > _dense [ _index ] ;
2023-02-13 21:11:54 +08:00
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-08 00:47:35 +08:00
public bool MoveNext ( ) = > + + _index < = _count & & _count < _dense . Length ; // <= потму что отсчет начинается с индекса 1 //_count < _dense.Length дает среде понять что проверки на выход за границы не нужны
2023-04-10 22:22:17 +08:00
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-17 22:58:52 +08:00
//public void Dispose() => source.Unlock();
2023-02-13 21:11:54 +08:00
}
#endregion
2023-04-08 23:01:10 +08:00
2023-04-09 02:52:39 +08:00
#region Object
2023-04-08 23:01:10 +08:00
public override string ToString ( )
{
return string . Join ( ", " , _dense . AsSpan ( 1 , _count ) . ToArray ( ) ) ;
}
2023-04-15 00:23:46 +08:00
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 )
{
2023-04-26 16:45:37 +08:00
if ( ReferenceEquals ( other , null ) )
return false ;
2023-04-15 00:23:46 +08:00
if ( other . Count ! = Count )
return false ;
foreach ( var item in other )
2023-04-24 16:48:18 +08:00
if ( ! Has ( item ) )
2023-04-15 00:23:46 +08:00
return false ;
return true ;
}
public override int GetHashCode ( )
{
int hash = 0 ;
foreach ( var item in this )
2023-04-23 15:57:35 +08:00
hash ^ = 1 < < ( item % 32 ) ; //реализация от балды, так как не нужен, но фишка в том что хеш не учитывает порядок сущьностей, что явлется правильным поведением.
2023-04-15 00:23:46 +08:00
return hash ;
}
#endregion
2023-05-07 00:50:02 +08:00
#region OtherMethods
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int First ( ) = > this [ 0 ] ;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Last ( ) = > this [ _count - 1 ] ;
#endregion
2023-04-15 00:23:46 +08:00
#region operators
2023-04-26 16:45:37 +08:00
private static bool StaticEquals ( EcsGroup a , EcsReadonlyGroup b ) = > StaticEquals ( a , b . GetGroupInternal ( ) ) ;
private static bool StaticEquals ( EcsGroup a , EcsGroup b )
{
if ( ReferenceEquals ( a , null ) )
return false ;
return a . Equals ( b ) ;
}
public static bool operator = = ( EcsGroup a , EcsGroup b ) = > StaticEquals ( a , b ) ;
public static bool operator = = ( EcsGroup a , EcsReadonlyGroup b ) = > StaticEquals ( a , b ) ;
public static bool operator ! = ( EcsGroup a , EcsGroup b ) = > ! StaticEquals ( a , b ) ;
public static bool operator ! = ( EcsGroup a , EcsReadonlyGroup b ) = > ! StaticEquals ( a , b ) ;
2023-04-15 00:23:46 +08:00
#endregion
#region OnWorldResize
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void OnWorldResize ( int newSize )
{
Array . Resize ( ref _sparse , newSize ) ;
}
#endregion
#region IDisposable / Release
public void Dispose ( )
{
Release ( ) ;
}
public void Release ( )
{
2023-05-26 00:24:38 +08:00
_isReleased = true ;
2023-04-15 00:23:46 +08:00
_source . ReleaseGroup ( this ) ;
}
2023-04-08 23:01:10 +08:00
#endregion
2023-05-07 00:50:02 +08:00
#region ThrowHalper
#if ( DEBUG & & ! DISABLE_DEBUG ) | | ! DRAGONECS_NO_SANITIZE_CHECKS
internal static class ThrowHalper
{
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowAlreadyContains ( int entityID ) = > throw new EcsFrameworkException ( $"This group already contains entity {entityID}." ) ;
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowArgumentOutOfRange ( ) = > throw new ArgumentOutOfRangeException ( $"index is less than 0 or is equal to or greater than Count." ) ;
[MethodImpl(MethodImplOptions.NoInlining)]
public static void ThrowDoesNotContain ( int entityID ) = > throw new EcsFrameworkException ( $"This group does not contain entity {entityID}." ) ;
}
#endif
#endregion
2023-02-13 21:11:54 +08:00
}
2023-04-01 20:45:37 +08:00
2023-05-26 00:24:38 +08:00
#region Extensions
2023-04-01 20:45:37 +08:00
public static class EcsGroupExtensions
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Normalize < T > ( this EcsGroup self , ref T [ ] array )
{
if ( array . Length < self . CapacityDense ) Array . Resize ( ref array , self . CapacityDense ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Normalize < T > ( this EcsReadonlyGroup self , ref T [ ] array )
{
if ( array . Length < self . CapacityDense ) Array . Resize ( ref array , self . CapacityDense ) ;
}
}
2023-05-26 00:24:38 +08:00
#endregion
2023-02-13 21:11:54 +08:00
}