new masks

This commit is contained in:
Mikhail 2023-03-13 00:05:35 +08:00
parent 5371c0473c
commit 67aa840be9
2 changed files with 117 additions and 20 deletions

View File

@ -1,17 +1,18 @@
using System; using System;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Reflection;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
#region Incs/Excs base #region Incs/Excs base
public interface ICondition public interface IMaskCondition
{ {
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype; public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype;
} }
#endregion #endregion
#region Incs #region Incs
public interface IInc : ICondition { } public interface IInc : IMaskCondition { }
public struct Inc : IInc public struct Inc : IInc
{ {
@ -43,7 +44,7 @@ namespace DCFApixels.DragonECS
#endregion #endregion
#region Excs #region Excs
public interface IExc : ICondition { } public interface IExc : IMaskCondition { }
public struct Exc : IExc public struct Exc : IExc
{ {
@ -74,6 +75,93 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region EcsMask
public sealed class EcsMask
{
internal readonly int UniqueID;
internal readonly int[] Inc;
internal readonly int[] Exc;
internal readonly int Hash;
internal int IncCount
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Inc.Length;
}
internal int ExcCount
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get => Inc.Length;
}
internal EcsMask(int uniqueID, int[] inc, int[] exc)
{
UniqueID = uniqueID;
Inc = inc;
Exc = exc;
}
}
public static class EcsMaskMap<TWorldArchetype>
where TWorldArchetype : IWorldArchetype
{
private static int _count;
private static int _capacity;
public static EcsMask GetMask<TInc, TExc>()
where TInc : struct, IInc
where TExc : struct, IExc
{
return Activator<TInc, TExc>.instance;
}
private class Activator<TInc, TExc>
where TInc : struct, IInc
where TExc : struct, IExc
{
static Activator()
{
var inc = new TInc().GetComponentsIDs<TWorldArchetype>();
var exc = new TExc().GetComponentsIDs<TWorldArchetype>();
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);
if(targetType != thisType)
{
instance = (EcsMask)targetType.GetField(nameof(instance), BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic).GetValue(null);
return;
}
var id = _count++;
if (_count >= _capacity)
_capacity <<= 1;
instance = new EcsMask(id, inc, exc);
}
public readonly static EcsMask instance;
}
}
#endregion
#region BakedMask #region BakedMask
public abstract class BakedMask public abstract class BakedMask
{ {
@ -193,16 +281,6 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public override BakedMask GetBaked<TWorldArchetype>() => BakedMask<TWorldArchetype, Mask<TInc, TExc>>.Instance; 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)
{
Array.Sort(self);
return self;
}
}
#endregion #endregion
#region Filter #region Filter
@ -267,4 +345,19 @@ namespace DCFApixels.DragonECS
#endregion #endregion
} }
#endregion #endregion
#region Utils
internal static class ArrayExt
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static T[] Sort<T>(this T[] self)
{
Array.Sort(self);
return self;
}
}
#endregion
} }

View File

@ -90,9 +90,9 @@ namespace DCFApixels.DragonECS
if (uniqueID >= _pools.Length) if (uniqueID >= _pools.Length)
{ {
Array.Resize(ref _pools, ComponentType.capacity); Array.Resize(ref _pools, ComponentType.Capacity);
Array.Resize(ref _filtersByIncludedComponents, ComponentType.capacity); Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity);
Array.Resize(ref _filtersByExcludedComponents, ComponentType.capacity); Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity);
} }
if (_pools[uniqueID] == null) if (_pools[uniqueID] == null)
@ -281,7 +281,11 @@ namespace DCFApixels.DragonECS
internal abstract class ComponentType internal abstract class ComponentType
{ {
internal static int increment = 1; internal static int increment = 1;
internal static int capacity = 512; internal static int Capacity
{
get => types.Length;
}
internal static Type[] types;
} }
internal sealed class ComponentType<T> : ComponentType internal sealed class ComponentType<T> : ComponentType
{ {
@ -296,11 +300,11 @@ namespace DCFApixels.DragonECS
throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype"); throw new EcsFrameworkException($"No more room for new component for this {typeof(TArchetype).FullName} IWorldArchetype");
} }
#endif #endif
if (increment > Capacity)
if (increment > capacity)
{ {
capacity <<= 1; Array.Resize(ref types, Capacity << 1);
} }
types[uniqueID] = typeof(T);
} }
} }
#endregion #endregion