mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
polishing pools
This commit is contained in:
parent
efed7dcdbd
commit
c3ece37bf5
@ -30,11 +30,26 @@ namespace DCFApixels.DragonECS
|
||||
private EcsWorld.PoolsMediator _mediator;
|
||||
|
||||
#region Properites
|
||||
public int Count => _itemsCount;
|
||||
public int Capacity => _items.Length;
|
||||
public int ComponentID => _componentTypeID;
|
||||
public Type ComponentType => typeof(T);
|
||||
public EcsWorld World => _source;
|
||||
public int Count
|
||||
{
|
||||
get { return _itemsCount; }
|
||||
}
|
||||
public int Capacity
|
||||
{
|
||||
get { return _items.Length; }
|
||||
}
|
||||
public int ComponentID
|
||||
{
|
||||
get { return _componentTypeID; }
|
||||
}
|
||||
public Type ComponentType
|
||||
{
|
||||
get { return typeof(T); }
|
||||
}
|
||||
public EcsWorld World
|
||||
{
|
||||
get { return _source; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
@ -42,7 +57,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
ref int itemIndex = ref _mapping[entityID];
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (itemIndex > 0) EcsPoolThrowHalper.ThrowAlreadyHasComponent<T>(entityID);
|
||||
if (itemIndex > 0) { EcsPoolThrowHalper.ThrowAlreadyHasComponent<T>(entityID); }
|
||||
#endif
|
||||
if (_recycledItemsCount > 0)
|
||||
{
|
||||
@ -53,7 +68,9 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
itemIndex = ++_itemsCount;
|
||||
if (itemIndex >= _items.Length)
|
||||
{
|
||||
Array.Resize(ref _items, _items.Length << 1);
|
||||
}
|
||||
}
|
||||
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
|
||||
_listeners.InvokeOnAddAndGet(entityID);
|
||||
@ -64,7 +81,7 @@ namespace DCFApixels.DragonECS
|
||||
public ref T Get(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
|
||||
#endif
|
||||
_listeners.InvokeOnGet(entityID);
|
||||
return ref _items[_mapping[entityID]];
|
||||
@ -73,7 +90,7 @@ namespace DCFApixels.DragonECS
|
||||
public ref readonly T Read(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
|
||||
#endif
|
||||
return ref _items[_mapping[entityID]];
|
||||
}
|
||||
@ -91,7 +108,9 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
itemIndex = ++_itemsCount;
|
||||
if (itemIndex >= _items.Length)
|
||||
{
|
||||
Array.Resize(ref _items, _items.Length << 1);
|
||||
}
|
||||
}
|
||||
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
|
||||
_listeners.InvokeOnAdd(entityID);
|
||||
@ -107,36 +126,39 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public void Del(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
#endif
|
||||
ref int itemIndex = ref _mapping[entityID];
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (itemIndex <= 0) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
|
||||
#endif
|
||||
ResetComponent(ref _items[itemIndex]);
|
||||
if (_recycledItemsCount >= _recycledItems.Length)
|
||||
{
|
||||
Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
|
||||
}
|
||||
_recycledItems[_recycledItemsCount++] = itemIndex;
|
||||
_mapping[entityID] = 0;
|
||||
itemIndex = 0;
|
||||
_itemsCount--;
|
||||
_mediator.UnregisterComponent(entityID, _componentTypeID, _maskBit);
|
||||
_listeners.InvokeOnDel(entityID);
|
||||
}
|
||||
public void TryDel(int entityID)
|
||||
{
|
||||
if (Has(entityID)) Del(entityID);
|
||||
if (Has(entityID))
|
||||
{
|
||||
Del(entityID);
|
||||
}
|
||||
}
|
||||
public void Copy(int fromEntityID, int toEntityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(fromEntityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID);
|
||||
if (!Has(fromEntityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID); }
|
||||
#endif
|
||||
CopyComponent(ref Get(fromEntityID), ref TryAddOrGet(toEntityID));
|
||||
}
|
||||
public void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(fromEntityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID);
|
||||
if (!Has(fromEntityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID); }
|
||||
#endif
|
||||
CopyComponent(ref Get(fromEntityID), ref toWorld.GetPool<T>().TryAddOrGet(toEntityID));
|
||||
}
|
||||
@ -171,11 +193,9 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
void IEcsPool.AddRaw(int entityID, object dataRaw) => Add(entityID) = (T)dataRaw;
|
||||
object IEcsPool.GetRaw(int entityID) => Read(entityID);
|
||||
void IEcsPool.SetRaw(int entityID, object dataRaw) => Get(entityID) = (T)dataRaw;
|
||||
ref readonly T IEcsStructPool<T>.Read(int entityID) => ref Read(entityID);
|
||||
ref T IEcsStructPool<T>.Get(int entityID) => ref Get(entityID);
|
||||
void IEcsPool.AddRaw(int entityID, object dataRaw) { Add(entityID) = (T)dataRaw; }
|
||||
object IEcsPool.GetRaw(int entityID) { return Get(entityID); }
|
||||
void IEcsPool.SetRaw(int entityID, object dataRaw) { Get(entityID) = (T)dataRaw; }
|
||||
#endregion
|
||||
|
||||
#region Listeners
|
||||
@ -219,8 +239,8 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region IEnumerator - IntelliSense hack
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException();
|
||||
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator() { throw new NotImplementedException(); }
|
||||
IEnumerator IEnumerable.GetEnumerator() { throw new NotImplementedException(); }
|
||||
#endregion
|
||||
}
|
||||
/// <summary>Standard component</summary>
|
||||
|
@ -12,7 +12,7 @@ namespace DCFApixels.DragonECS
|
||||
Type ComponentType { get; }
|
||||
EcsWorld World { get; }
|
||||
int Count { get; }
|
||||
int Capacity { get; }
|
||||
int Capacity { get; } //TODO удалить. не во всех реализация нужен, проще привести к типу
|
||||
#endregion
|
||||
|
||||
#region Methods
|
||||
@ -30,18 +30,21 @@ namespace DCFApixels.DragonECS
|
||||
void RemoveListener(IEcsPoolEventListener listener);
|
||||
#endregion
|
||||
}
|
||||
public interface IEcsStructPool<T> : IEcsPool
|
||||
/// <summary>A pool for struct components.</summary>
|
||||
public interface IEcsStructPool<T> : IEcsPool where T: struct
|
||||
{
|
||||
ref T Add(int entityID);
|
||||
ref readonly T Read(int entityID);
|
||||
ref T Get(int entityID);
|
||||
}
|
||||
public interface IEcsClassPool<T> : IEcsPool
|
||||
/// <summary>A pool for reference components of type T that instantiates components itself.</summary>
|
||||
public interface IEcsClassPool<T> : IEcsPool where T: class
|
||||
{
|
||||
T Add(int entityID);
|
||||
T Get(int entityID);
|
||||
}
|
||||
public interface IEcsHybridPool<T> : IEcsPool
|
||||
/// <summary>A pool for reference components of type T, which does not instantiate components itself but receives components from external sources..</summary>
|
||||
public interface IEcsHybridPool<T> : IEcsPool where T: class
|
||||
{
|
||||
void Add(int entityID, T component);
|
||||
T Get(int entityID);
|
||||
@ -68,6 +71,14 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
throw new EcsFrameworkException($"Entity({entityID}) has no component {EcsDebugUtility.GetGenericTypeName<T>()}.");
|
||||
}
|
||||
public static void ThrowAlreadyHasComponent(Type type, int entityID)
|
||||
{
|
||||
throw new EcsFrameworkException($"Entity({entityID}) already has component {EcsDebugUtility.GetGenericTypeName(type)}.");
|
||||
}
|
||||
public static void ThrowNotHaveComponent(Type type, int entityID)
|
||||
{
|
||||
throw new EcsFrameworkException($"Entity({entityID}) has no component {EcsDebugUtility.GetGenericTypeName(type)}.");
|
||||
}
|
||||
}
|
||||
public static class IEcsPoolImplementationExtensions
|
||||
{
|
||||
|
@ -33,24 +33,41 @@ namespace DCFApixels.DragonECS
|
||||
public EcsTagPool()
|
||||
{
|
||||
if (_isInvalidType)
|
||||
{
|
||||
throw new EcsFrameworkException($"{typeof(T).Name} type must not contain any data.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endregion
|
||||
|
||||
#region Properites
|
||||
public int Count => _count;
|
||||
int IEcsPool.Capacity => -1;
|
||||
public int ComponentID => _componentTypeID;
|
||||
public Type ComponentType => typeof(T);
|
||||
public EcsWorld World => _source;
|
||||
public int Count
|
||||
{
|
||||
get { return _count; }
|
||||
}
|
||||
int IEcsPool.Capacity
|
||||
{
|
||||
get { return -1; }
|
||||
}
|
||||
public int ComponentID
|
||||
{
|
||||
get { return _componentTypeID; }
|
||||
}
|
||||
public Type ComponentType
|
||||
{
|
||||
get { return typeof(T); }
|
||||
}
|
||||
public EcsWorld World
|
||||
{
|
||||
get { return _source; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Method
|
||||
public void Add(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (Has(entityID)) EcsPoolThrowHalper.ThrowAlreadyHasComponent<T>(entityID);
|
||||
if (Has(entityID)) { EcsPoolThrowHalper.ThrowAlreadyHasComponent<T>(entityID); }
|
||||
#endif
|
||||
_count++;
|
||||
_mapping[entityID] = true;
|
||||
@ -59,12 +76,9 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public void TryAdd(int entityID)
|
||||
{
|
||||
if (!_mapping[entityID])
|
||||
if (Has(entityID) == false)
|
||||
{
|
||||
_count++;
|
||||
_mapping[entityID] = true;
|
||||
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
|
||||
_listeners.InvokeOnAdd(entityID);
|
||||
Add(entityID);
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@ -75,7 +89,7 @@ namespace DCFApixels.DragonECS
|
||||
public void Del(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
if (!Has(entityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
|
||||
#endif
|
||||
_mapping[entityID] = false;
|
||||
_count--;
|
||||
@ -84,19 +98,22 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public void TryDel(int entityID)
|
||||
{
|
||||
if (Has(entityID)) Del(entityID);
|
||||
if (Has(entityID))
|
||||
{
|
||||
Del(entityID);
|
||||
}
|
||||
}
|
||||
public void Copy(int fromEntityID, int toEntityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(fromEntityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID);
|
||||
if (!Has(fromEntityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID); }
|
||||
#endif
|
||||
TryAdd(toEntityID);
|
||||
}
|
||||
public void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(fromEntityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID);
|
||||
if (!Has(fromEntityID)) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID); }
|
||||
#endif
|
||||
toWorld.GetPool<T>().TryAdd(toEntityID);
|
||||
}
|
||||
@ -105,20 +122,28 @@ namespace DCFApixels.DragonECS
|
||||
if (isHas)
|
||||
{
|
||||
if (!Has(entityID))
|
||||
{
|
||||
Add(entityID);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Has(entityID))
|
||||
{
|
||||
Del(entityID);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void Toggle(int entityID)
|
||||
{
|
||||
if (Has(entityID))
|
||||
{
|
||||
Del(entityID);
|
||||
}
|
||||
else
|
||||
{
|
||||
Add(entityID);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -142,11 +167,27 @@ namespace DCFApixels.DragonECS
|
||||
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
|
||||
{
|
||||
foreach (var entityID in buffer)
|
||||
{
|
||||
TryDel(entityID);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
void IEcsPool.AddRaw(int entityID, object dataRaw) { Add(entityID); }
|
||||
object IEcsPool.GetRaw(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (Has(entityID) == false) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
|
||||
#endif
|
||||
return _fakeComponent;
|
||||
}
|
||||
void IEcsPool.SetRaw(int entityID, object dataRaw)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (Has(entityID) == false) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
|
||||
#endif
|
||||
}
|
||||
ref T IEcsStructPool<T>.Add(int entityID)
|
||||
{
|
||||
Add(entityID);
|
||||
@ -155,31 +196,17 @@ namespace DCFApixels.DragonECS
|
||||
ref readonly T IEcsStructPool<T>.Read(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
if (Has(entityID) == false) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
|
||||
#endif
|
||||
return ref _fakeComponent;
|
||||
}
|
||||
ref T IEcsStructPool<T>.Get(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
if (Has(entityID) == false) { EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID); }
|
||||
#endif
|
||||
return ref _fakeComponent;
|
||||
}
|
||||
void IEcsPool.AddRaw(int entityID, object dataRaw) => Add(entityID);
|
||||
object IEcsPool.GetRaw(int entityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
#endif
|
||||
return _fakeComponent;
|
||||
}
|
||||
void IEcsPool.SetRaw(int entityID, object dataRaw)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
#endif
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Listeners
|
||||
|
@ -123,6 +123,11 @@ namespace DCFApixels.DragonECS.Internal
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Exception(string message)
|
||||
{
|
||||
throw new Exception(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user