DragonECS/src/Pools/EcsSinglePool.cs

124 lines
4.3 KiB
C#
Raw Normal View History

2023-04-21 03:16:05 +08:00
using System;
using System.Runtime.CompilerServices;
using Unity.Profiling;
namespace DCFApixels.DragonECS
{
2023-04-22 23:40:09 +08:00
public sealed class EcsSinglePool<T> : EcsPoolBase<T>
2023-04-21 14:21:24 +08:00
where T : struct, IEcsSingleComponent
2023-04-21 03:16:05 +08:00
{
private EcsWorld _source;
private int[] _mapping;// index = entityID / value = itemIndex;/ value = 0 = no entityID
//private T[] _items; //dense
//private int _count;
//private int[] _recycledItems;
//private int _recycledItemsCount;
private int _count;
private T _component;
private PoolRunners _poolRunners;
#region Properites
2023-04-24 16:48:18 +08:00
public ref T Instance
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => ref _component;
}
2023-04-21 03:16:05 +08:00
public int Count => _count;
public sealed override EcsWorld World => _source;
#endregion
#region Init
protected override void Init(EcsWorld world)
{
_source = world;
_mapping = new int[world.Capacity];
_count = 0;
_poolRunners = new PoolRunners(world.Pipeline);
}
#endregion
#region Write/Read/Has/Del
private ProfilerMarker _addMark = new ProfilerMarker("EcsPoo.Add");
private ProfilerMarker _writeMark = new ProfilerMarker("EcsPoo.Write");
private ProfilerMarker _readMark = new ProfilerMarker("EcsPoo.Read");
private ProfilerMarker _hasMark = new ProfilerMarker("EcsPoo.Has");
private ProfilerMarker _delMark = new ProfilerMarker("EcsPoo.Del");
public ref T Add(int entityID)
{
// using (_addMark.Auto())
// {
if (_mapping[entityID] <= 0)
{
_mapping[entityID] = ++_count;
_poolRunners.add.OnComponentAdd<T>(entityID);
}
return ref _component;
// }
}
2023-04-24 16:48:18 +08:00
2023-04-21 03:16:05 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref T Write(int entityID)
{
// using (_writeMark.Auto())
_poolRunners.write.OnComponentWrite<T>(entityID);
return ref _component;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ref readonly T Read(int entityID)
{
// using (_readMark.Auto())
return ref _component;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public sealed override bool Has(int entityID)
{
// using (_hasMark.Auto())
return _mapping[entityID] > 0;
}
public void Del(int entityID)
{
// using (_delMark.Auto())
// {
_mapping[entityID] = 0;
_count--;
_poolRunners.del.OnComponentDel<T>(entityID);
// }
}
#endregion
#region WorldCallbacks
protected override void OnWorldResize(int newSize)
{
Array.Resize(ref _mapping, newSize);
}
protected override void OnDestroy() { }
#endregion
}
2023-04-24 16:48:18 +08:00
/// <summary> Singleton component </summary>
2023-04-21 14:21:24 +08:00
public interface IEcsSingleComponent { }
2023-04-21 03:46:51 +08:00
public static class EcsSinglePoolExt
2023-04-21 03:16:05 +08:00
{
2023-04-21 03:46:51 +08:00
public static EcsSinglePool<TSingleComponent> GetPool<TSingleComponent>(this EcsWorld self)
2023-04-21 14:21:24 +08:00
where TSingleComponent : struct, IEcsSingleComponent
2023-04-21 03:16:05 +08:00
{
2023-04-21 03:46:51 +08:00
return self.GetPool<TSingleComponent, EcsSinglePool<TSingleComponent>>();
2023-04-21 16:03:50 +08:00
}
public static EcsSinglePool<TSingleComponent> Include<TSingleComponent>(this EcsQueryBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent
{
return self.Include<TSingleComponent, EcsSinglePool<TSingleComponent>>();
}
public static EcsSinglePool<TSingleComponent> Exclude<TSingleComponent>(this EcsQueryBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent
{
return self.Exclude<TSingleComponent, EcsSinglePool<TSingleComponent>>();
}
public static EcsSinglePool<TSingleComponent> Optional<TSingleComponent>(this EcsQueryBuilderBase self) where TSingleComponent : struct, IEcsSingleComponent
{
return self.Optional<TSingleComponent, EcsSinglePool<TSingleComponent>>();
}
2023-04-21 03:16:05 +08:00
}
}