2024-01-07 18:52:54 +08:00
using DCFApixels.DragonECS.Internal ;
2023-06-26 02:53:55 +08:00
using System ;
2023-05-07 00:50:02 +08:00
using System.Collections.Generic ;
using System.Reflection ;
using System.Runtime.CompilerServices ;
namespace DCFApixels.DragonECS
{
2024-04-22 17:01:13 +08:00
public abstract class EcsAspect : ITemplateNode
2023-05-07 00:50:02 +08:00
{
2024-01-07 18:52:54 +08:00
internal EcsWorld _source ;
internal EcsMask _mask ;
2024-03-26 16:06:03 +08:00
private bool _isBuilt = false ;
[ThreadStatic]
2024-03-26 18:09:13 +08:00
private static Stack < Builder > _constructorBuildersStack = null ;
private static Stack < Builder > GetBuildersStack ( )
{
2024-04-09 00:19:43 +08:00
if ( _constructorBuildersStack = = null )
2024-03-26 18:09:13 +08:00
{
_constructorBuildersStack = new Stack < Builder > ( ) ;
}
return _constructorBuildersStack ;
}
2024-03-26 16:06:03 +08:00
protected static IncludeMarker Inc
{
get
{
2024-03-26 18:09:13 +08:00
var buildersStack = GetBuildersStack ( ) ;
if ( buildersStack . Count < = 0 )
2024-04-22 17:37:37 +08:00
{
Throw . Aspect_CanOnlyBeUsedDuringInitialization ( nameof ( Inc ) ) ;
2024-03-26 16:06:03 +08:00
}
2024-03-26 18:09:13 +08:00
return buildersStack . Peek ( ) . Inc ;
2024-03-26 16:06:03 +08:00
}
}
protected static ExcludeMarker Exc
{
get
{
2024-03-26 18:09:13 +08:00
var buildersStack = GetBuildersStack ( ) ;
if ( buildersStack . Count < = 0 )
2024-04-22 17:37:37 +08:00
{
Throw . Aspect_CanOnlyBeUsedDuringInitialization ( nameof ( Exc ) ) ;
2024-03-26 16:06:03 +08:00
}
2024-03-26 18:09:13 +08:00
return buildersStack . Peek ( ) . Exc ;
2024-03-26 16:06:03 +08:00
}
}
protected static OptionalMarker Opt
{
get
{
2024-03-26 18:09:13 +08:00
var buildersStack = GetBuildersStack ( ) ;
if ( buildersStack . Count < = 0 )
2024-04-22 17:37:37 +08:00
{
Throw . Aspect_CanOnlyBeUsedDuringInitialization ( nameof ( Opt ) ) ;
2024-03-26 16:06:03 +08:00
}
2024-03-26 18:09:13 +08:00
return buildersStack . Peek ( ) . Opt ;
2024-03-26 16:06:03 +08:00
}
}
2024-01-07 18:52:54 +08:00
2024-02-11 01:14:54 +08:00
private UnsafeArray < int > _sortIncBuffer ;
private UnsafeArray < int > _sortExcBuffer ;
private UnsafeArray < EcsMaskChunck > _sortIncChunckBuffer ;
private UnsafeArray < EcsMaskChunck > _sortExcChunckBuffer ;
2024-01-07 18:52:54 +08:00
2023-05-07 00:50:02 +08:00
#region Properties
2024-03-02 21:45:09 +08:00
public EcsMask Mask
{
get { return _mask ; }
}
public EcsWorld World
{
get { return _source ; }
}
public bool IsInit
{
2024-03-26 16:06:03 +08:00
get { return _isBuilt ; }
2024-03-02 21:45:09 +08:00
}
2023-05-07 00:50:02 +08:00
#endregion
#region Methods
2024-02-13 21:00:01 +08:00
public bool IsMatches ( int entityID )
{
return _source . IsMatchesMask ( _mask , entityID ) ;
}
2023-05-07 00:50:02 +08:00
#endregion
#region Builder
protected virtual void Init ( Builder b ) { }
2024-02-11 01:28:18 +08:00
public sealed class Builder
2023-05-07 00:50:02 +08:00
{
private EcsWorld _world ;
2024-01-07 19:32:16 +08:00
private EcsMask . Builder _maskBuilder ;
2024-03-08 20:40:19 +08:00
public IncludeMarker Inc
{
get { return new IncludeMarker ( this ) ; }
}
public ExcludeMarker Exc
{
get { return new ExcludeMarker ( this ) ; }
}
public OptionalMarker Opt
{
get { return new OptionalMarker ( this ) ; }
}
2023-05-07 00:50:02 +08:00
public EcsWorld World = > _world ;
private Builder ( EcsWorld world )
{
_world = world ;
2024-01-11 00:48:39 +08:00
_maskBuilder = EcsMask . New ( world ) ;
2023-05-07 00:50:02 +08:00
}
2024-01-07 19:32:16 +08:00
internal static unsafe TAspect New < TAspect > ( EcsWorld world ) where TAspect : EcsAspect
2023-05-07 00:50:02 +08:00
{
Builder builder = new Builder ( world ) ;
2023-06-22 14:31:13 +08:00
Type aspectType = typeof ( TAspect ) ;
EcsAspect newAspect ;
2024-02-23 18:34:40 +08:00
//TODO добавить оповещение что инициализация через конструктор не работает
#if ! REFLECTION_DISABLED
ConstructorInfo constructorInfo = aspectType . GetConstructor ( BindingFlags . Instance | BindingFlags . Public | BindingFlags . NonPublic , null , new Type [ ] { typeof ( Builder ) } , null ) ;
2024-03-26 16:06:03 +08:00
2024-03-26 18:09:13 +08:00
var buildersStack = GetBuildersStack ( ) ;
buildersStack . Push ( builder ) ;
2023-05-07 00:50:02 +08:00
if ( constructorInfo ! = null )
{
2023-06-22 14:31:13 +08:00
newAspect = ( EcsAspect ) constructorInfo . Invoke ( new object [ ] { builder } ) ;
2023-05-07 00:50:02 +08:00
}
else
2024-02-23 18:34:40 +08:00
#endif
2023-05-07 00:50:02 +08:00
{
2024-02-23 18:34:40 +08:00
#pragma warning disable IL2091 // Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The generic parameter of the source method or type does not have matching annotations.
newAspect = Activator . CreateInstance < TAspect > ( ) ;
#pragma warning restore IL2091
2023-05-07 00:50:02 +08:00
}
2024-03-26 18:09:13 +08:00
newAspect . Init ( builder ) ;
buildersStack . Pop ( ) ;
2024-01-07 18:52:54 +08:00
newAspect . _source = world ;
2024-01-07 19:32:16 +08:00
builder . Build ( out newAspect . _mask ) ;
2024-03-26 16:06:03 +08:00
newAspect . _isBuilt = true ;
2024-01-07 18:52:54 +08:00
2024-04-22 17:20:31 +08:00
newAspect . _sortIncBuffer = new UnsafeArray < int > ( newAspect . _mask . _inc . Length , true ) ;
newAspect . _sortExcBuffer = new UnsafeArray < int > ( newAspect . _mask . _exc . Length , true ) ;
newAspect . _sortIncChunckBuffer = new UnsafeArray < EcsMaskChunck > ( newAspect . _mask . _incChunckMasks . Length , true ) ;
newAspect . _sortExcChunckBuffer = new UnsafeArray < EcsMaskChunck > ( newAspect . _mask . _excChunckMasks . Length , true ) ;
2024-01-07 18:52:54 +08:00
for ( int i = 0 ; i < newAspect . _sortIncBuffer . Length ; i + + )
{
2024-04-22 17:20:31 +08:00
newAspect . _sortIncBuffer . ptr [ i ] = newAspect . _mask . _inc [ i ] ;
2024-01-07 18:52:54 +08:00
}
for ( int i = 0 ; i < newAspect . _sortExcBuffer . Length ; i + + )
{
2024-04-22 17:20:31 +08:00
newAspect . _sortExcBuffer . ptr [ i ] = newAspect . _mask . _exc [ i ] ;
2024-01-07 18:52:54 +08:00
}
for ( int i = 0 ; i < newAspect . _sortIncChunckBuffer . Length ; i + + )
{
2024-04-22 17:20:31 +08:00
newAspect . _sortIncChunckBuffer . ptr [ i ] = newAspect . _mask . _incChunckMasks [ i ] ;
2024-01-07 18:52:54 +08:00
}
for ( int i = 0 ; i < newAspect . _sortExcChunckBuffer . Length ; i + + )
{
2024-04-22 17:20:31 +08:00
newAspect . _sortExcChunckBuffer . ptr [ i ] = newAspect . _mask . _excChunckMasks [ i ] ;
2024-01-07 18:52:54 +08:00
}
2023-06-22 14:31:13 +08:00
return ( TAspect ) newAspect ;
2023-05-07 00:50:02 +08:00
}
2024-04-18 22:14:50 +08:00
#region Include / Exclude / Optional / Combine / Except
2024-03-07 03:40:06 +08:00
public TPool IncludePool < TPool > ( ) where TPool : IEcsPoolImplementation , new ( )
2023-05-07 00:50:02 +08:00
{
2024-03-07 03:30:18 +08:00
var pool = _world . GetPoolInstance < TPool > ( ) ;
2024-02-23 18:34:40 +08:00
IncludeImplicit ( pool . ComponentType ) ;
return pool ;
2023-05-07 00:50:02 +08:00
}
2024-03-07 03:40:06 +08:00
public TPool ExcludePool < TPool > ( ) where TPool : IEcsPoolImplementation , new ( )
2023-05-07 00:50:02 +08:00
{
2024-03-07 03:30:18 +08:00
var pool = _world . GetPoolInstance < TPool > ( ) ;
2024-02-23 18:34:40 +08:00
ExcludeImplicit ( pool . ComponentType ) ;
return pool ;
2023-05-07 00:50:02 +08:00
}
2024-03-07 03:40:06 +08:00
public TPool OptionalPool < TPool > ( ) where TPool : IEcsPoolImplementation , new ( )
2023-05-07 00:50:02 +08:00
{
2024-03-07 03:30:18 +08:00
return _world . GetPoolInstance < TPool > ( ) ;
2023-05-07 00:50:02 +08:00
}
2023-06-04 18:32:05 +08:00
private void IncludeImplicit ( Type type )
2023-05-07 00:50:02 +08:00
{
2024-01-07 19:32:16 +08:00
_maskBuilder . Include ( type ) ;
2023-05-07 00:50:02 +08:00
}
2023-06-04 18:32:05 +08:00
private void ExcludeImplicit ( Type type )
2023-05-07 00:50:02 +08:00
{
2024-01-07 19:32:16 +08:00
_maskBuilder . Exclude ( type ) ;
2023-05-07 00:50:02 +08:00
}
2023-06-22 14:31:13 +08:00
public TOtherAspect Combine < TOtherAspect > ( int order = 0 ) where TOtherAspect : EcsAspect
2023-06-03 01:58:54 +08:00
{
2023-06-22 14:31:13 +08:00
var result = _world . GetAspect < TOtherAspect > ( ) ;
2024-01-11 00:48:39 +08:00
_maskBuilder . Combine ( result . Mask ) ;
2023-06-03 01:58:54 +08:00
return result ;
}
2024-04-18 22:14:50 +08:00
public TOtherAspect Except < TOtherAspect > ( int order = 0 ) where TOtherAspect : EcsAspect
{
var result = _world . GetAspect < TOtherAspect > ( ) ;
_maskBuilder . Except ( result . Mask ) ;
return result ;
}
2023-06-03 01:58:54 +08:00
#endregion
2024-01-07 19:32:16 +08:00
private void Build ( out EcsMask mask )
2023-05-07 00:50:02 +08:00
{
2024-01-07 19:32:16 +08:00
mask = _maskBuilder . Build ( ) ;
2023-05-07 00:50:02 +08:00
}
2023-05-28 05:53:08 +08:00
#region SupportReflectionHack
#if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve]
#endif
2023-06-04 18:32:05 +08:00
private void SupportReflectionHack < TPool > ( ) where TPool : IEcsPoolImplementation , new ( )
2023-05-28 05:53:08 +08:00
{
2024-03-07 03:40:06 +08:00
IncludePool < TPool > ( ) ;
ExcludePool < TPool > ( ) ;
OptionalPool < TPool > ( ) ;
2023-06-04 18:32:05 +08:00
IncludeImplicit ( null ) ;
ExcludeImplicit ( null ) ;
2023-05-28 05:53:08 +08:00
}
#endregion
2023-05-07 00:50:02 +08:00
}
#endregion
2024-03-02 21:45:09 +08:00
#region Finalizator
2024-01-07 18:52:54 +08:00
unsafe ~ EcsAspect ( )
{
_sortIncBuffer . Dispose ( ) ;
_sortExcBuffer . Dispose ( ) ;
_sortIncChunckBuffer . Dispose ( ) ;
_sortExcChunckBuffer . Dispose ( ) ;
}
#endregion
2023-06-02 04:00:08 +08:00
#region Iterator
2024-02-11 01:14:54 +08:00
public Iterator GetIterator ( )
2023-05-07 00:50:02 +08:00
{
2024-02-11 01:14:54 +08:00
return new Iterator ( this , _source . Entities ) ;
2023-05-07 00:50:02 +08:00
}
2024-02-11 01:14:54 +08:00
public Iterator GetIteratorFor ( EcsSpan span )
2023-05-07 00:50:02 +08:00
{
2024-02-11 01:14:54 +08:00
return new Iterator ( this , span ) ;
2023-05-07 00:50:02 +08:00
}
2023-06-02 04:00:08 +08:00
#endregion
2023-06-05 22:09:34 +08:00
2024-01-07 18:52:54 +08:00
#region Combined
2023-06-25 23:13:51 +08:00
private readonly struct Combined
2023-06-05 22:09:34 +08:00
{
2023-06-25 23:13:51 +08:00
public readonly EcsAspect aspect ;
public readonly int order ;
2023-06-22 14:31:13 +08:00
public Combined ( EcsAspect aspect , int order )
2023-06-05 22:09:34 +08:00
{
2023-06-22 14:31:13 +08:00
this . aspect = aspect ;
2023-06-05 22:09:34 +08:00
this . order = order ;
}
}
2024-01-07 18:52:54 +08:00
#endregion
2023-05-07 00:50:02 +08:00
2024-02-11 01:14:54 +08:00
#region Iterator
public ref struct Iterator
2023-12-24 15:40:19 +08:00
{
2024-04-16 12:46:09 +08:00
public readonly short worldID ;
2024-02-11 01:14:54 +08:00
public readonly EcsAspect aspect ;
private EcsSpan _span ;
public Iterator ( EcsAspect aspect , EcsSpan span )
2023-12-24 15:40:19 +08:00
{
2024-02-11 01:14:54 +08:00
worldID = aspect . World . id ;
_span = span ;
this . aspect = aspect ;
2023-12-24 15:40:19 +08:00
}
2024-04-18 00:36:05 +08:00
#region CopyTo
2024-02-11 01:14:54 +08:00
public void CopyTo ( EcsGroup group )
2023-12-24 15:40:19 +08:00
{
2024-02-11 01:14:54 +08:00
group . Clear ( ) ;
var enumerator = GetEnumerator ( ) ;
while ( enumerator . MoveNext ( ) )
2024-03-02 21:45:09 +08:00
{
2024-03-02 04:20:34 +08:00
group . Add_Internal ( enumerator . Current ) ;
2024-03-02 21:45:09 +08:00
}
2023-12-24 15:40:19 +08:00
}
2024-02-11 01:14:54 +08:00
public int CopyTo ( ref int [ ] array )
2023-05-07 00:50:02 +08:00
{
2024-02-11 01:14:54 +08:00
int count = 0 ;
2024-03-02 21:45:09 +08:00
var enumerator = GetEnumerator ( ) ;
2024-02-11 01:14:54 +08:00
while ( enumerator . MoveNext ( ) )
2024-01-07 18:52:54 +08:00
{
2024-02-11 01:14:54 +08:00
if ( array . Length < = count )
2024-03-02 21:45:09 +08:00
{
2024-02-11 01:14:54 +08:00
Array . Resize ( ref array , array . Length < < 1 ) ;
2024-03-02 21:45:09 +08:00
}
2024-02-11 01:14:54 +08:00
array [ count + + ] = enumerator . Current ;
2024-01-07 18:52:54 +08:00
}
2024-02-11 01:14:54 +08:00
return count ;
2024-01-07 18:52:54 +08:00
}
2024-02-11 01:14:54 +08:00
public EcsSpan CopyToSpan ( ref int [ ] array )
2024-01-07 18:52:54 +08:00
{
2024-03-02 21:45:09 +08:00
int count = CopyTo ( ref array ) ;
2024-02-11 01:14:54 +08:00
return new EcsSpan ( worldID , array , count ) ;
}
2024-04-18 00:36:05 +08:00
#endregion
2024-02-11 01:14:54 +08:00
2024-03-02 21:45:09 +08:00
#region Other
2024-02-11 01:14:54 +08:00
public override string ToString ( )
{
List < int > ints = new List < int > ( ) ;
foreach ( var e in this )
2024-01-07 18:52:54 +08:00
{
2024-02-11 01:14:54 +08:00
ints . Add ( e ) ;
2024-01-07 18:52:54 +08:00
}
2024-02-11 01:14:54 +08:00
return CollectionUtility . EntitiesToString ( ints , "it" ) ;
2024-01-07 18:52:54 +08:00
}
2024-01-07 23:19:18 +08:00
#endregion
2024-02-11 01:14:54 +08:00
#region Enumerator
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 21:45:09 +08:00
public Enumerator GetEnumerator ( ) { return new Enumerator ( _span , aspect ) ; }
2024-01-07 18:52:54 +08:00
2024-02-11 01:14:54 +08:00
public unsafe ref struct Enumerator
2023-05-07 00:50:02 +08:00
{
2024-02-11 01:14:54 +08:00
#region CountComparers
private readonly struct IncCountComparer : IComparerX < int >
2024-01-06 00:07:07 +08:00
{
2024-02-11 01:14:54 +08:00
public readonly int [ ] counts ;
public IncCountComparer ( int [ ] counts )
{
this . counts = counts ;
}
public int Compare ( int a , int b )
{
return counts [ a ] - counts [ b ] ;
}
2024-01-06 00:07:07 +08:00
}
2024-02-11 01:14:54 +08:00
private readonly struct ExcCountComparer : IComparerX < int >
2024-01-06 00:07:07 +08:00
{
2024-02-11 01:14:54 +08:00
public readonly int [ ] counts ;
public ExcCountComparer ( int [ ] counts )
2024-01-07 23:19:18 +08:00
{
2024-02-11 01:14:54 +08:00
this . counts = counts ;
2024-01-07 23:19:18 +08:00
}
2024-02-11 01:14:54 +08:00
public int Compare ( int a , int b )
2024-01-06 00:07:07 +08:00
{
2024-02-11 01:14:54 +08:00
return counts [ b ] - counts [ a ] ;
2024-01-06 00:07:07 +08:00
}
}
2024-02-11 01:14:54 +08:00
#endregion
private ReadOnlySpan < int > . Enumerator _span ;
2024-02-16 21:17:20 +08:00
private readonly int [ ] _entityComponentMasks ;
2024-02-11 01:14:54 +08:00
private static EcsMaskChunck * _preSortedIncBuffer ;
private static EcsMaskChunck * _preSortedExcBuffer ;
2024-01-06 00:07:07 +08:00
2024-02-11 01:14:54 +08:00
private UnsafeArray < EcsMaskChunck > _sortIncChunckBuffer ;
private UnsafeArray < EcsMaskChunck > _sortExcChunckBuffer ;
2024-04-18 00:36:05 +08:00
private readonly int _entityComponentMaskLengthBitShift ;
2024-02-11 01:14:54 +08:00
public unsafe Enumerator ( EcsSpan span , EcsAspect aspect )
2024-01-06 00:07:07 +08:00
{
2024-02-16 21:17:20 +08:00
_entityComponentMasks = aspect . World . _entityComponentMasks ;
2024-02-11 01:14:54 +08:00
_sortIncChunckBuffer = aspect . _sortIncChunckBuffer ;
_sortExcChunckBuffer = aspect . _sortExcChunckBuffer ;
2024-04-18 00:36:05 +08:00
_entityComponentMaskLengthBitShift = aspect . World . _entityComponentMaskLengthBitShift ;
2024-02-16 21:17:20 +08:00
2024-04-18 22:14:50 +08:00
if ( aspect . Mask . IsBroken )
{
_span = span . Slice ( 0 , 0 ) . GetEnumerator ( ) ;
return ;
}
2024-02-11 01:14:54 +08:00
#region Sort
UnsafeArray < int > _sortIncBuffer = aspect . _sortIncBuffer ;
UnsafeArray < int > _sortExcBuffer = aspect . _sortExcBuffer ;
int [ ] counts = aspect . World . _poolComponentCounts ;
if ( _preSortedIncBuffer = = null )
2024-01-07 23:19:18 +08:00
{
2024-02-11 01:14:54 +08:00
_preSortedIncBuffer = UnmanagedArrayUtility . New < EcsMaskChunck > ( 256 ) ;
_preSortedExcBuffer = UnmanagedArrayUtility . New < EcsMaskChunck > ( 256 ) ;
2024-01-07 23:19:18 +08:00
}
2024-02-11 01:14:54 +08:00
if ( _sortIncChunckBuffer . Length > 1 )
2024-01-06 00:07:07 +08:00
{
2024-02-11 01:14:54 +08:00
IncCountComparer incComparer = new IncCountComparer ( counts ) ;
UnsafeArraySortHalperX < int > . InsertionSort ( _sortIncBuffer . ptr , _sortIncBuffer . Length , ref incComparer ) ;
for ( int i = 0 ; i < _sortIncBuffer . Length ; i + + )
2024-01-06 00:07:07 +08:00
{
2024-02-11 01:14:54 +08:00
_preSortedIncBuffer [ i ] = EcsMaskChunck . FromID ( _sortIncBuffer . ptr [ i ] ) ;
}
for ( int i = 0 , ii = 0 ; ii < _sortIncChunckBuffer . Length ; ii + + )
{
2024-04-18 22:14:50 +08:00
EcsMaskChunck chunkX = _preSortedIncBuffer [ i ] ;
int chankIndexX = chunkX . chankIndex ;
int maskX = chunkX . mask ;
2024-02-11 01:14:54 +08:00
for ( int j = i + 1 ; j < _sortIncBuffer . Length ; j + + )
2024-01-06 00:07:07 +08:00
{
2024-02-11 01:14:54 +08:00
if ( _preSortedIncBuffer [ j ] . chankIndex = = chankIndexX )
{
maskX | = _preSortedIncBuffer [ j ] . mask ;
}
}
_sortIncChunckBuffer . ptr [ ii ] = new EcsMaskChunck ( chankIndexX , maskX ) ;
while ( + + i < _sortIncBuffer . Length & & _preSortedIncBuffer [ i ] . chankIndex = = chankIndexX )
{
// skip
2024-01-06 00:07:07 +08:00
}
}
2024-02-11 01:14:54 +08:00
}
2024-04-08 23:49:56 +08:00
if ( _sortIncChunckBuffer . Length > 0 & & counts [ _sortIncBuffer . ptr [ 0 ] ] < = 0 )
{
_span = span . Slice ( 0 , 0 ) . GetEnumerator ( ) ;
return ;
}
2024-02-11 01:14:54 +08:00
if ( _sortExcChunckBuffer . Length > 1 )
{
ExcCountComparer excComparer = new ExcCountComparer ( counts ) ;
UnsafeArraySortHalperX < int > . InsertionSort ( _sortExcBuffer . ptr , _sortExcBuffer . Length , ref excComparer ) ;
for ( int i = 0 ; i < _sortExcBuffer . Length ; i + + )
2024-01-06 00:07:07 +08:00
{
2024-02-11 01:14:54 +08:00
_preSortedExcBuffer [ i ] = EcsMaskChunck . FromID ( _sortExcBuffer . ptr [ i ] ) ;
}
for ( int i = 0 , ii = 0 ; ii < _sortExcChunckBuffer . Length ; ii + + )
{
EcsMaskChunck bas = _preSortedExcBuffer [ i ] ;
int chankIndexX = bas . chankIndex ;
int maskX = bas . mask ;
for ( int j = i + 1 ; j < _sortExcBuffer . Length ; j + + )
{
if ( _preSortedExcBuffer [ j ] . chankIndex = = chankIndexX )
{
maskX | = _preSortedExcBuffer [ j ] . mask ;
}
}
_sortExcChunckBuffer . ptr [ ii ] = new EcsMaskChunck ( chankIndexX , maskX ) ;
while ( + + i < _sortExcBuffer . Length & & _preSortedExcBuffer [ i ] . chankIndex = = chankIndexX )
{
// skip
}
2024-01-06 00:07:07 +08:00
}
}
2024-02-11 01:14:54 +08:00
#endregion
2024-04-18 00:36:05 +08:00
2024-04-08 23:49:56 +08:00
_span = span . GetEnumerator ( ) ;
2024-01-06 00:07:07 +08:00
}
2024-02-11 01:14:54 +08:00
public int Current
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-02 21:45:09 +08:00
get { return _span . Current ; }
2024-02-11 01:14:54 +08:00
}
2023-05-07 00:50:02 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-11 01:14:54 +08:00
public bool MoveNext ( )
2023-05-07 00:50:02 +08:00
{
2024-02-11 01:14:54 +08:00
while ( _span . MoveNext ( ) )
2023-11-22 17:35:03 +08:00
{
2024-04-18 00:36:05 +08:00
int chunck = _span . Current < < _entityComponentMaskLengthBitShift ;
2024-02-11 01:14:54 +08:00
for ( int i = 0 ; i < _sortIncChunckBuffer . Length ; i + + )
{
var bit = _sortIncChunckBuffer . ptr [ i ] ;
2024-04-08 23:49:56 +08:00
if ( ( _entityComponentMasks [ chunck + bit . chankIndex ] & bit . mask ) ! = bit . mask )
2024-03-02 21:45:09 +08:00
{
2024-02-11 01:14:54 +08:00
goto skip ;
2024-03-02 21:45:09 +08:00
}
2024-02-11 01:14:54 +08:00
}
for ( int i = 0 ; i < _sortExcChunckBuffer . Length ; i + + )
{
var bit = _sortExcChunckBuffer . ptr [ i ] ;
2024-04-08 23:49:56 +08:00
if ( ( _entityComponentMasks [ chunck + bit . chankIndex ] & bit . mask ) ! = 0 )
2024-03-02 21:45:09 +08:00
{
2024-02-11 01:14:54 +08:00
goto skip ;
2024-03-02 21:45:09 +08:00
}
2024-02-11 01:14:54 +08:00
}
return true ;
skip : continue ;
2023-11-22 17:35:03 +08:00
}
2024-02-11 01:14:54 +08:00
return false ;
2023-05-07 00:50:02 +08:00
}
}
2024-02-11 01:14:54 +08:00
#endregion
2023-05-07 00:50:02 +08:00
}
2023-06-02 04:00:08 +08:00
#endregion
2024-04-22 17:01:13 +08:00
#region Template
public virtual void Apply ( short worldID , int entityID )
{
EcsWorld world = EcsWorld . GetWorld ( worldID ) ;
2024-04-22 17:20:31 +08:00
foreach ( var incTypeID in _mask . _inc )
2024-04-22 17:01:13 +08:00
{
var pool = world . GetPoolInstance ( incTypeID ) ;
2024-04-22 17:16:37 +08:00
if ( pool ! = null )
2024-04-22 17:01:13 +08:00
{
2024-04-22 17:16:37 +08:00
if ( pool . Has ( entityID ) = = false )
{
pool . AddRaw ( entityID , null ) ;
}
}
#if DEBUG
else
{
EcsDebug . PrintWarning ( "Component has not been added because the pool has not been initialized yet." ) ;
2024-04-22 17:01:13 +08:00
}
2024-04-22 17:16:37 +08:00
#endif
2024-04-26 04:55:19 +08:00
}
2024-04-22 17:20:31 +08:00
foreach ( var excTypeID in _mask . _exc )
2024-04-22 17:01:13 +08:00
{
var pool = world . GetPoolInstance ( excTypeID ) ;
2024-04-22 17:09:06 +08:00
if ( pool ! = null & & pool . Has ( entityID ) )
2024-04-22 17:01:13 +08:00
{
pool . Del ( entityID ) ;
}
}
}
#endregion
2023-05-07 00:50:02 +08:00
}
2024-03-08 20:40:19 +08:00
public readonly ref struct IncludeMarker
{
private readonly EcsAspect . Builder _builder ;
public IncludeMarker ( EcsAspect . Builder builder )
{
_builder = builder ;
}
2024-03-09 21:33:44 +08:00
public T GetInstance < T > ( )
2024-03-08 20:40:19 +08:00
where T : IEcsPoolImplementation , new ( )
{
return _builder . IncludePool < T > ( ) ;
}
}
public readonly ref struct ExcludeMarker
{
private readonly EcsAspect . Builder _builder ;
public ExcludeMarker ( EcsAspect . Builder builder )
{
_builder = builder ;
}
public T GetInstance < T > ( )
where T : IEcsPoolImplementation , new ( )
{
return _builder . ExcludePool < T > ( ) ;
}
}
public readonly ref struct OptionalMarker
{
private readonly EcsAspect . Builder _builder ;
public OptionalMarker ( EcsAspect . Builder builder )
{
_builder = builder ;
}
public T GetInstance < T > ( )
where T : IEcsPoolImplementation , new ( )
{
return _builder . OptionalPool < T > ( ) ;
}
}
2023-05-07 00:50:02 +08:00
}