2024-11-01 12:41:10 +08:00
|
|
|
|
using DCFApixels.DragonECS.Core;
|
|
|
|
|
|
using DCFApixels.DragonECS.Internal;
|
2024-10-11 18:28:46 +08:00
|
|
|
|
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
|
2023-05-07 00:50:02 +08:00
|
|
|
|
{
|
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-11-01 12:41:10 +08:00
|
|
|
|
public TExecutor GetExecutor<TExecutor>(IComponentMask 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();
|
2023-05-26 06:18:09 +08:00
|
|
|
|
protected abstract void OnDestroy();
|
2023-05-07 00:50:02 +08:00
|
|
|
|
}
|
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;
|
2024-11-01 12:41:10 +08:00
|
|
|
|
_maskInc = mask._incs;
|
|
|
|
|
|
_maskExc = mask._excs;
|
|
|
|
|
|
_versions = UnmanagedArrayUtility.New<long>(1 + mask._incs.Length + mask._excs.Length);
|
2024-10-11 18:28:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
}
|