DragonECS/src/Executors/EcsQueryExecutor.cs

162 lines
4.7 KiB
C#
Raw Normal View History

2024-10-11 18:28:46 +08:00
using DCFApixels.DragonECS.Internal;
using System;
2024-08-24 12:29:58 +08:00
using System.Collections.Generic;
using System.Runtime.CompilerServices;
2023-12-24 15:40:19 +08:00
namespace DCFApixels.DragonECS
{
2024-08-24 12:29:58 +08:00
public partial class EcsWorld
{
2024-10-02 22:13:10 +08:00
private readonly Dictionary<(Type, object), EcsQueryExecutor> _executorCoures = new Dictionary<(Type, object), EcsQueryExecutor>(256);
2024-10-05 18:05:33 +08:00
public TExecutor GetExecutor<TExecutor>(IEcsComponentMask mask)
2024-10-03 08:20:22 +08:00
where TExecutor : EcsQueryExecutor, new()
2024-08-24 12:29:58 +08:00
{
2024-10-03 08:20:22 +08:00
var coreType = typeof(TExecutor);
if (_executorCoures.TryGetValue((coreType, mask), out EcsQueryExecutor core) == false)
2024-08-24 12:29:58 +08:00
{
2024-10-03 08:20:22 +08:00
core = new TExecutor();
2024-10-05 18:05:33 +08:00
core.Initialize(this, mask.ToMask(this));
2024-10-03 08:20:22 +08:00
_executorCoures.Add((coreType, mask), core);
2024-08-24 12:29:58 +08:00
}
2024-10-03 08:20:22 +08:00
return (TExecutor)core;
}
2024-08-24 12:29:58 +08:00
}
2024-10-02 22:13:10 +08:00
public abstract class EcsQueryExecutor
2024-08-24 12:29:58 +08:00
{
private EcsWorld _source;
2024-08-24 13:10:50 +08:00
private EcsMask _mask;
2024-08-24 12:29:58 +08:00
public short WorldID
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-10-31 16:27:53 +08:00
get { return _source.ID; }
2024-08-24 12:29:58 +08:00
}
public EcsWorld World
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _source; }
}
2024-08-24 13:10:50 +08:00
protected EcsMask Mask
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _mask; }
}
2024-10-03 08:20:22 +08:00
public abstract long Version { get; }
2024-08-24 13:10:50 +08:00
internal void Initialize(EcsWorld world, EcsMask mask)
2024-08-24 12:29:58 +08:00
{
_source = world;
2024-08-24 13:10:50 +08:00
_mask = mask;
2024-08-24 12:29:58 +08:00
OnInitialize();
}
internal void Destroy()
{
OnDestroy();
_source = null;
2023-12-24 15:40:19 +08:00
}
2023-06-08 04:04:39 +08:00
protected abstract void OnInitialize();
protected abstract void OnDestroy();
}
2024-08-23 22:31:43 +08:00
2024-10-11 18:28:46 +08:00
public readonly unsafe struct WorldStateVersionsChecker : IDisposable
2024-08-23 22:31:43 +08:00
{
2024-10-11 18:28:46 +08:00
private readonly EcsWorld _world;
private readonly int[] _maskInc;
private readonly int[] _maskExc;
// [0] world version
// [-> _maskInc.Length] inc versions
// [-> _maskExc.Length] exc versions
private readonly long* _versions;
public long Version
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _versions[0]; }
}
2024-08-23 22:31:43 +08:00
2024-10-11 18:28:46 +08:00
public WorldStateVersionsChecker(EcsMask mask)
2024-08-23 22:31:43 +08:00
{
2024-10-11 18:28:46 +08:00
_world = mask.World;
_maskInc = mask._inc;
_maskExc = mask._exc;
_versions = UnmanagedArrayUtility.New<long>(1 + mask._inc.Length + mask._exc.Length);
}
public bool Check()
{
if (*_versions == _world.Version)
{
return true;
}
2024-10-31 14:46:21 +08:00
long* versionsPtr = _versions;
2024-10-11 18:28:46 +08:00
var slots = _world._poolSlots;
foreach (var slotIndex in _maskInc)
{
2024-10-31 14:46:21 +08:00
versionsPtr++;
if (*versionsPtr != slots[slotIndex].version)
2024-10-11 18:28:46 +08:00
{
return false;
}
}
foreach (var slotIndex in _maskExc)
{
2024-10-31 14:46:21 +08:00
versionsPtr++;
if (*versionsPtr != slots[slotIndex].version)
2024-10-11 18:28:46 +08:00
{
return false;
}
}
return true;
2024-08-23 22:31:43 +08:00
}
2024-10-11 18:28:46 +08:00
public void Next()
{
*_versions = _world.Version;
2024-08-23 22:31:43 +08:00
2024-10-11 18:28:46 +08:00
long* ptr = _versions;
var slots = _world._poolSlots;
foreach (var slotIndex in _maskInc)
{
ptr++;
*ptr = slots[slotIndex].version;
}
foreach (var slotIndex in _maskExc)
{
ptr++;
*ptr = slots[slotIndex].version;
}
}
public bool CheckAndNext()
2024-08-23 22:31:43 +08:00
{
2024-10-11 18:28:46 +08:00
if (*_versions == _world.Version)
{
return true;
}
*_versions = _world.Version;
long* ptr = _versions;
var slots = _world._poolSlots;
2024-08-23 22:31:43 +08:00
bool result = true;
2024-10-11 18:28:46 +08:00
foreach (var slotIndex in _maskInc)
2024-08-23 22:31:43 +08:00
{
2024-10-11 18:28:46 +08:00
ptr++;
if (*ptr != slots[slotIndex].version)
2024-08-23 22:31:43 +08:00
{
result = false;
2024-10-11 18:28:46 +08:00
*ptr = slots[slotIndex].version;
2024-08-23 22:31:43 +08:00
}
}
2024-10-11 18:28:46 +08:00
foreach (var slotIndex in _maskExc)
2024-08-23 22:31:43 +08:00
{
2024-10-11 18:28:46 +08:00
ptr++;
if (*ptr != slots[slotIndex].version)
2024-08-23 22:31:43 +08:00
{
result = false;
2024-10-11 18:28:46 +08:00
*ptr = slots[slotIndex].version;
2024-08-23 22:31:43 +08:00
}
}
return result;
}
2024-10-11 18:28:46 +08:00
public void Dispose()
{
}
2024-08-23 22:31:43 +08:00
}
2023-12-24 15:40:19 +08:00
}