DragonECS/src/EcsFilter.cs

271 lines
8.3 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-03-12 20:45:18 +08:00
2023-03-02 14:42:44 +08:00
}
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
2023-03-12 20:45:18 +08:00
where TMask : Mask, new()
2023-03-02 14:42:44 +08:00
{
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;
2023-03-12 20:45:18 +08:00
2023-03-02 14:42:44 +08:00
_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-12 20:45:18 +08:00
private static readonly BakedMask<TWorldArchetype, TMask> _instance;
2023-03-02 14:42:44 +08:00
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;
}
2023-03-12 20:45:18 +08:00
public abstract class MaskSingleton<TSelf>
where TSelf : Mask, new()
2023-03-02 14:42:44 +08:00
{
2023-03-12 20:45:18 +08:00
protected static TSelf _instance = new TSelf();
2023-03-02 14:42:44 +08:00
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
}
2023-03-12 20:45:18 +08:00
public class Mask<TInc> : Mask where TInc : struct, IInc
2023-03-02 14:42:44 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-12 20:45:18 +08:00
internal override int[] MakeInc<TWorldArchetype>() => new TInc().GetComponentsIDs<TWorldArchetype>().Sort();
2023-03-02 14:42:44 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal override int[] MakeExc<TWorldArchetype>() => Array.Empty<int>();
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-12 20:45:18 +08:00
public override BakedMask GetBaked<TWorldArchetype>() => BakedMask<TWorldArchetype, Mask<TInc>>.Instance;
2023-03-02 14:42:44 +08:00
}
2023-03-12 20:45:18 +08:00
public class Mask<TInc, TExc> : Mask where TInc : struct, IInc where TExc : struct, IExc
2023-03-02 14:42:44 +08:00
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-12 20:45:18 +08:00
internal override int[] MakeInc<TWorldArchetype>() => new TInc().GetComponentsIDs<TWorldArchetype>().Sort();
2023-03-02 14:42:44 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-12 20:45:18 +08:00
internal override int[] MakeExc<TWorldArchetype>() => new TExc().GetComponentsIDs<TWorldArchetype>().Sort();
2023-03-02 14:42:44 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2023-03-12 20:45:18 +08:00
public override BakedMask GetBaked<TWorldArchetype>() => BakedMask<TWorldArchetype, Mask<TInc, TExc>>.Instance;
}
internal static class ArrayExt
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T[] Sort<T>(this T[] self)
2023-02-14 03:26:34 +08:00
{
2023-03-12 20:45:18 +08:00
Array.Sort(self);
return self;
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
}