DragonECS/src/Executors/EcsQueryExecutor.cs

149 lines
4.7 KiB
C#
Raw Normal View History

2024-08-24 12:29:58 +08:00
using System;
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-08-24 12:29:58 +08:00
private readonly ExecutorMediator _executorsMediator;
public readonly struct ExecutorMediator
{
public readonly EcsWorld World;
internal ExecutorMediator(EcsWorld world)
{
if (world == null || world._executorsMediator.World != null)
{
throw new InvalidOperationException();
}
World = world;
}
2024-08-24 13:10:50 +08:00
public TExecutorCore GetCore<TExecutorCore>(EcsMask mask)
2024-10-02 22:13:10 +08:00
where TExecutorCore : EcsQueryExecutor, new()
2024-08-24 12:29:58 +08:00
{
2024-08-24 13:10:50 +08:00
var coreType = typeof(TExecutorCore);
2024-10-02 22:13:10 +08:00
if (World._executorCoures.TryGetValue((coreType, mask), out EcsQueryExecutor core) == false)
2024-08-24 12:29:58 +08:00
{
core = new TExecutorCore();
2024-08-24 13:10:50 +08:00
core.Initialize(World, mask);
World._executorCoures.Add((coreType, mask), core);
2024-08-24 12:29:58 +08:00
}
return (TExecutorCore)core;
}
2024-10-02 22:13:10 +08:00
public TExecutorCore GetCore<TExecutorCore>(EcsStaticMask staticMask)
where TExecutorCore : EcsQueryExecutor, new()
{
var coreType = typeof(TExecutorCore);
if (World._executorCoures.TryGetValue((coreType, staticMask), out EcsQueryExecutor core) == false)
{
core = new TExecutorCore();
core.Initialize(World, staticMask.ToMask(World));
World._executorCoures.Add((coreType, staticMask), core);
}
return (TExecutorCore)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)]
get { return _source.id; }
}
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; }
}
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;
}
protected abstract void OnInitialize();
protected abstract void OnDestroy();
}
2024-10-02 22:13:10 +08:00
public abstract class EcsQueryCache
{
2023-12-24 15:40:19 +08:00
private EcsWorld _source;
2024-08-24 12:29:58 +08:00
private EcsWorld.ExecutorMediator _mediator;
2024-03-17 05:22:36 +08:00
public short WorldID
2023-12-24 15:40:19 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-17 05:22:36 +08:00
get { return _source.id; }
2023-12-24 15:40:19 +08:00
}
public EcsWorld World
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2024-03-17 05:22:36 +08:00
get { return _source; }
2023-12-24 15:40:19 +08:00
}
2024-08-24 12:29:58 +08:00
protected EcsWorld.ExecutorMediator Mediator
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get { return _mediator; }
}
2023-12-24 15:40:19 +08:00
public abstract long Version { get; }
2024-08-24 12:29:58 +08:00
internal void Initialize(EcsWorld world, EcsWorld.ExecutorMediator mediator)
2023-05-27 15:59:46 +08:00
{
2023-12-24 15:40:19 +08:00
_source = world;
2024-08-24 12:29:58 +08:00
_mediator = mediator;
2023-05-27 15:59:46 +08:00
OnInitialize();
}
2023-12-24 15:40:19 +08:00
internal void Destroy()
{
OnDestroy();
_source = null;
}
2023-06-08 04:04:39 +08:00
protected abstract void OnInitialize();
protected abstract void OnDestroy();
}
2024-08-23 22:31:43 +08:00
public readonly struct PoolVersionsChecker
{
private readonly EcsMask _mask;
private readonly long[] _versions;
2024-08-24 12:29:58 +08:00
public PoolVersionsChecker(EcsMask mask)
2024-08-23 22:31:43 +08:00
{
_mask = mask;
_versions = new long[mask._inc.Length + mask._exc.Length];
}
public bool NextEquals()
{
var slots = _mask.World._poolSlots;
bool result = true;
int index = 0;
foreach (var i in _mask._inc)
{
if (slots[i].version != _versions[index++])
{
result = false;
}
}
foreach (var i in _mask._exc)
{
if (slots[i].version != _versions[index++])
{
result = false;
}
}
return result;
}
}
2023-12-24 15:40:19 +08:00
}