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-13 21:11:54 +08:00
|
|
|
|
|
2023-02-14 03:26:34 +08:00
|
|
|
|
#region Incs
|
|
|
|
|
public interface IInc : ICondition { }
|
2023-02-13 21:11:54 +08:00
|
|
|
|
|
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-13 21:11:54 +08:00
|
|
|
|
|
2023-02-14 03:26:34 +08:00
|
|
|
|
#region Excs
|
|
|
|
|
public interface IExc : ICondition { }
|
2023-02-13 21:11:54 +08:00
|
|
|
|
|
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
|
|
|
|
}
|