mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-11-13 00:55:55 +08:00
remove old mask/fixes
This commit is contained in:
parent
67aa840be9
commit
c3e55cb10b
183
src/EcsFilter.cs
183
src/EcsFilter.cs
@ -75,15 +75,13 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region EcsMask
|
||||
public sealed class EcsMask
|
||||
{
|
||||
internal readonly Type WorldArchetypeType;
|
||||
internal readonly int UniqueID;
|
||||
internal readonly int[] Inc;
|
||||
internal readonly int[] Exc;
|
||||
internal readonly int Hash;
|
||||
|
||||
internal int IncCount
|
||||
{
|
||||
@ -93,10 +91,11 @@ namespace DCFApixels.DragonECS
|
||||
internal int ExcCount
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => Inc.Length;
|
||||
get => Exc.Length;
|
||||
}
|
||||
internal EcsMask(int uniqueID, int[] inc, int[] exc)
|
||||
internal EcsMask(Type worldArchetypeType, int uniqueID, int[] inc, int[] exc)
|
||||
{
|
||||
WorldArchetypeType = worldArchetypeType;
|
||||
UniqueID = uniqueID;
|
||||
Inc = inc;
|
||||
Exc = exc;
|
||||
@ -109,6 +108,17 @@ namespace DCFApixels.DragonECS
|
||||
private static int _count;
|
||||
private static int _capacity;
|
||||
|
||||
public static int Count
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _count;
|
||||
}
|
||||
public static int Capacity
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _capacity;
|
||||
}
|
||||
|
||||
public static EcsMask GetMask<TInc, TExc>()
|
||||
where TInc : struct, IInc
|
||||
where TExc : struct, IExc
|
||||
@ -127,21 +137,26 @@ namespace DCFApixels.DragonECS
|
||||
Array.Sort(inc);
|
||||
Array.Sort(exc);
|
||||
|
||||
Type[] sortedInc = new Type[inc.Length];
|
||||
Type[] sortedExc = new Type[exc.Length];
|
||||
for (int i = 0; i < sortedInc.Length; i++)
|
||||
{
|
||||
sortedInc[i] = EcsWorld<TWorldArchetype>.ComponentType.types[inc[i]];
|
||||
}
|
||||
for (int i = 0; i < sortedInc.Length; i++)
|
||||
{
|
||||
sortedExc[i] = EcsWorld<TWorldArchetype>.ComponentType.types[exc[i]];
|
||||
}
|
||||
Type thisType = typeof(Activator<TInc, TExc>);
|
||||
Type sortedIncType = typeof(TInc).GetGenericTypeDefinition().MakeGenericType(sortedInc);
|
||||
Type sortedExcType = typeof(TExc).GetGenericTypeDefinition().MakeGenericType(sortedExc);
|
||||
|
||||
Type targetType = typeof(Activator<,>).MakeGenericType(sortedIncType, sortedExcType);
|
||||
Type sortedIncType = typeof(TInc);
|
||||
if (sortedIncType.IsGenericType)
|
||||
{
|
||||
Type[] sortedInc = new Type[inc.Length];
|
||||
for (int i = 0; i < sortedInc.Length; i++)
|
||||
sortedInc[i] = EcsWorld<TWorldArchetype>.ComponentType.types[inc[i]];
|
||||
sortedIncType = sortedIncType.GetGenericTypeDefinition().MakeGenericType(sortedInc);
|
||||
}
|
||||
Type sortedExcType = typeof(TExc);
|
||||
if (sortedExcType.IsGenericType)
|
||||
{
|
||||
Type[] sortedExc = new Type[exc.Length];
|
||||
for (int i = 0; i < sortedExc.Length; i++)
|
||||
sortedExc[i] = EcsWorld<TWorldArchetype>.ComponentType.types[exc[i]];
|
||||
sortedExcType = sortedExcType.GetGenericTypeDefinition().MakeGenericType(sortedExc);
|
||||
}
|
||||
|
||||
Type targetType = typeof(Activator<,>).MakeGenericType(typeof(TWorldArchetype), sortedIncType, sortedExcType);
|
||||
|
||||
if(targetType != thisType)
|
||||
{
|
||||
@ -153,7 +168,7 @@ namespace DCFApixels.DragonECS
|
||||
if (_count >= _capacity)
|
||||
_capacity <<= 1;
|
||||
|
||||
instance = new EcsMask(id, inc, exc);
|
||||
instance = new EcsMask(typeof(TWorldArchetype), id, inc, exc);
|
||||
}
|
||||
|
||||
public readonly static EcsMask instance;
|
||||
@ -161,133 +176,11 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region BakedMask
|
||||
public abstract class BakedMask
|
||||
{
|
||||
internal readonly int[] Inc;
|
||||
internal readonly int[] Exc;
|
||||
internal readonly Mask Mask;
|
||||
|
||||
internal int IncCount
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => Inc.Length;
|
||||
}
|
||||
internal int ExcCount
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => Exc.Length;
|
||||
}
|
||||
|
||||
//Уникальный айди в рамках одного архиетипа мира
|
||||
internal abstract int UniqueID { get; }
|
||||
internal abstract Type WorldArchetypeType { get; }
|
||||
|
||||
protected BakedMask(int[] inc, int[] exc, Mask mask)
|
||||
{
|
||||
Inc = inc;
|
||||
Exc = exc;
|
||||
Mask = mask;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class BakedMask<TWorldArchetype> : BakedMask
|
||||
{
|
||||
internal static int increment = 1;
|
||||
internal static int capacity = 512;
|
||||
|
||||
protected BakedMask(int[] inc, int[] exc, Mask mask) : base(inc, exc, mask) { }
|
||||
|
||||
|
||||
}
|
||||
|
||||
public sealed class BakedMask<TWorldArchetype, TMask> : BakedMask<TWorldArchetype>
|
||||
where TWorldArchetype : IWorldArchetype
|
||||
where TMask : Mask, new()
|
||||
{
|
||||
public static readonly int uniqueID;
|
||||
|
||||
static BakedMask()
|
||||
{
|
||||
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>();
|
||||
}
|
||||
|
||||
private BakedMask() : base(
|
||||
MaskSingleton<TMask>.Instance.MakeInc<IWorldArchetype>(),
|
||||
MaskSingleton<TMask>.Instance.MakeExc<IWorldArchetype>(),
|
||||
MaskSingleton<TMask>.Instance)
|
||||
{ }
|
||||
|
||||
private static readonly BakedMask<TWorldArchetype, TMask> _instance;
|
||||
public static BakedMask<TWorldArchetype, TMask> Instance
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _instance;
|
||||
}
|
||||
internal override int UniqueID
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => uniqueID;
|
||||
}
|
||||
internal override Type WorldArchetypeType
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => typeof(IWorldArchetype);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#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>
|
||||
where TSelf : Mask, new()
|
||||
{
|
||||
protected static TSelf _instance = new TSelf();
|
||||
internal static TSelf Instance
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _instance;
|
||||
}
|
||||
}
|
||||
public class Mask<TInc> : Mask where TInc : struct, IInc
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal override int[] MakeInc<TWorldArchetype>() => new TInc().GetComponentsIDs<TWorldArchetype>().Sort();
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal override int[] MakeExc<TWorldArchetype>() => Array.Empty<int>();
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override BakedMask GetBaked<TWorldArchetype>() => BakedMask<TWorldArchetype, Mask<TInc>>.Instance;
|
||||
}
|
||||
public class Mask<TInc, TExc> : Mask where TInc : struct, IInc where TExc : struct, IExc
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal override int[] MakeInc<TWorldArchetype>() => new TInc().GetComponentsIDs<TWorldArchetype>().Sort();
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal override int[] MakeExc<TWorldArchetype>() => new TExc().GetComponentsIDs<TWorldArchetype>().Sort();
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override BakedMask GetBaked<TWorldArchetype>() => BakedMask<TWorldArchetype, Mask<TInc, TExc>>.Instance;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Filter
|
||||
public interface IEcsFilter
|
||||
{
|
||||
public IEcsWorld World { get; }
|
||||
public BakedMask Mask { get; }
|
||||
public EcsMask Mask { get; }
|
||||
public IEcsReadonlyGroup Entities { get; }
|
||||
public int EntitiesCount { get; }
|
||||
}
|
||||
@ -296,7 +189,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
private readonly IEcsWorld _source;
|
||||
private readonly EcsGroup _entities;
|
||||
private readonly BakedMask _mask;
|
||||
private readonly EcsMask _mask;
|
||||
|
||||
#region Properties
|
||||
public IEcsWorld World
|
||||
@ -304,7 +197,7 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _source;
|
||||
}
|
||||
public BakedMask Mask
|
||||
public EcsMask Mask
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _mask;
|
||||
@ -322,7 +215,7 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Constrcutors
|
||||
internal EcsFilter(IEcsWorld source, BakedMask mask, int capasity)
|
||||
internal EcsFilter(IEcsWorld source, EcsMask mask, int capasity)
|
||||
{
|
||||
_source = source;
|
||||
_mask = mask;
|
||||
|
||||
@ -26,8 +26,8 @@ namespace DCFApixels.DragonECS
|
||||
public ent NewEntity();
|
||||
public void Destroy();
|
||||
|
||||
public bool IsMaskCompatible(Mask mask, int entity);
|
||||
public bool IsMaskCompatibleWithout(Mask mask, int entity, int otherPoolID);
|
||||
public bool IsMaskCompatible(EcsMask mask, int entity);
|
||||
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherPoolID);
|
||||
|
||||
internal void OnEntityComponentAdded(int entityID, int changedPoolID);
|
||||
internal void OnEntityComponentRemoved(int entityID, int changedPoolID);
|
||||
@ -105,31 +105,24 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region GetFilter
|
||||
|
||||
public EcsFilter GetFilter<TInc>() where TInc : struct, IInc
|
||||
{
|
||||
return GetFilterInternal<Mask<TInc>>();
|
||||
}
|
||||
public EcsFilter GetFilter<TInc>() where TInc : struct, IInc => GetFilter<TInc, Exc>();
|
||||
public EcsFilter GetFilter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc
|
||||
{
|
||||
return GetFilterInternal<Mask<TInc, TExc>>();
|
||||
}
|
||||
private EcsFilter GetFilterInternal<TMask>() where TMask : Mask, new()
|
||||
{
|
||||
var bakedmask = BakedMask<TArchetype, TMask>.Instance;
|
||||
var mask = EcsMaskMap<TArchetype>.GetMask<TInc, Exc>();
|
||||
|
||||
if (_filters.Length >= BakedMask<TArchetype>.capacity)
|
||||
if (_filters.Length <= EcsMaskMap<TArchetype>.Capacity)
|
||||
{
|
||||
Array.Resize(ref _filters, BakedMask<TArchetype>.capacity);
|
||||
Array.Resize(ref _filters, EcsMaskMap<TArchetype>.Capacity);
|
||||
}
|
||||
|
||||
if (_filters[bakedmask.UniqueID] == null)
|
||||
if (_filters[mask.UniqueID] == null)
|
||||
{
|
||||
_filters[bakedmask.UniqueID] = NewFilter(bakedmask);
|
||||
_filters[mask.UniqueID] = NewFilter(mask);
|
||||
}
|
||||
return _filters[bakedmask.UniqueID];
|
||||
return _filters[mask.UniqueID];
|
||||
}
|
||||
|
||||
private EcsFilter NewFilter(BakedMask mask, int capacirty = 512)
|
||||
private EcsFilter NewFilter(EcsMask mask, int capacirty = 512)
|
||||
{
|
||||
var newFilter = new EcsFilter(this, mask, capacirty);
|
||||
|
||||
@ -162,19 +155,22 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region IsMaskCompatible/IsMaskCompatibleWithout
|
||||
public bool IsMaskCompatible(Mask mask, int entity)
|
||||
public bool IsMaskCompatible(EcsMask mask, int entity)
|
||||
{
|
||||
BakedMask bakedMask = mask.GetBaked<TArchetype>();
|
||||
for (int i = 0, iMax = bakedMask.IncCount; i < iMax; i++)
|
||||
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS
|
||||
if (mask.WorldArchetypeType != typeof(TArchetype))
|
||||
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
|
||||
#endif
|
||||
for (int i = 0, iMax = mask.IncCount; i < iMax; i++)
|
||||
{
|
||||
if (!_pools[bakedMask.Inc[i]].Has(entity))
|
||||
if (!_pools[mask.Inc[i]].Has(entity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0, iMax = bakedMask.ExcCount; i < iMax; i++)
|
||||
for (int i = 0, iMax = mask.ExcCount; i < iMax; i++)
|
||||
{
|
||||
if (_pools[bakedMask.Exc[i]].Has(entity))
|
||||
if (_pools[mask.Exc[i]].Has(entity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -182,20 +178,23 @@ namespace DCFApixels.DragonECS
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsMaskCompatibleWithout(Mask mask, int entity, int otherPoolID)
|
||||
public bool IsMaskCompatibleWithout(EcsMask mask, int entity, int otherPoolID)
|
||||
{
|
||||
BakedMask bakedMask = mask.GetBaked<TArchetype>();
|
||||
for (int i = 0, iMax = bakedMask.IncCount; i < iMax; i++)
|
||||
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS
|
||||
if (mask.WorldArchetypeType != typeof(TArchetype))
|
||||
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TArchetype)");
|
||||
#endif
|
||||
for (int i = 0, iMax = mask.IncCount; i < iMax; i++)
|
||||
{
|
||||
int poolID = bakedMask.Inc[i];
|
||||
int poolID = mask.Inc[i];
|
||||
if (poolID == otherPoolID || !_pools[poolID].Has(entity))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (int i = 0, iMax = bakedMask.ExcCount; i < iMax; i++)
|
||||
for (int i = 0, iMax = mask.ExcCount; i < iMax; i++)
|
||||
{
|
||||
int poolID = bakedMask.Exc[i];
|
||||
int poolID = mask.Exc[i];
|
||||
if (poolID != otherPoolID && _pools[poolID].Has(entity))
|
||||
{
|
||||
return false;
|
||||
@ -215,7 +214,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
foreach (var filter in includeList)
|
||||
{
|
||||
if (IsMaskCompatible(filter.Mask.Mask, entityID))
|
||||
if (IsMaskCompatible(filter.Mask, entityID))
|
||||
{
|
||||
filter.Add(entityID);
|
||||
}
|
||||
@ -225,7 +224,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
foreach (var filter in excludeList)
|
||||
{
|
||||
if (IsMaskCompatibleWithout(filter.Mask.Mask, entityID, changedPoolID))
|
||||
if (IsMaskCompatibleWithout(filter.Mask, entityID, changedPoolID))
|
||||
{
|
||||
filter.Remove(entityID);
|
||||
}
|
||||
@ -242,7 +241,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
foreach (var filter in includeList)
|
||||
{
|
||||
if (IsMaskCompatible(filter.Mask.Mask, entityID))
|
||||
if (IsMaskCompatible(filter.Mask, entityID))
|
||||
{
|
||||
filter.Remove(entityID);
|
||||
}
|
||||
@ -252,7 +251,7 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
foreach (var filter in excludeList)
|
||||
{
|
||||
if (IsMaskCompatibleWithout(filter.Mask.Mask, entityID, changedPoolID))
|
||||
if (IsMaskCompatibleWithout(filter.Mask, entityID, changedPoolID))
|
||||
{
|
||||
filter.Add(entityID);
|
||||
}
|
||||
@ -278,33 +277,33 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Utils
|
||||
internal abstract class ComponentType
|
||||
internal static class ComponentType
|
||||
{
|
||||
internal static int increment = 1;
|
||||
internal static int Capacity
|
||||
{
|
||||
get => types.Length;
|
||||
}
|
||||
internal static Type[] types;
|
||||
internal static Type[] types = new Type[64];
|
||||
}
|
||||
internal sealed class ComponentType<T> : ComponentType
|
||||
internal static class ComponentType<T>
|
||||
{
|
||||
internal static int uniqueID;
|
||||
|
||||
static ComponentType()
|
||||
{
|
||||
uniqueID = increment++;
|
||||
uniqueID = ComponentType.increment++;
|
||||
#if DEBUG || DCFAECS_NO_SANITIZE_CHECKS
|
||||
if (increment + 1 > ushort.MaxValue)
|
||||
if (ComponentType.increment + 1 > ushort.MaxValue)
|
||||
{
|
||||
throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype");
|
||||
}
|
||||
#endif
|
||||
if (increment > Capacity)
|
||||
if (uniqueID >= ComponentType.types.Length)
|
||||
{
|
||||
Array.Resize(ref types, Capacity << 1);
|
||||
Array.Resize(ref ComponentType.types, ComponentType.types.Length << 1);
|
||||
}
|
||||
types[uniqueID] = typeof(T);
|
||||
ComponentType.types[uniqueID] = typeof(T);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -3,4 +3,8 @@
|
||||
DCFAECS_NO_SANITIZE_CHECKS - отвключение дополнительных проверок
|
||||
|
||||
public const int MAX_WORLDS = byte.MaxValue; //Номер последнего мира 254
|
||||
public const int DEAD_WORLD_ID = byte.MaxValue; //Зарезервированный номер мира для мертвых сущьностей
|
||||
public const int DEAD_WORLD_ID = byte.MaxValue; //Зарезервированный номер мира для мертвых сущьностей
|
||||
|
||||
|
||||
|
||||
#if DEBUG || !DCFAECS_NO_SANITIZE_CHECKS
|
||||
|
||||
@ -26,6 +26,11 @@ namespace DCFApixels.DragonECS
|
||||
int has4 = x4.GetHashCode();
|
||||
int has5 = x5.GetHashCode();
|
||||
|
||||
Debug.Log("1 " + has1);
|
||||
Debug.Log("2 " + has2);
|
||||
Debug.Log("3 " + has3);
|
||||
Debug.Log("4 " + has4);
|
||||
Debug.Log("5 " + has5);
|
||||
var e = _world.NewEntity();
|
||||
e.Write<TransfromCom>().position = Vector3.zero;
|
||||
e.Write<View>().Ref = _sharedData.view1;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user