DragonECS/src/EcsFilter.cs

274 lines
8.4 KiB
C#
Raw Normal View History

2023-02-07 17:11:56 +08:00
using System;
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS
{
2023-02-14 03:26:34 +08:00
#region Incs/Excs base
public interface ICondition
2023-02-07 17:11:56 +08:00
{
2023-03-02 14:42:44 +08:00
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype;
2023-02-07 17:11:56 +08:00
}
2023-02-14 03:26:34 +08:00
#endregion
2023-02-14 03:26:34 +08:00
#region Incs
public interface IInc : ICondition { }
2023-03-02 14:42:44 +08:00
public struct Inc : IInc
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype => Array.Empty<int>();
2023-02-14 03:26:34 +08:00
}
2023-03-02 14:42:44 +08:00
public struct Inc<T0> : IInc
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
public int[] GetComponentsIDs<TWorldArchetype>()
where TWorldArchetype : IWorldArchetype
2023-02-14 03:26:34 +08:00
{
return new int[]
{
2023-03-02 14:42:44 +08:00
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID
2023-02-14 03:26:34 +08:00
};
}
}
2023-03-02 14:42:44 +08:00
public struct Inc<T0, T1> : IInc
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
public int[] GetComponentsIDs<TWorldArchetype>()
where TWorldArchetype : IWorldArchetype
2023-02-14 03:26:34 +08:00
{
return new int[]
{
2023-03-02 14:42:44 +08:00
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID
2023-02-14 03:26:34 +08:00
};
}
}
#endregion
2023-02-14 03:26:34 +08:00
#region Excs
public interface IExc : ICondition { }
2023-03-02 14:42:44 +08:00
public struct Exc : IExc
2023-02-07 17:11:56 +08:00
{
2023-03-02 14:42:44 +08:00
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype => Array.Empty<int>();
2023-02-14 03:26:34 +08:00
}
2023-03-02 14:42:44 +08:00
public struct Exc<T0> : IExc
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
public int[] GetComponentsIDs<TWorldArchetype>()
where TWorldArchetype : IWorldArchetype
2023-02-14 03:26:34 +08:00
{
return new int[]
{
2023-03-02 14:42:44 +08:00
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
2023-02-14 03:26:34 +08:00
};
}
}
2023-03-02 14:42:44 +08:00
public struct Exc<T0, T1> : IExc
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
public int[] GetComponentsIDs<TWorldArchetype>()
where TWorldArchetype : IWorldArchetype
2023-02-14 03:26:34 +08:00
{
return new int[]
{
2023-03-02 14:42:44 +08:00
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID
2023-02-14 03:26:34 +08:00
};
}
}
2023-03-02 14:42:44 +08:00
#endregion
#region BakedMask
public abstract class BakedMask
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
internal readonly int[] Inc;
internal readonly int[] Exc;
internal readonly Mask Mask;
internal int IncCount
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Inc.Length;
2023-02-14 03:26:34 +08:00
}
2023-03-02 14:42:44 +08:00
internal int ExcCount
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Exc.Length;
2023-02-14 03:26:34 +08:00
}
2023-03-02 14:42:44 +08:00
//Уникальный айди в рамках одного архиетипа мира
internal abstract int UniqueID { get; }
internal abstract Type WorldArchetypeType { get; }
protected BakedMask(int[] inc, int[] exc, Mask mask)
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
Inc = inc;
Exc = exc;
Mask = mask;
2023-02-14 03:26:34 +08:00
}
}
2023-02-07 17:11:56 +08:00
2023-03-02 14:42:44 +08:00
public abstract class BakedMask<TWorldArchetype> : BakedMask
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
internal static int increment = 1;
internal static int capacity = 512;
2023-02-07 17:11:56 +08:00
2023-03-02 14:42:44 +08:00
protected BakedMask(int[] inc, int[] exc, Mask mask) : base(inc, exc, mask) { }
}
2023-02-07 17:11:56 +08:00
2023-03-02 14:42:44 +08:00
public sealed class BakedMask<TWorldArchetype, TMask> : BakedMask<TWorldArchetype>
where TWorldArchetype : IWorldArchetype
where TMask : MaskSingleton<TMask>
{
public static readonly int uniqueID;
2023-02-07 17:11:56 +08:00
2023-03-02 14:42:44 +08:00
static BakedMask()
2023-02-07 17:11:56 +08:00
{
2023-03-02 14:42:44 +08:00
uniqueID = increment++;
#if DEBUG || DCFAECS_NO_SANITIZE_CHECKS
if (uniqueID >= ushort.MaxValue)
throw new EcsFrameworkException($"No more room for new BakedMask for this {typeof(TWorldArchetype).FullName} IWorldArchetype");
#endif
if (increment > capacity)
capacity <<= 1;
_instance = new BakedMask<TWorldArchetype, TMask>();
2023-02-07 17:11:56 +08:00
}
2023-03-02 14:42:44 +08:00
private BakedMask() : base(
MaskSingleton<TMask>.Instance.MakeInc<IWorldArchetype>(),
MaskSingleton<TMask>.Instance.MakeExc<IWorldArchetype>(),
MaskSingleton<TMask>.Instance)
{ }
2023-02-07 17:11:56 +08:00
2023-03-02 14:42:44 +08:00
private static readonly BakedMask<TWorldArchetype, TMask> _instance = new BakedMask<TWorldArchetype, TMask>();
public static BakedMask<TWorldArchetype, TMask> Instance
2023-02-07 17:11:56 +08:00
{
2023-02-14 03:26:34 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _instance;
2023-02-07 17:11:56 +08:00
}
2023-03-02 14:42:44 +08:00
internal override int UniqueID
2023-02-07 17:11:56 +08:00
{
2023-02-14 03:26:34 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-02 14:42:44 +08:00
get => uniqueID;
2023-02-07 17:11:56 +08:00
}
2023-03-02 14:42:44 +08:00
internal override Type WorldArchetypeType
2023-02-07 17:11:56 +08:00
{
2023-02-14 03:26:34 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-02 14:42:44 +08:00
get => typeof(IWorldArchetype);
2023-02-07 17:11:56 +08:00
}
2023-02-14 03:26:34 +08:00
}
2023-03-02 14:42:44 +08:00
#endregion
2023-02-07 17:11:56 +08:00
2023-03-02 14:42:44 +08:00
#region Masks
public abstract class Mask
{
internal abstract int[] MakeInc<TWorldArchetype>() where TWorldArchetype : IWorldArchetype;
internal abstract int[] MakeExc<TWorldArchetype>() where TWorldArchetype : IWorldArchetype;
public abstract BakedMask GetBaked<TWorldArchetype>() where TWorldArchetype : IWorldArchetype;
}
public abstract class MaskSingleton<TSelf> : Mask
where TSelf : Mask
{
protected static TSelf _instance;
internal static TSelf Instance
2023-02-07 17:11:56 +08:00
{
2023-02-14 03:26:34 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _instance;
2023-02-07 17:11:56 +08:00
}
2023-03-02 14:42:44 +08:00
}
public class Mask<TInc> : MaskSingleton<Mask<TInc>>
where TInc : struct, IInc
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int[] MakeInc<TWorldArchetype>() => new TInc().GetComponentsIDs<TWorldArchetype>();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int[] MakeExc<TWorldArchetype>() => Array.Empty<int>();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override BakedMask GetBaked<TWorldArchetype>()
2023-02-07 17:11:56 +08:00
{
2023-03-02 14:42:44 +08:00
return BakedMask<TWorldArchetype, Mask<TInc>>.Instance;
2023-02-14 03:26:34 +08:00
}
2023-03-02 14:42:44 +08:00
static Mask() { _instance = new Mask<TInc>(); }
}
public class Mask<TInc, TExc> : MaskSingleton<Mask<TInc, TExc>>
where TInc : struct, IInc
where TExc : struct, IExc
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int[] MakeInc<TWorldArchetype>() => new TInc().GetComponentsIDs<TWorldArchetype>();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int[] MakeExc<TWorldArchetype>() => new TExc().GetComponentsIDs<TWorldArchetype>();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override BakedMask GetBaked<TWorldArchetype>()
2023-02-14 03:26:34 +08:00
{
2023-03-02 14:42:44 +08:00
return BakedMask<TWorldArchetype, Mask<TInc, TExc>>.Instance;
2023-02-14 03:26:34 +08:00
}
2023-03-02 14:42:44 +08:00
static Mask() { _instance = new Mask<TInc, TExc>(); }
2023-02-14 03:26:34 +08:00
}
#endregion
2023-02-07 17:11:56 +08:00
2023-02-14 03:26:34 +08:00
#region Filter
public interface IEcsFilter
{
2023-03-02 14:42:44 +08:00
public IEcsWorld World { get; }
public BakedMask Mask { get; }
2023-02-14 03:26:34 +08:00
public IEcsReadonlyGroup Entities { get; }
public int EntitiesCount { get; }
}
2023-02-07 17:11:56 +08:00
2023-02-14 03:26:34 +08:00
public class EcsFilter : IEcsFilter
{
2023-03-02 14:42:44 +08:00
private readonly IEcsWorld _source;
2023-02-14 03:26:34 +08:00
private readonly EcsGroup _entities;
2023-03-02 14:42:44 +08:00
private readonly BakedMask _mask;
2023-02-07 17:11:56 +08:00
2023-02-14 03:26:34 +08:00
#region Properties
2023-03-02 14:42:44 +08:00
public IEcsWorld World
2023-02-14 03:26:34 +08:00
{
2023-02-07 17:11:56 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-02-14 03:26:34 +08:00
get => _source;
}
2023-03-02 14:42:44 +08:00
public BakedMask Mask
2023-02-14 03:26:34 +08:00
{
2023-02-07 17:11:56 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-02-14 03:26:34 +08:00
get => _mask;
}
public IEcsReadonlyGroup Entities
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _entities;
}
public int EntitiesCount
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _entities.Count;
}
#endregion
#region Constrcutors
2023-03-02 14:42:44 +08:00
internal EcsFilter(IEcsWorld source, BakedMask mask, int capasity)
2023-02-14 03:26:34 +08:00
{
_source = source;
_mask = mask;
_entities = new EcsGroup(source, capasity);
2023-02-07 17:11:56 +08:00
}
2023-02-14 03:26:34 +08:00
#endregion
2023-02-07 17:11:56 +08:00
2023-02-14 03:26:34 +08:00
#region EntityChangedReact
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void Add(int entityID)
2023-02-07 17:11:56 +08:00
{
2023-02-14 03:26:34 +08:00
_entities.Add(entityID);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void Remove(int entityID)
{
_entities.Remove(entityID);
2023-02-07 17:11:56 +08:00
}
#endregion
}
2023-02-14 03:26:34 +08:00
#endregion
2023-02-07 17:11:56 +08:00
}