2025-03-14 16:53:25 +08:00
#if DISABLE_DEBUG
#undef DEBUG
#endif
2025-03-10 12:59:43 +08:00
using DCFApixels.DragonECS.Core ;
2024-02-07 22:16:41 +08:00
using DCFApixels.DragonECS.Internal ;
2024-04-30 16:09:57 +08:00
using DCFApixels.DragonECS.PoolsCore ;
2023-02-08 17:57:06 +08:00
using System ;
2023-04-22 23:40:09 +08:00
using System.Collections ;
using System.Collections.Generic ;
2024-12-04 16:10:09 +08:00
using System.ComponentModel ;
2024-12-03 16:59:32 +08:00
using System.Diagnostics ;
2023-03-30 16:45:43 +08:00
using System.Runtime.CompilerServices ;
2024-05-01 16:32:03 +08:00
#if ENABLE_IL2CPP
using Unity.IL2CPP.CompilerServices ;
#endif
2023-02-05 19:59:45 +08:00
namespace DCFApixels.DragonECS
{
2024-04-30 16:09:57 +08:00
/// <summary>Standard component</summary>
2024-06-13 18:04:18 +08:00
[MetaColor(MetaColor.DragonRose)]
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
[MetaDescription(EcsConsts.AUTHOR, "Standard component.")]
2025-03-19 16:30:20 +08:00
[MetaID("DragonECS_84D2537C9201D6F6B92FEC1C8883A07A")]
2025-03-19 16:32:25 +08:00
public interface IEcsComponent : IEcsComponentMember { }
2024-05-01 14:29:01 +08:00
2024-06-13 18:04:18 +08:00
/// <summary>Pool for IEcsComponent components</summary>
2024-04-28 19:43:10 +08:00
#if ENABLE_IL2CPP
2024-11-08 17:21:36 +08:00
[Il2CppSetOption(Option.NullChecks, false)]
2024-04-28 19:43:10 +08:00
#endif
2024-05-01 14:29:01 +08:00
[MetaColor(MetaColor.DragonRose)]
2024-06-13 18:04:18 +08:00
[MetaGroup(EcsConsts.PACK_GROUP, EcsConsts.POOLS_GROUP)]
2024-06-11 02:30:00 +08:00
[MetaDescription(EcsConsts.AUTHOR, "Pool for IEcsComponent components.")]
2025-03-19 16:30:20 +08:00
[MetaID("DragonECS_C501547C9201A4B03FC25632E4FAAFD7")]
2025-03-14 17:07:38 +08:00
[DebuggerDisplay("Count: {Count} Type: {ComponentType}")]
2023-06-25 23:13:51 +08:00
public sealed class EcsPool < T > : IEcsPoolImplementation < T > , IEcsStructPool < T > , IEnumerable < T > //IEnumerable<T> - IntelliSense hack
2023-04-21 14:21:24 +08:00
where T : struct , IEcsComponent
2023-02-05 19:59:45 +08:00
{
2023-05-07 00:50:02 +08:00
private EcsWorld _source ;
2023-12-06 18:58:06 +08:00
private int _componentTypeID ;
2024-01-07 18:52:54 +08:00
private EcsMaskChunck _maskBit ;
2023-04-22 23:40:09 +08:00
2025-03-15 15:00:07 +08:00
private int [ ] _mapping ; // index = entityID / value = itemIndex;/ value = 0 = no entityID.
private T [ ] _items ; // dense; _items[0] - fake component.
2024-03-07 06:46:44 +08:00
private int _itemsCount = 0 ;
2023-04-01 20:45:37 +08:00
private int [ ] _recycledItems ;
2024-03-07 06:46:44 +08:00
private int _recycledItemsCount = 0 ;
2023-02-05 19:59:45 +08:00
2025-03-17 13:05:23 +08:00
private readonly IEcsComponentLifecycle < T > _componentLifecycleHandler = EcsComponentLifecycleHandler < T > . instance ;
private readonly bool _isHasComponentLifecycleHandler = EcsComponentLifecycleHandler < T > . isHasHandler ;
2025-03-14 20:33:06 +08:00
private readonly IEcsComponentCopy < T > _componentCopyHandler = EcsComponentCopyHandler < T > . instance ;
private readonly bool _isHasComponentCopyHandler = EcsComponentCopyHandler < T > . isHasHandler ;
2023-05-23 15:58:31 +08:00
2025-03-15 15:00:07 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2025-03-14 20:33:06 +08:00
private StructList < IEcsPoolEventListener > _listeners = new StructList < IEcsPoolEventListener > ( 2 ) ;
2024-04-27 19:05:05 +08:00
private int _listenersCachedCount = 0 ;
2024-05-01 16:58:54 +08:00
#endif
2024-11-04 07:36:42 +08:00
private bool _isLocked ;
2023-04-17 22:58:52 +08:00
2023-12-06 18:58:06 +08:00
private EcsWorld . PoolsMediator _mediator ;
2023-02-07 17:11:56 +08:00
#region Properites
2024-02-24 02:26:42 +08:00
public int Count
{
get { return _itemsCount ; }
}
public int Capacity
{
get { return _items . Length ; }
}
2024-02-25 00:55:30 +08:00
public int ComponentTypeID
2024-02-24 02:26:42 +08:00
{
get { return _componentTypeID ; }
}
public Type ComponentType
{
get { return typeof ( T ) ; }
}
public EcsWorld World
{
get { return _source ; }
}
2024-02-25 17:27:08 +08:00
public bool IsReadOnly
2024-02-25 00:55:30 +08:00
{
get { return false ; }
}
2025-03-13 20:40:47 +08:00
public ref T this [ int index ]
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return ref Get ( index ) ; }
}
2023-02-07 17:11:56 +08:00
#endregion
2023-05-07 00:50:02 +08:00
#region Methods
2023-04-21 03:16:05 +08:00
public ref T Add ( int entityID )
2023-02-13 21:11:54 +08:00
{
2023-04-20 18:23:23 +08:00
ref int itemIndex = ref _mapping [ entityID ] ;
2025-03-15 15:00:07 +08:00
#if DEBUG
2025-04-04 14:40:53 +08:00
if ( _source . IsUsed ( entityID ) = = false ) { Throw . Ent_ThrowIsNotAlive ( _source , entityID ) ; }
2024-11-05 15:56:46 +08:00
if ( itemIndex > 0 ) { EcsPoolThrowHelper . ThrowAlreadyHasComponent < T > ( entityID ) ; }
if ( _isLocked ) { EcsPoolThrowHelper . ThrowPoolLocked ( ) ; }
2025-03-15 15:00:07 +08:00
#elif DRAGONECS_STABILITY_MODE
if ( itemIndex > 0 ) { return ref Get ( entityID ) ; }
2025-04-04 14:46:35 +08:00
if ( _isLocked | _source . IsUsed ( entityID ) = = false ) { return ref _items [ 0 ] ; }
2023-05-07 00:50:02 +08:00
#endif
if ( _recycledItemsCount > 0 )
2023-04-20 18:23:23 +08:00
{
2023-05-07 00:50:02 +08:00
itemIndex = _recycledItems [ - - _recycledItemsCount ] ;
_itemsCount + + ;
2023-04-17 22:58:52 +08:00
}
2023-05-07 00:50:02 +08:00
else
{
itemIndex = + + _itemsCount ;
if ( itemIndex > = _items . Length )
2024-02-24 02:26:42 +08:00
{
2023-05-07 00:50:02 +08:00
Array . Resize ( ref _items , _items . Length < < 1 ) ;
2024-02-24 02:26:42 +08:00
}
2023-05-07 00:50:02 +08:00
}
2023-12-06 18:58:06 +08:00
_mediator . RegisterComponent ( entityID , _componentTypeID , _maskBit ) ;
2024-12-04 16:10:09 +08:00
ref T result = ref _items [ itemIndex ] ;
EnableComponent ( ref result ) ;
2025-03-15 15:00:07 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2024-04-27 19:05:05 +08:00
_listeners . InvokeOnAddAndGet ( entityID , _listenersCachedCount ) ;
2024-05-01 16:58:54 +08:00
#endif
2024-12-04 16:10:09 +08:00
return ref result ;
2023-04-09 02:52:39 +08:00
}
2023-04-17 22:58:52 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-05-30 16:01:16 +08:00
public ref T Get ( int entityID )
2023-04-09 02:52:39 +08:00
{
2025-03-15 15:00:07 +08:00
#if DEBUG // <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> STAB_MODE
2024-11-05 15:56:46 +08:00
if ( ! Has ( entityID ) ) { EcsPoolThrowHelper . ThrowNotHaveComponent < T > ( entityID ) ; }
2023-05-07 00:50:02 +08:00
#endif
2025-03-15 15:00:07 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2024-04-27 19:05:05 +08:00
_listeners . InvokeOnGet ( entityID , _listenersCachedCount ) ;
2024-05-01 16:58:54 +08:00
#endif
2023-04-20 18:23:23 +08:00
return ref _items [ _mapping [ entityID ] ] ;
2023-04-01 20:45:37 +08:00
}
2023-02-05 19:59:45 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-21 03:16:05 +08:00
public ref readonly T Read ( int entityID )
2023-02-05 19:59:45 +08:00
{
2025-03-15 15:00:07 +08:00
#if DEBUG // <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> STAB_MODE
2024-11-05 15:56:46 +08:00
if ( ! Has ( entityID ) ) { EcsPoolThrowHelper . ThrowNotHaveComponent < T > ( entityID ) ; }
2023-05-07 00:50:02 +08:00
#endif
2023-04-01 21:16:08 +08:00
return ref _items [ _mapping [ entityID ] ] ;
2023-02-05 19:59:45 +08:00
}
2023-05-30 16:01:16 +08:00
public ref T TryAddOrGet ( int entityID )
2023-05-07 00:50:02 +08:00
{
ref int itemIndex = ref _mapping [ entityID ] ;
if ( itemIndex < = 0 )
2024-11-04 07:36:42 +08:00
{ //Add block
2025-03-15 15:00:07 +08:00
#if DEBUG
2024-11-05 15:56:46 +08:00
if ( _isLocked ) { EcsPoolThrowHelper . ThrowPoolLocked ( ) ; }
2025-03-15 15:00:07 +08:00
#elif DRAGONECS_STABILITY_MODE
if ( _isLocked ) { return ref _items [ 0 ] ; }
2024-11-04 07:36:42 +08:00
#endif
2023-05-07 00:50:02 +08:00
if ( _recycledItemsCount > 0 )
{
itemIndex = _recycledItems [ - - _recycledItemsCount ] ;
_itemsCount + + ;
}
else
{
itemIndex = + + _itemsCount ;
if ( itemIndex > = _items . Length )
2024-02-24 02:26:42 +08:00
{
2023-05-07 00:50:02 +08:00
Array . Resize ( ref _items , _items . Length < < 1 ) ;
2024-02-24 02:26:42 +08:00
}
2023-05-07 00:50:02 +08:00
}
2023-12-06 18:58:06 +08:00
_mediator . RegisterComponent ( entityID , _componentTypeID , _maskBit ) ;
2024-04-10 12:11:10 +08:00
EnableComponent ( ref _items [ itemIndex ] ) ;
2025-03-15 15:00:07 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2024-04-27 19:05:05 +08:00
_listeners . InvokeOnAdd ( entityID , _listenersCachedCount ) ;
2024-05-01 16:58:54 +08:00
#endif
2024-11-04 07:36:42 +08:00
} //Add block end
2025-03-15 15:00:07 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2024-04-27 19:05:05 +08:00
_listeners . InvokeOnGet ( entityID , _listenersCachedCount ) ;
2024-05-01 16:58:54 +08:00
#endif
2023-05-07 00:50:02 +08:00
return ref _items [ itemIndex ] ;
}
2023-02-07 17:11:56 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-05-07 00:50:02 +08:00
public bool Has ( int entityID )
2023-04-01 20:45:37 +08:00
{
2025-01-06 10:48:39 +08:00
return _mapping [ entityID ] ! = 0 ;
2023-04-01 20:45:37 +08:00
}
2023-04-21 03:16:05 +08:00
public void Del ( int entityID )
2023-02-07 17:11:56 +08:00
{
2024-02-24 02:26:42 +08:00
ref int itemIndex = ref _mapping [ entityID ] ;
2025-03-15 15:00:07 +08:00
#if DEBUG
2024-11-05 15:56:46 +08:00
if ( itemIndex < = 0 ) { EcsPoolThrowHelper . ThrowNotHaveComponent < T > ( entityID ) ; }
2025-03-15 15:00:07 +08:00
if ( _isLocked ) { EcsPoolThrowHelper . ThrowPoolLocked ( ) ; }
#elif DRAGONECS_STABILITY_MODE
if ( itemIndex < = 0 ) { return ; }
if ( _isLocked ) { return ; }
2023-05-07 00:50:02 +08:00
#endif
2024-03-10 19:22:47 +08:00
DisableComponent ( ref _items [ itemIndex ] ) ;
2023-04-01 21:16:08 +08:00
if ( _recycledItemsCount > = _recycledItems . Length )
2024-02-09 22:20:55 +08:00
{
2023-04-01 20:45:37 +08:00
Array . Resize ( ref _recycledItems , _recycledItems . Length < < 1 ) ;
2024-02-09 22:20:55 +08:00
}
2023-04-20 11:23:54 +08:00
_recycledItems [ _recycledItemsCount + + ] = itemIndex ;
2024-02-24 02:26:42 +08:00
itemIndex = 0 ;
2023-04-01 20:45:37 +08:00
_itemsCount - - ;
2023-12-06 18:58:06 +08:00
_mediator . UnregisterComponent ( entityID , _componentTypeID , _maskBit ) ;
2025-03-15 15:00:07 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2024-04-27 19:05:05 +08:00
_listeners . InvokeOnDel ( entityID , _listenersCachedCount ) ;
2024-05-01 16:58:54 +08:00
#endif
2023-05-07 00:50:02 +08:00
}
public void TryDel ( int entityID )
{
2024-02-24 02:26:42 +08:00
if ( Has ( entityID ) )
{
Del ( entityID ) ;
}
2023-05-07 00:50:02 +08:00
}
public void Copy ( int fromEntityID , int toEntityID )
{
2025-03-15 15:00:07 +08:00
#if DEBUG
2024-11-05 15:56:46 +08:00
if ( ! Has ( fromEntityID ) ) { EcsPoolThrowHelper . ThrowNotHaveComponent < T > ( fromEntityID ) ; }
2025-03-15 15:00:07 +08:00
#elif DRAGONECS_STABILITY_MODE
if ( ! Has ( fromEntityID ) ) { return ; }
2023-05-07 00:50:02 +08:00
#endif
2024-02-09 22:20:55 +08:00
CopyComponent ( ref Get ( fromEntityID ) , ref TryAddOrGet ( toEntityID ) ) ;
2023-05-23 01:47:28 +08:00
}
public void Copy ( int fromEntityID , EcsWorld toWorld , int toEntityID )
{
2025-03-15 15:00:07 +08:00
#if DEBUG
2024-11-05 15:56:46 +08:00
if ( ! Has ( fromEntityID ) ) { EcsPoolThrowHelper . ThrowNotHaveComponent < T > ( fromEntityID ) ; }
2025-03-15 15:00:07 +08:00
#elif DRAGONECS_STABILITY_MODE
if ( ! Has ( fromEntityID ) ) { return ; }
2023-05-23 01:47:28 +08:00
#endif
2024-02-09 22:20:55 +08:00
CopyComponent ( ref Get ( fromEntityID ) , ref toWorld . GetPool < T > ( ) . TryAddOrGet ( toEntityID ) ) ;
2023-04-20 11:23:54 +08:00
}
2024-03-13 17:41:33 +08:00
public void ClearAll ( )
{
2025-03-15 15:00:07 +08:00
#if DEBUG
2024-11-05 15:56:46 +08:00
if ( _isLocked ) { EcsPoolThrowHelper . ThrowPoolLocked ( ) ; }
2025-03-15 15:00:07 +08:00
#elif DRAGONECS_STABILITY_MODE
if ( _isLocked ) { return ; }
2024-11-04 07:36:42 +08:00
#endif
2024-12-18 16:18:30 +08:00
_recycledItemsCount = 0 ; // <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> , <20> <> <EFBFBD> <20> <> <EFBFBD> Del <20> <> <20> <> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD> <EFBFBD>
if ( _itemsCount < = 0 ) { return ; }
2024-03-13 17:41:33 +08:00
_itemsCount = 0 ;
2025-03-10 12:59:43 +08:00
var span = _source . Where ( out SingleAspect < T > _ ) ;
2024-03-13 17:41:33 +08:00
foreach ( var entityID in span )
{
ref int itemIndex = ref _mapping [ entityID ] ;
DisableComponent ( ref _items [ itemIndex ] ) ;
itemIndex = 0 ;
_mediator . UnregisterComponent ( entityID , _componentTypeID , _maskBit ) ;
2025-03-15 15:00:07 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2024-04-27 19:05:05 +08:00
_listeners . InvokeOnDel ( entityID , _listenersCachedCount ) ;
2024-05-01 16:58:54 +08:00
#endif
2024-03-13 17:41:33 +08:00
}
}
2023-02-07 17:11:56 +08:00
#endregion
2023-05-07 00:50:02 +08:00
#region Callbacks
2023-12-06 18:58:06 +08:00
void IEcsPoolImplementation . OnInit ( EcsWorld world , EcsWorld . PoolsMediator mediator , int componentTypeID )
2023-11-08 15:15:10 +08:00
{
2025-03-10 12:59:43 +08:00
#if DEBUG
AllowedInWorldsAttribute . CheckAllows < T > ( world ) ;
#endif
2023-11-08 15:15:10 +08:00
_source = world ;
2023-12-06 18:58:06 +08:00
_mediator = mediator ;
_componentTypeID = componentTypeID ;
2024-01-07 18:52:54 +08:00
_maskBit = EcsMaskChunck . FromID ( componentTypeID ) ;
2023-11-22 17:35:03 +08:00
2023-11-08 15:15:10 +08:00
_mapping = new int [ world . Capacity ] ;
2025-03-19 11:18:25 +08:00
_items = new T [ ArrayUtility . NextPow2 ( world . Configs . GetWorldConfigOrDefault ( ) . PoolComponentsCapacity ) ] ;
2024-03-07 07:48:18 +08:00
_recycledItems = new int [ world . Configs . GetWorldConfigOrDefault ( ) . PoolRecycledComponentsCapacity ] ;
2023-11-08 15:15:10 +08:00
}
2023-05-07 00:50:02 +08:00
void IEcsPoolImplementation . OnWorldResize ( int newSize )
2023-03-30 16:43:22 +08:00
{
2023-04-01 20:45:37 +08:00
Array . Resize ( ref _mapping , newSize ) ;
2023-03-30 16:43:22 +08:00
}
2023-05-07 00:50:02 +08:00
void IEcsPoolImplementation . OnWorldDestroy ( ) { }
void IEcsPoolImplementation . OnReleaseDelEntityBuffer ( ReadOnlySpan < int > buffer )
{
2024-02-25 23:05:11 +08:00
if ( _itemsCount < = 0 )
{
return ;
}
2023-05-07 00:50:02 +08:00
foreach ( var entityID in buffer )
2024-02-07 22:16:41 +08:00
{
2023-05-07 00:50:02 +08:00
TryDel ( entityID ) ;
2024-02-07 22:16:41 +08:00
}
2023-05-07 00:50:02 +08:00
}
2024-11-04 07:36:42 +08:00
void IEcsPoolImplementation . OnLockedChanged_Debug ( bool locked ) { _isLocked = locked ; }
2023-05-07 00:50:02 +08:00
#endregion
2023-04-22 23:40:09 +08:00
2023-05-07 00:50:02 +08:00
#region Other
2024-11-12 16:31:31 +08:00
void IEcsPool . AddEmpty ( int entityID ) { Add ( entityID ) ; }
2024-03-13 17:41:33 +08:00
void IEcsPool . AddRaw ( int entityID , object dataRaw )
{
Add ( entityID ) = dataRaw = = null ? default : ( T ) dataRaw ;
}
2025-03-28 12:10:16 +08:00
object IEcsReadonlyPool . GetRaw ( int entityID ) { return Read ( entityID ) ; }
2024-03-13 17:41:33 +08:00
void IEcsPool . SetRaw ( int entityID , object dataRaw )
{
Get ( entityID ) = dataRaw = = null ? default : ( T ) dataRaw ;
}
2023-04-06 23:40:47 +08:00
#endregion
2023-04-21 03:16:05 +08:00
2023-05-23 15:58:31 +08:00
#region Listeners
2025-03-15 15:00:07 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2023-05-23 15:58:31 +08:00
public void AddListener ( IEcsPoolEventListener listener )
{
2024-11-05 15:56:46 +08:00
if ( listener = = null ) { EcsPoolThrowHelper . ThrowNullListener ( ) ; }
2023-05-23 15:58:31 +08:00
_listeners . Add ( listener ) ;
2024-04-27 19:05:05 +08:00
_listenersCachedCount + + ;
2023-05-23 15:58:31 +08:00
}
public void RemoveListener ( IEcsPoolEventListener listener )
{
2024-11-05 15:56:46 +08:00
if ( listener = = null ) { EcsPoolThrowHelper . ThrowNullListener ( ) ; }
2024-12-04 16:10:09 +08:00
if ( _listeners . RemoveWithOrder ( listener ) )
2024-04-27 19:05:05 +08:00
{
_listenersCachedCount - - ;
}
2023-05-23 15:58:31 +08:00
}
2024-05-01 16:58:54 +08:00
#endif
2023-05-23 15:58:31 +08:00
#endregion
2024-03-10 19:22:47 +08:00
#region Enable / Disable / Copy
2024-02-09 22:20:55 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-10 19:22:47 +08:00
private void EnableComponent ( ref T component )
2024-02-09 22:20:55 +08:00
{
2024-03-10 19:22:47 +08:00
if ( _isHasComponentLifecycleHandler )
2024-02-09 22:20:55 +08:00
{
2024-03-10 19:22:47 +08:00
_componentLifecycleHandler . Enable ( ref component ) ;
}
else
{
component = default ;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void DisableComponent ( ref T component )
{
if ( _isHasComponentLifecycleHandler )
{
_componentLifecycleHandler . Disable ( ref component ) ;
2024-02-09 22:20:55 +08:00
}
else
{
component = default ;
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void CopyComponent ( ref T from , ref T to )
{
if ( _isHasComponentCopyHandler )
{
_componentCopyHandler . Copy ( ref from , ref to ) ;
}
else
{
to = from ;
}
}
#endregion
2023-05-07 00:50:02 +08:00
#region IEnumerator - IntelliSense hack
2024-02-24 02:26:42 +08:00
IEnumerator < T > IEnumerable < T > . GetEnumerator ( ) { throw new NotImplementedException ( ) ; }
IEnumerator IEnumerable . GetEnumerator ( ) { throw new NotImplementedException ( ) ; }
2023-05-07 00:50:02 +08:00
#endregion
2024-03-08 20:40:19 +08:00
2025-03-28 12:10:16 +08:00
#region Convertors
2024-03-08 20:40:19 +08:00
public static implicit operator EcsPool < T > ( IncludeMarker a ) { return a . GetInstance < EcsPool < T > > ( ) ; }
public static implicit operator EcsPool < T > ( ExcludeMarker a ) { return a . GetInstance < EcsPool < T > > ( ) ; }
public static implicit operator EcsPool < T > ( OptionalMarker a ) { return a . GetInstance < EcsPool < T > > ( ) ; }
2024-12-03 17:44:16 +08:00
public static implicit operator EcsPool < T > ( EcsWorld . GetPoolInstanceMarker a ) { return a . GetInstance < EcsPool < T > > ( ) ; }
2024-03-08 20:40:19 +08:00
#endregion
2025-03-19 09:39:14 +08:00
#region Apply
public static void Apply ( ref T component , int entityID , short worldID )
{
EcsWorld . GetPoolInstance < EcsPool < T > > ( worldID ) . TryAddOrGet ( entityID ) = component ;
}
public static void Apply ( ref T component , int entityID , EcsPool < T > pool )
{
pool . TryAddOrGet ( entityID ) = component ;
}
#endregion
2023-05-07 00:50:02 +08:00
}
2024-12-04 16:10:09 +08:00
2025-03-28 12:10:16 +08:00
#if ENABLE_IL2CPP
[Il2CppSetOption(Option.NullChecks, false)]
#endif
2025-03-28 12:12:32 +08:00
[EditorBrowsable(EditorBrowsableState.Never)]
2025-03-28 12:10:16 +08:00
public readonly struct ReadonlyEcsPool < T > : IEcsReadonlyPool //IEnumerable<T> - IntelliSense hack
where T : struct , IEcsComponent
{
private readonly EcsPool < T > _pool ;
#region Properties
public int ComponentTypeID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _pool . ComponentTypeID ; }
}
public Type ComponentType
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _pool . ComponentType ; }
}
public EcsWorld World
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _pool . World ; }
}
public int Count
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _pool . Count ; }
}
public bool IsReadOnly
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _pool . IsReadOnly ; }
}
2025-03-29 10:15:04 +08:00
public ref readonly T this [ int entityID ]
{
get { return ref _pool . Read ( entityID ) ; }
}
2025-03-28 12:10:16 +08:00
#endregion
#region Constructors
internal ReadonlyEcsPool ( EcsPool < T > pool )
{
_pool = pool ;
}
#endregion
#region Methods
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Has ( int entityID ) { return _pool . Has ( entityID ) ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly T Get ( int entityID ) { return ref _pool . Read ( entityID ) ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly T Read ( int entityID ) { return ref _pool . Read ( entityID ) ; }
object IEcsReadonlyPool . GetRaw ( int entityID ) { return _pool . Read ( entityID ) ; }
2025-03-29 15:55:26 +08:00
#if ! DRAGONECS_DISABLE_POOLS_EVENTS
2025-03-28 12:10:16 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void AddListener ( IEcsPoolEventListener listener ) { _pool . AddListener ( listener ) ; }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void RemoveListener ( IEcsPoolEventListener listener ) { _pool . AddListener ( listener ) ; }
2025-03-29 15:55:26 +08:00
#endif
#endregion
2025-03-28 12:10:16 +08:00
#region Convertors
public static implicit operator ReadonlyEcsPool < T > ( EcsPool < T > a ) { return new ReadonlyEcsPool < T > ( a ) ; }
public static implicit operator ReadonlyEcsPool < T > ( IncludeMarker a ) { return a . GetInstance < EcsPool < T > > ( ) ; }
public static implicit operator ReadonlyEcsPool < T > ( ExcludeMarker a ) { return a . GetInstance < EcsPool < T > > ( ) ; }
public static implicit operator ReadonlyEcsPool < T > ( OptionalMarker a ) { return a . GetInstance < EcsPool < T > > ( ) ; }
public static implicit operator ReadonlyEcsPool < T > ( EcsWorld . GetPoolInstanceMarker a ) { return a . GetInstance < EcsPool < T > > ( ) ; }
#endregion
}
2024-12-04 16:10:09 +08:00
public static class EcsPoolExtensions
2023-04-21 03:16:05 +08:00
{
2023-07-03 02:50:16 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-04-21 16:03:50 +08:00
public static EcsPool < TComponent > GetPool < TComponent > ( this EcsWorld self ) where TComponent : struct , IEcsComponent
2023-04-21 03:16:05 +08:00
{
2024-03-07 03:30:18 +08:00
return self . GetPoolInstance < EcsPool < TComponent > > ( ) ;
2023-04-21 16:03:50 +08:00
}
2023-07-03 02:50:16 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-11-21 10:41:41 +08:00
public static EcsPool < TComponent > GetPoolUnchecked < TComponent > ( this EcsWorld self ) where TComponent : struct , IEcsComponent
2023-07-03 02:50:16 +08:00
{
2024-03-07 03:30:18 +08:00
return self . GetPoolInstanceUnchecked < EcsPool < TComponent > > ( ) ;
2023-07-03 02:50:16 +08:00
}
2023-04-21 16:03:50 +08:00
2024-12-04 16:10:09 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPool < TComponent > Inc < TComponent > ( this EcsAspect . Builder self ) where TComponent : struct , IEcsComponent
{
return self . IncludePool < EcsPool < TComponent > > ( ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPool < TComponent > Exc < TComponent > ( this EcsAspect . Builder self ) where TComponent : struct , IEcsComponent
{
return self . ExcludePool < EcsPool < TComponent > > ( ) ;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsPool < TComponent > Opt < TComponent > ( this EcsAspect . Builder self ) where TComponent : struct , IEcsComponent
{
return self . OptionalPool < EcsPool < TComponent > > ( ) ;
}
#region Obsolete
[Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Inc) + "<T>()")]
[EditorBrowsable(EditorBrowsableState.Never)]
2023-07-03 02:50:16 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-11 01:28:18 +08:00
public static EcsPool < TComponent > Include < TComponent > ( this EcsAspect . Builder self ) where TComponent : struct , IEcsComponent
2023-04-21 16:03:50 +08:00
{
2024-03-07 03:40:06 +08:00
return self . IncludePool < EcsPool < TComponent > > ( ) ;
2023-04-21 16:03:50 +08:00
}
2024-12-04 16:10:09 +08:00
[Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Exc) + "<T>()")]
[EditorBrowsable(EditorBrowsableState.Never)]
2023-07-03 02:50:16 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-11 01:28:18 +08:00
public static EcsPool < TComponent > Exclude < TComponent > ( this EcsAspect . Builder self ) where TComponent : struct , IEcsComponent
2023-04-21 16:03:50 +08:00
{
2024-03-07 03:40:06 +08:00
return self . ExcludePool < EcsPool < TComponent > > ( ) ;
2023-04-21 16:03:50 +08:00
}
2024-12-04 16:10:09 +08:00
[Obsolete("Use " + nameof(EcsAspect) + "." + nameof(EcsAspect.Builder) + "." + nameof(Opt) + "<T>()")]
[EditorBrowsable(EditorBrowsableState.Never)]
2023-07-03 02:50:16 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-02-11 01:28:18 +08:00
public static EcsPool < TComponent > Optional < TComponent > ( this EcsAspect . Builder self ) where TComponent : struct , IEcsComponent
2023-04-21 16:03:50 +08:00
{
2024-03-07 03:40:06 +08:00
return self . OptionalPool < EcsPool < TComponent > > ( ) ;
2023-04-21 16:03:50 +08:00
}
2024-12-04 16:10:09 +08:00
#endregion
2023-04-21 03:16:05 +08:00
}
2023-02-05 19:59:45 +08:00
}