mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-09-18 01:44:35 +08:00
Merge branch 'new_dev'
This commit is contained in:
commit
374afe75a9
@ -5,6 +5,23 @@ using System.Linq;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public readonly struct Injector
|
||||
{
|
||||
private readonly EcsPipeline _pipeline;
|
||||
public Injector(EcsPipeline pipeline)
|
||||
{
|
||||
_pipeline = pipeline;
|
||||
}
|
||||
public void Inject<T>(T data)
|
||||
{
|
||||
_pipeline.Inject(data);
|
||||
}
|
||||
}
|
||||
public interface IInjectionBlock
|
||||
{
|
||||
void InjectTo(Injector i);
|
||||
}
|
||||
|
||||
[MetaName(nameof(PreInject))]
|
||||
[BindWithEcsRunner(typeof(EcsPreInjectRunner))]
|
||||
public interface IEcsPreInject : IEcsProcess
|
||||
@ -56,7 +73,14 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
void IEcsPreInject.PreInject(object obj)
|
||||
{
|
||||
foreach (var item in targets) item.PreInject(obj);
|
||||
if (obj is IInjectionBlock container)
|
||||
{
|
||||
container.InjectTo(new Injector(Pipeline));
|
||||
}
|
||||
foreach (var item in targets)
|
||||
{
|
||||
item.PreInject(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
[MetaTags(MetaTags.HIDDEN)]
|
||||
@ -74,9 +98,9 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
Type baseType = typeof(T).BaseType;
|
||||
if (baseType != typeof(object) && baseType != typeof(ValueType) && baseType != null)
|
||||
_baseTypeInjectRunner = (EcsBaseTypeInjectRunner)Activator.CreateInstance(typeof(EcsBaseTypeInjectRunner<>).MakeGenericType(baseType), Source);
|
||||
_baseTypeInjectRunner = (EcsBaseTypeInjectRunner)Activator.CreateInstance(typeof(EcsBaseTypeInjectRunner<>).MakeGenericType(baseType), Pipeline);
|
||||
else
|
||||
_baseTypeInjectRunner = new EcsObjectTypePreInjectRunner(Source);
|
||||
_baseTypeInjectRunner = new EcsObjectTypePreInjectRunner(Pipeline);
|
||||
}
|
||||
}
|
||||
internal abstract class EcsBaseTypeInjectRunner
|
||||
@ -155,7 +179,10 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
public static partial class EcsPipelineExtensions
|
||||
{
|
||||
public static void Inject<T>(EcsPipeline self, T data) => self.GetRunner<IEcsInject<T>>().Inject(data);
|
||||
public static void Inject<T>(this EcsPipeline self, T data)
|
||||
{
|
||||
self.GetRunner<IEcsInject<T>>().Inject(data);
|
||||
}
|
||||
}
|
||||
public static partial class EcsPipelineBuilderExtensions
|
||||
{
|
||||
@ -167,33 +194,33 @@ namespace DCFApixels.DragonECS
|
||||
self.AddModule(module);
|
||||
return self;
|
||||
}
|
||||
public static EcsPipeline.Builder Inject<A, B>(this EcsPipeline.Builder self, A a, B b)
|
||||
public static EcsPipeline.Builder Inject<T0, T1>(this EcsPipeline.Builder self, T0 d0, T1 d1)
|
||||
{
|
||||
return self.Inject(a).Inject(b);
|
||||
return self.Inject(d0).Inject(d1);
|
||||
}
|
||||
public static EcsPipeline.Builder Inject<A, B, C>(this EcsPipeline.Builder self, A a, B b, C c)
|
||||
public static EcsPipeline.Builder Inject<T0, T1, T2>(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2)
|
||||
{
|
||||
return self.Inject(a).Inject(b).Inject(c);
|
||||
return self.Inject(d0).Inject(d1).Inject(d2);
|
||||
}
|
||||
public static EcsPipeline.Builder Inject<A, B, C, D>(this EcsPipeline.Builder self, A a, B b, C c, D d)
|
||||
public static EcsPipeline.Builder Inject<T0, T1, T2, T3>(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3)
|
||||
{
|
||||
return self.Inject(a).Inject(b).Inject(c).Inject(d);
|
||||
return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3);
|
||||
}
|
||||
public static EcsPipeline.Builder Inject<A, B, C, D, E>(this EcsPipeline.Builder self, A a, B b, C c, D d, E e)
|
||||
public static EcsPipeline.Builder Inject<T0, T1, T2, T3, T4>(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4)
|
||||
{
|
||||
return self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e);
|
||||
return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4);
|
||||
}
|
||||
public static EcsPipeline.Builder Inject<A, B, C, D, E, F>(this EcsPipeline.Builder self, A a, B b, C c, D d, E e, F f)
|
||||
public static EcsPipeline.Builder Inject<T0, T1, T2, T3, T4, T5>(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 f)
|
||||
{
|
||||
return self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e).Inject(f);
|
||||
return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(f);
|
||||
}
|
||||
public static EcsPipeline.Builder Inject<A, B, C, D, E, F, G>(this EcsPipeline.Builder self, A a, B b, C c, D d, E e, F f, G g)
|
||||
public static EcsPipeline.Builder Inject<T0, T1, T2, T3, T4, T5, T6>(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 f, T6 d6)
|
||||
{
|
||||
return self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e).Inject(f).Inject(g);
|
||||
return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(f).Inject(d6);
|
||||
}
|
||||
public static EcsPipeline.Builder Inject<A, B, C, D, E, F, G, H>(this EcsPipeline.Builder self, A a, B b, C c, D d, E e, F f, G g, H h)
|
||||
public static EcsPipeline.Builder Inject<T0, T1, T2, T3, T4, T5, T6, T7>(this EcsPipeline.Builder self, T0 d0, T1 d1, T2 d2, T3 d3, T4 d4, T5 f, T6 d6, T7 d7)
|
||||
{
|
||||
return self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e).Inject(f).Inject(g).Inject(h);
|
||||
return self.Inject(d0).Inject(d1).Inject(d2).Inject(d3).Inject(d4).Inject(f).Inject(d6).Inject(d7);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,13 @@
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public sealed class EcsDefaultWorld : EcsWorld { }
|
||||
public sealed class EcsEventWorld : EcsWorld { }
|
||||
public sealed class EcsDefaultWorld : EcsWorld
|
||||
{
|
||||
public EcsDefaultWorld() : base(null) { }
|
||||
public EcsDefaultWorld(IEcsWorldConfig config) : base(config) { }
|
||||
}
|
||||
public sealed class EcsEventWorld : EcsWorld
|
||||
{
|
||||
public EcsEventWorld() : base(null) { }
|
||||
public EcsEventWorld(IEcsWorldConfig config) : base(config) { }
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ namespace DCFApixels.DragonECS
|
||||
public int WorldID
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get => _source.World.id;
|
||||
get => _source.WorldID;
|
||||
}
|
||||
public EcsWorld World
|
||||
{
|
||||
@ -106,17 +106,18 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsSubsetOf(EcsReadonlyGroup group) => _source.IsSubsetOf(group._source);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsSubsetOf(EcsGroup group) => _source.IsSubsetOf(group);
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsSupersetOf(EcsReadonlyGroup group) => _source.IsSupersetOf(group._source);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsSupersetOf(EcsGroup group) => _source.IsSupersetOf(group);
|
||||
#endregion
|
||||
|
||||
#region Internal
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
internal EcsGroup GetGroupInternal() => _source;
|
||||
|
||||
internal EcsGroup GetSource_Internal() => _source;
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
@ -293,7 +294,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region CopyFrom/Clone/Bake/ToSpan
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void CopyFrom(EcsReadonlyGroup group) => CopyFrom(group.GetGroupInternal());
|
||||
public void CopyFrom(EcsReadonlyGroup group) => CopyFrom(group.GetSource_Internal());
|
||||
public void CopyFrom(EcsGroup group)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
@ -347,7 +348,7 @@ namespace DCFApixels.DragonECS
|
||||
#region UnionWith
|
||||
/// <summary>as Union sets</summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void UnionWith(EcsReadonlyGroup group) => UnionWith(group.GetGroupInternal());
|
||||
public void UnionWith(EcsReadonlyGroup group) => UnionWith(group.GetSource_Internal());
|
||||
/// <summary>as Union sets</summary>
|
||||
public void UnionWith(EcsGroup group)
|
||||
{
|
||||
@ -374,7 +375,7 @@ namespace DCFApixels.DragonECS
|
||||
#region ExceptWith
|
||||
/// <summary>as Except sets</summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void ExceptWith(EcsReadonlyGroup group) => ExceptWith(group.GetGroupInternal());
|
||||
public void ExceptWith(EcsReadonlyGroup group) => ExceptWith(group.GetSource_Internal());
|
||||
/// <summary>as Except sets</summary>
|
||||
public void ExceptWith(EcsGroup group)
|
||||
{
|
||||
@ -432,7 +433,7 @@ namespace DCFApixels.DragonECS
|
||||
#region IntersectWith
|
||||
/// <summary>as Intersect sets</summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void IntersectWith(EcsReadonlyGroup group) => IntersectWith(group.GetGroupInternal());
|
||||
public void IntersectWith(EcsReadonlyGroup group) => IntersectWith(group.GetSource_Internal());
|
||||
/// <summary>as Intersect sets</summary>
|
||||
public void IntersectWith(EcsGroup group)
|
||||
{
|
||||
@ -451,7 +452,7 @@ namespace DCFApixels.DragonECS
|
||||
#region SymmetricExceptWith
|
||||
/// <summary>as Symmetric Except sets</summary>
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void SymmetricExceptWith(EcsReadonlyGroup group) => SymmetricExceptWith(group.GetGroupInternal());
|
||||
public void SymmetricExceptWith(EcsReadonlyGroup group) => SymmetricExceptWith(group.GetSource_Internal());
|
||||
/// <summary>as Symmetric Except sets</summary>
|
||||
public void SymmetricExceptWith(EcsGroup group)
|
||||
{
|
||||
@ -479,7 +480,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region SetEquals
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool SetEquals(EcsReadonlyGroup group) => SetEquals(group.GetGroupInternal());
|
||||
public bool SetEquals(EcsReadonlyGroup group) => SetEquals(group.GetSource_Internal());
|
||||
public bool SetEquals(EcsGroup group)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
@ -508,7 +509,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region Overlaps
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Overlaps(EcsReadonlyGroup group) => Overlaps(group.GetGroupInternal());
|
||||
public bool Overlaps(EcsReadonlyGroup group) => Overlaps(group.GetSource_Internal());
|
||||
public bool Overlaps(EcsGroup group)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
@ -542,7 +543,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region IsSubsetOf
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsSubsetOf(EcsReadonlyGroup group) => IsSubsetOf(group.GetGroupInternal());
|
||||
public bool IsSubsetOf(EcsReadonlyGroup group) => IsSubsetOf(group.GetSource_Internal());
|
||||
public bool IsSubsetOf(EcsGroup group)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
@ -559,7 +560,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
#region IsSupersetOf
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool IsSupersetOf(EcsReadonlyGroup group) => IsSupersetOf(group.GetGroupInternal());
|
||||
public bool IsSupersetOf(EcsReadonlyGroup group) => IsSupersetOf(group.GetSource_Internal());
|
||||
public bool IsSupersetOf(EcsGroup group)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
@ -764,7 +765,7 @@ namespace DCFApixels.DragonECS
|
||||
public int CapacitySparce => _group.CapacitySparce;
|
||||
public override string ToString() => _group.ToString();
|
||||
public DebuggerProxy(EcsGroup group) => _group = group;
|
||||
public DebuggerProxy(EcsReadonlyGroup group) : this(group.GetGroupInternal()) { }
|
||||
public DebuggerProxy(EcsReadonlyGroup group) : this(group.GetSource_Internal()) { }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
using DCFApixels.DragonECS.Utils;
|
||||
using DCFApixels.DragonECS.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
|
@ -1,5 +1,3 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
@ -16,14 +14,15 @@ namespace DCFApixels.DragonECS
|
||||
public static readonly bool isHasHandler;
|
||||
static EcsWorldComponentHandler()
|
||||
{
|
||||
Type targetType = typeof(T);
|
||||
isHasHandler = targetType.GetInterfaces().Contains(typeof(IEcsWorldComponent<>).MakeGenericType(targetType));
|
||||
if (isHasHandler)
|
||||
T def = default;
|
||||
if (def is IEcsWorldComponent<T> intrf)
|
||||
{
|
||||
instance = (IEcsWorldComponent<T>)Activator.CreateInstance(typeof(WorldComponentHandler<>).MakeGenericType(targetType));
|
||||
isHasHandler = true;
|
||||
instance = intrf;
|
||||
}
|
||||
else
|
||||
{
|
||||
isHasHandler = false;
|
||||
instance = new DummyHandler();
|
||||
}
|
||||
}
|
||||
@ -34,14 +33,6 @@ namespace DCFApixels.DragonECS
|
||||
public void OnDestroy(ref T component, EcsWorld world) { }
|
||||
}
|
||||
}
|
||||
internal class WorldComponentHandler<T> : IEcsWorldComponent<T>
|
||||
where T : IEcsWorldComponent<T>
|
||||
{
|
||||
private T _fakeInstnace = default;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Init(ref T component, EcsWorld world) => _fakeInstnace.Init(ref component, world);
|
||||
public void OnDestroy(ref T component, EcsWorld world) => _fakeInstnace.OnDestroy(ref component, world);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEcsComponentReset
|
||||
@ -55,14 +46,15 @@ namespace DCFApixels.DragonECS
|
||||
public static readonly bool isHasHandler;
|
||||
static EcsComponentResetHandler()
|
||||
{
|
||||
Type targetType = typeof(T);
|
||||
isHasHandler = targetType.GetInterfaces().Contains(typeof(IEcsComponentReset<>).MakeGenericType(targetType));
|
||||
if (isHasHandler)
|
||||
T def = default;
|
||||
if (def is IEcsComponentReset<T> intrf)
|
||||
{
|
||||
instance = (IEcsComponentReset<T>)Activator.CreateInstance(typeof(ComponentResetHandler<>).MakeGenericType(targetType));
|
||||
isHasHandler = true;
|
||||
instance = intrf;
|
||||
}
|
||||
else
|
||||
{
|
||||
isHasHandler = false;
|
||||
instance = new DummyHandler();
|
||||
}
|
||||
}
|
||||
@ -72,13 +64,6 @@ namespace DCFApixels.DragonECS
|
||||
public void Reset(ref T component) => component = default;
|
||||
}
|
||||
}
|
||||
internal sealed class ComponentResetHandler<T> : IEcsComponentReset<T>
|
||||
where T : IEcsComponentReset<T>
|
||||
{
|
||||
private T _fakeInstnace = default;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Reset(ref T component) => _fakeInstnace.Reset(ref component);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEcsComponentCopy
|
||||
@ -92,14 +77,15 @@ namespace DCFApixels.DragonECS
|
||||
public static readonly bool isHasHandler;
|
||||
static EcsComponentCopyHandler()
|
||||
{
|
||||
Type targetType = typeof(T);
|
||||
isHasHandler = targetType.GetInterfaces().Contains(typeof(IEcsComponentCopy<>).MakeGenericType(targetType));
|
||||
if (isHasHandler)
|
||||
T def = default;
|
||||
if (def is IEcsComponentCopy<T> intrf)
|
||||
{
|
||||
instance = (IEcsComponentCopy<T>)Activator.CreateInstance(typeof(ComponentCopyHandler<>).MakeGenericType(targetType));
|
||||
isHasHandler = true;
|
||||
instance = intrf;
|
||||
}
|
||||
else
|
||||
{
|
||||
isHasHandler = false;
|
||||
instance = new DummyHandler();
|
||||
}
|
||||
}
|
||||
@ -109,12 +95,5 @@ namespace DCFApixels.DragonECS
|
||||
public void Copy(ref T from, ref T to) => to = from;
|
||||
}
|
||||
}
|
||||
internal sealed class ComponentCopyHandler<T> : IEcsComponentCopy<T>
|
||||
where T : IEcsComponentCopy<T>
|
||||
{
|
||||
private T _fakeInstnace = default;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Copy(ref T from, ref T to) => _fakeInstnace.Copy(ref from, ref to);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
@ -41,6 +41,11 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static void PrintWarning(object v) => Print(EcsConsts.DEBUG_WARNING_TAG, v);
|
||||
public static void PrintError(object v) => Print(EcsConsts.DEBUG_ERROR_TAG, v);
|
||||
public static void PrintErrorAndBreak(object v)
|
||||
{
|
||||
Print(EcsConsts.DEBUG_ERROR_TAG, v);
|
||||
Break();
|
||||
}
|
||||
public static void PrintPass(object v) => Print(EcsConsts.DEBUG_PASS_TAG, v);
|
||||
public static void Print()
|
||||
{
|
||||
@ -176,7 +181,11 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public override void ProfilerMarkBegin(int id)
|
||||
{
|
||||
var color = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.DarkGray;
|
||||
_stopwatchs[id].Start();
|
||||
Print("ProfilerMark", $"{_stopwatchsNames[id]} start <");
|
||||
Console.ForegroundColor = color;
|
||||
}
|
||||
public override void ProfilerMarkEnd(int id)
|
||||
{
|
||||
@ -185,7 +194,7 @@ namespace DCFApixels.DragonECS
|
||||
_stopwatchs[id].Stop();
|
||||
var time = _stopwatchs[id].Elapsed;
|
||||
_stopwatchs[id].Reset();
|
||||
Print("ProfilerMark", _stopwatchsNames[id] + " s:" + time.TotalSeconds);
|
||||
Print("ProfilerMark", $"> {_stopwatchsNames[id]} s:{time.TotalSeconds}");
|
||||
Console.ForegroundColor = color;
|
||||
}
|
||||
protected override void OnDelProfilerMark(int id)
|
||||
|
@ -49,6 +49,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
private static string AutoToString(object target, Type type, bool isWriteName)
|
||||
{
|
||||
//TODO сделать специальный вывод в виде названий констант для Enum-ов
|
||||
var fields = type.GetFields(RFL_FLAGS);
|
||||
string[] values = new string[fields.Length];
|
||||
for (int i = 0; i < fields.Length; i++)
|
||||
|
@ -40,7 +40,7 @@ namespace DCFApixels.DragonECS
|
||||
private Builder(EcsWorld world)
|
||||
{
|
||||
_world = world;
|
||||
_maskBuilder = new EcsMask.Builder(world);
|
||||
_maskBuilder = EcsMask.New(world);
|
||||
}
|
||||
internal static unsafe TAspect New<TAspect>(EcsWorld world) where TAspect : EcsAspect
|
||||
{
|
||||
@ -113,16 +113,11 @@ namespace DCFApixels.DragonECS
|
||||
public TOtherAspect Combine<TOtherAspect>(int order = 0) where TOtherAspect : EcsAspect
|
||||
{
|
||||
var result = _world.GetAspect<TOtherAspect>();
|
||||
_maskBuilder.CombineWith(result.Mask);
|
||||
_maskBuilder.Combine(result.Mask);
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public EcsWorldCmp<T> GetWorldData<T>() where T : struct
|
||||
{
|
||||
return new EcsWorldCmp<T>(_world.id);
|
||||
}
|
||||
|
||||
private void Build(out EcsMask mask)
|
||||
{
|
||||
mask = _maskBuilder.Build();
|
||||
|
124
src/EcsMask.cs
124
src/EcsMask.cs
@ -7,20 +7,6 @@ using System.Runtime.CompilerServices;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public abstract partial class EcsWorld
|
||||
{
|
||||
private Dictionary<EcsMask.BuilderMaskKey, EcsMask> _masks = new Dictionary<EcsMask.BuilderMaskKey, EcsMask>(256);
|
||||
internal EcsMask GetMask_Internal(EcsMask.BuilderMaskKey maskKey)
|
||||
{
|
||||
if (!_masks.TryGetValue(maskKey, out EcsMask result))
|
||||
{
|
||||
result = new EcsMask(_masks.Count, id, maskKey.inc, maskKey.exc);
|
||||
_masks.Add(maskKey, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
[DebuggerTypeProxy(typeof(DebuggerProxy))]
|
||||
public sealed class EcsMask : IEquatable<EcsMask>
|
||||
{
|
||||
@ -42,6 +28,10 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
public static Builder New(EcsWorld world)
|
||||
{
|
||||
return new Builder(world);
|
||||
}
|
||||
internal EcsMask(int id, int worldID, int[] inc, int[] exc)
|
||||
{
|
||||
#if DEBUG
|
||||
@ -168,19 +158,69 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Builder
|
||||
public readonly struct BuilderMaskKey : IEquatable<BuilderMaskKey>
|
||||
private readonly struct WorldMaskComponent : IEcsWorldComponent<WorldMaskComponent>
|
||||
{
|
||||
private readonly EcsWorld _world;
|
||||
private readonly Dictionary<Key, EcsMask> _masks;
|
||||
|
||||
#region Constructor/Destructor
|
||||
public WorldMaskComponent(EcsWorld world, Dictionary<Key, EcsMask> masks)
|
||||
{
|
||||
_world = world;
|
||||
_masks = masks;
|
||||
}
|
||||
public void Init(ref WorldMaskComponent component, EcsWorld world)
|
||||
{
|
||||
component = new WorldMaskComponent(world, new Dictionary<Key, EcsMask>(256));
|
||||
}
|
||||
public void OnDestroy(ref WorldMaskComponent component, EcsWorld world)
|
||||
{
|
||||
component._masks.Clear();
|
||||
component = default;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetMask
|
||||
internal EcsMask GetMask(Key maskKey)
|
||||
{
|
||||
if (!_masks.TryGetValue(maskKey, out EcsMask result))
|
||||
{
|
||||
result = new EcsMask(_masks.Count, _world.id, maskKey.inc, maskKey.exc);
|
||||
_masks.Add(maskKey, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
private readonly struct Key : IEquatable<Key>
|
||||
{
|
||||
public readonly int[] inc;
|
||||
public readonly int[] exc;
|
||||
public readonly int hash;
|
||||
public BuilderMaskKey(int[] inc, int[] exc, int hash)
|
||||
|
||||
#region Constructors
|
||||
public Key(int[] inc, int[] exc)
|
||||
{
|
||||
this.inc = inc;
|
||||
this.exc = exc;
|
||||
this.hash = hash;
|
||||
unchecked
|
||||
{
|
||||
hash = inc.Length + exc.Length;
|
||||
for (int i = 0, iMax = inc.Length; i < iMax; i++)
|
||||
{
|
||||
hash = hash * EcsConsts.MAGIC_PRIME + inc[i];
|
||||
}
|
||||
for (int i = 0, iMax = exc.Length; i < iMax; i++)
|
||||
{
|
||||
hash = hash * EcsConsts.MAGIC_PRIME - exc[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Object
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public bool Equals(BuilderMaskKey other)
|
||||
public bool Equals(Key other)
|
||||
{
|
||||
if (inc.Length != other.inc.Length)
|
||||
{
|
||||
@ -204,16 +244,11 @@ namespace DCFApixels.DragonECS
|
||||
return false;
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
if (other.hash != hash)
|
||||
{
|
||||
throw new Exception("other.hash != hash");
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public override int GetHashCode() => hash;
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class Builder
|
||||
@ -223,49 +258,58 @@ namespace DCFApixels.DragonECS
|
||||
private readonly HashSet<int> _exc = new HashSet<int>();
|
||||
private readonly List<Combined> _combined = new List<Combined>();
|
||||
|
||||
#region Constrcutors
|
||||
internal Builder(EcsWorld world)
|
||||
{
|
||||
_world = world;
|
||||
}
|
||||
#endregion
|
||||
|
||||
public void Include<T>()
|
||||
#region Include/Exclude/Combine
|
||||
public Builder Include<T>()
|
||||
{
|
||||
int id = _world.GetComponentID<T>();
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(typeof(T));
|
||||
#endif
|
||||
_inc.Add(id);
|
||||
return this;
|
||||
}
|
||||
public void Exclude<T>()
|
||||
public Builder Exclude<T>()
|
||||
{
|
||||
int id = _world.GetComponentID<T>();
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(typeof(T));
|
||||
#endif
|
||||
_exc.Add(id);
|
||||
return this;
|
||||
}
|
||||
public void Include(Type type)
|
||||
public Builder Include(Type type)
|
||||
{
|
||||
int id = _world.GetComponentID(type);
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type);
|
||||
#endif
|
||||
_inc.Add(id);
|
||||
return this;
|
||||
}
|
||||
public void Exclude(Type type)
|
||||
public Builder Exclude(Type type)
|
||||
{
|
||||
int id = _world.GetComponentID(type);
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (_inc.Contains(id) || _exc.Contains(id)) Throw.ConstraintIsAlreadyContainedInMask(type);
|
||||
#endif
|
||||
_exc.Add(id);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void CombineWith(EcsMask mask, int order = 0)
|
||||
public Builder Combine(EcsMask mask, int order = 0)
|
||||
{
|
||||
_combined.Add(new Combined(mask, order));
|
||||
return this;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Build
|
||||
public EcsMask Build()
|
||||
{
|
||||
HashSet<int> combinedInc;
|
||||
@ -296,24 +340,16 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
var inc = combinedInc.ToArray();
|
||||
Array.Sort(inc);
|
||||
_inc.Clear();
|
||||
var exc = combinedExc.ToArray();
|
||||
Array.Sort(exc);
|
||||
_exc.Clear();
|
||||
|
||||
unchecked
|
||||
{
|
||||
int keyHash = inc.Length + exc.Length;
|
||||
for (int i = 0, iMax = inc.Length; i < iMax; i++)
|
||||
{
|
||||
keyHash = keyHash * EcsConsts.MAGIC_PRIME + inc[i];
|
||||
}
|
||||
for (int i = 0, iMax = exc.Length; i < iMax; i++)
|
||||
{
|
||||
keyHash = keyHash * EcsConsts.MAGIC_PRIME - exc[i];
|
||||
}
|
||||
BuilderMaskKey key = new BuilderMaskKey(inc, exc, keyHash);
|
||||
return _world.GetMask_Internal(key);
|
||||
}
|
||||
_combined.Clear();
|
||||
|
||||
return _world.Get<WorldMaskComponent>().GetMask(new Key(inc, exc));
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
private readonly struct Combined
|
||||
|
@ -38,16 +38,21 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Runners
|
||||
public T[] GetSystems<T>() where T : IEcsProcess
|
||||
{
|
||||
return _allSystems.Where(o => o is T).Select(o => (T)o).ToArray();
|
||||
}
|
||||
public T GetRunner<T>() where T : IEcsProcess
|
||||
{
|
||||
Type type = typeof(T);
|
||||
if (_runners.TryGetValue(type, out IEcsRunner result))
|
||||
{
|
||||
return (T)result;
|
||||
}
|
||||
result = (IEcsRunner)EcsRunner<T>.Instantiate(this);
|
||||
_runners.Add(type, result);
|
||||
return (T)result;
|
||||
}
|
||||
|
||||
internal void OnRunnerDestroy(IEcsRunner runner)
|
||||
{
|
||||
_runners.Remove(runner.Interface);
|
||||
|
@ -54,9 +54,9 @@ namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEcsRunner
|
||||
{
|
||||
EcsPipeline Source { get; }
|
||||
EcsPipeline Pipeline { get; }
|
||||
Type Interface { get; }
|
||||
IList Targets { get; }
|
||||
IList TargetsRaw { get; }
|
||||
object Filter { get; }
|
||||
bool IsHasFilter { get; }
|
||||
bool IsDestroyed { get; }
|
||||
@ -203,9 +203,10 @@ namespace DCFApixels.DragonECS
|
||||
private bool _isDestroyed;
|
||||
|
||||
#region Properties
|
||||
public EcsPipeline Source => _source;
|
||||
public EcsPipeline Pipeline => _source;
|
||||
public Type Interface => typeof(TInterface);
|
||||
public IList Targets => _targetsSealed;
|
||||
public IList TargetsRaw => _targetsSealed;
|
||||
public ReadOnlySpan<TInterface> Targets => targets;
|
||||
public object Filter => _filter;
|
||||
public bool IsHasFilter => _isHasFilter;
|
||||
public bool IsDestroyed => _isDestroyed;
|
||||
@ -225,9 +226,13 @@ namespace DCFApixels.DragonECS
|
||||
internal void Rebuild()
|
||||
{
|
||||
if (_isHasFilter)
|
||||
{
|
||||
Set(_source, FilterSystems(_source.AllSystems), _isHasFilter, _filter);
|
||||
}
|
||||
else
|
||||
{
|
||||
Set(_source, FilterSystems(_source.AllSystems, _filter), _isHasFilter, _filter);
|
||||
}
|
||||
}
|
||||
public void Destroy()
|
||||
{
|
||||
|
180
src/EcsWorld.cs
180
src/EcsWorld.cs
@ -9,6 +9,7 @@ namespace DCFApixels.DragonECS
|
||||
public abstract partial class EcsWorld
|
||||
{
|
||||
public readonly short id;
|
||||
private IEcsWorldConfig _config;
|
||||
|
||||
private bool _isDestroyed;
|
||||
|
||||
@ -23,7 +24,7 @@ namespace DCFApixels.DragonECS
|
||||
private int _delEntBufferCount;
|
||||
private int _delEntBufferMinCount;
|
||||
private int _freeSpace;
|
||||
private bool _isEnableReleaseDelEntBuffer = true;
|
||||
private bool _isEnableAutoReleaseDelEntBuffer = true;
|
||||
|
||||
private List<WeakReference<EcsGroup>> _groups = new List<WeakReference<EcsGroup>>();
|
||||
private Stack<EcsGroup> _groupsPool = new Stack<EcsGroup>(64);
|
||||
@ -36,41 +37,88 @@ namespace DCFApixels.DragonECS
|
||||
private readonly PoolsMediator _poolsMediator;
|
||||
|
||||
#region Properties
|
||||
public bool IsDestroyed => _isDestroyed;
|
||||
public int Count => _entitiesCount;
|
||||
public int Capacity => _entitesCapacity; //_denseEntities.Length;
|
||||
public IEcsWorldConfig Config
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _config; }
|
||||
}
|
||||
public bool IsDestroyed
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _isDestroyed; }
|
||||
}
|
||||
public int Count
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _entitiesCount; }
|
||||
}
|
||||
public int Capacity
|
||||
{
|
||||
//_denseEntities.Length;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _entitesCapacity; }
|
||||
}
|
||||
public int DelEntBufferCount
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _delEntBufferCount; }
|
||||
}
|
||||
public bool IsEnableReleaseDelEntBuffer
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _isEnableAutoReleaseDelEntBuffer; }
|
||||
}
|
||||
|
||||
public int DelEntBufferCount => _delEntBufferCount;
|
||||
public bool IsEnableReleaseDelEntBuffer => _isEnableReleaseDelEntBuffer;
|
||||
|
||||
public EcsReadonlyGroup Entities => _allEntites.Readonly;
|
||||
public ReadOnlySpan<IEcsPoolImplementation> AllPools => _pools;// new ReadOnlySpan<IEcsPoolImplementation>(pools, 0, _poolsCount);
|
||||
public EcsReadonlyGroup Entities
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get
|
||||
{
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
return _allEntites.Readonly;
|
||||
}
|
||||
}
|
||||
public ReadOnlySpan<IEcsPoolImplementation> AllPools
|
||||
{
|
||||
// new ReadOnlySpan<IEcsPoolImplementation>(pools, 0, _poolsCount);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
get { return _pools; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Constructors/Destroy
|
||||
public EcsWorld() : this(true) { }
|
||||
internal EcsWorld(bool isIndexable)
|
||||
public EcsWorld(IEcsWorldConfig config) : this(config, true) { }
|
||||
private EcsWorld(IEcsWorldConfig config, bool isIndexable)
|
||||
{
|
||||
const int POOLS_CAPACITY = 512;
|
||||
_poolsMediator = new PoolsMediator(this);
|
||||
|
||||
_entitesCapacity = 512;
|
||||
if (config == null)
|
||||
{
|
||||
config = EmptyConfig.Instance;
|
||||
}
|
||||
config.Lock();
|
||||
_config = config;
|
||||
|
||||
if (isIndexable)
|
||||
{
|
||||
id = (short)_worldIdDispenser.UseFree();
|
||||
if (id >= Worlds.Length)
|
||||
{
|
||||
Array.Resize(ref Worlds, Worlds.Length << 1);
|
||||
}
|
||||
Worlds[id] = this;
|
||||
}
|
||||
|
||||
_poolsMediator = new PoolsMediator(this);
|
||||
_entityDispenser = new IntDispenser(0);
|
||||
_pools = new IEcsPoolImplementation[POOLS_CAPACITY];
|
||||
_poolComponentCounts = new int[POOLS_CAPACITY];
|
||||
//_sortedPoolIds = new int[POOLS_CAPACITY];
|
||||
//_sortedPoolIdsMapping = new int[POOLS_CAPACITY];
|
||||
|
||||
int poolsCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.Get_PoolsCapacity());
|
||||
_pools = new IEcsPoolImplementation[poolsCapacity];
|
||||
_poolComponentCounts = new int[poolsCapacity];
|
||||
ArrayUtility.Fill(_pools, _nullPool);
|
||||
|
||||
_entitesCapacity = ArrayUtility.NormalizeSizeToPowerOfTwo(config.Get_EntitiesCapacity());
|
||||
_gens = new short[_entitesCapacity];
|
||||
_componentCounts = new short[_entitesCapacity];
|
||||
|
||||
@ -78,9 +126,11 @@ namespace DCFApixels.DragonECS
|
||||
_delEntBufferCount = 0;
|
||||
_delEntBuffer = new int[_entitesCapacity];
|
||||
_entitiesComponentMasks = new int[_entitesCapacity][];
|
||||
|
||||
int maskLength = _pools.Length / 32 + 1;
|
||||
for (int i = 0; i < _entitesCapacity; i++)
|
||||
{
|
||||
_entitiesComponentMasks[i] = new int[_pools.Length / 32 + 1];
|
||||
_entitiesComponentMasks[i] = new int[maskLength];
|
||||
}
|
||||
|
||||
_delEntBufferMinCount = Math.Max(_delEntBuffer.Length >> DEL_ENT_BUFFER_SIZE_OFFSET, DEL_ENT_BUFFER_MIN_SIZE);
|
||||
@ -142,7 +192,7 @@ namespace DCFApixels.DragonECS
|
||||
#region Where Query
|
||||
public EcsReadonlyGroup WhereToGroupFor<TAspect>(EcsSpan span, out TAspect aspect) where TAspect : EcsAspect
|
||||
{
|
||||
if (_isEnableReleaseDelEntBuffer)
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
@ -152,7 +202,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public EcsReadonlyGroup WhereToGroupFor<TAspect>(EcsSpan span) where TAspect : EcsAspect
|
||||
{
|
||||
if (_isEnableReleaseDelEntBuffer)
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
@ -160,7 +210,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public EcsReadonlyGroup WhereToGroup<TAspect>(out TAspect aspect) where TAspect : EcsAspect
|
||||
{
|
||||
if (_isEnableReleaseDelEntBuffer)
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
@ -170,7 +220,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public EcsReadonlyGroup WhereToGroup<TAspect>() where TAspect : EcsAspect
|
||||
{
|
||||
if (_isEnableReleaseDelEntBuffer)
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
@ -179,7 +229,7 @@ namespace DCFApixels.DragonECS
|
||||
|
||||
public EcsSpan WhereFor<TAspect>(EcsSpan span, out TAspect aspect) where TAspect : EcsAspect
|
||||
{
|
||||
if (_isEnableReleaseDelEntBuffer)
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
@ -189,7 +239,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public EcsSpan WhereFor<TAspect>(EcsSpan span) where TAspect : EcsAspect
|
||||
{
|
||||
if (_isEnableReleaseDelEntBuffer)
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
@ -197,7 +247,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public EcsSpan Where<TAspect>(out TAspect aspect) where TAspect : EcsAspect
|
||||
{
|
||||
if (_isEnableReleaseDelEntBuffer)
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
@ -207,7 +257,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
public EcsSpan Where<TAspect>() where TAspect : EcsAspect
|
||||
{
|
||||
if (_isEnableReleaseDelEntBuffer)
|
||||
if (_isEnableAutoReleaseDelEntBuffer)
|
||||
{
|
||||
ReleaseDelEntityBufferAll();
|
||||
}
|
||||
@ -216,20 +266,20 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Entity
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public int NewEntity()
|
||||
{
|
||||
//if (_isEnableReleaseDelEntBuffer && _freeSpace <= 1 && _delEntBufferCount > _delEntBufferMinCount)
|
||||
// ReleaseDelEntityBufferAll();
|
||||
|
||||
int entityID = _entityDispenser.GetFree();
|
||||
_freeSpace--;
|
||||
_entitiesCount++;
|
||||
|
||||
if (_gens.Length <= entityID)
|
||||
Upsize();
|
||||
{
|
||||
Upsize_Internal(_gens.Length << 1);
|
||||
}
|
||||
|
||||
_gens[entityID] &= GEN_BITS;
|
||||
_allEntites.Add(entityID);
|
||||
_allEntites.AddUnchecked(entityID);
|
||||
_entityListeners.InvokeOnNewEntity(entityID);
|
||||
return entityID;
|
||||
}
|
||||
@ -238,8 +288,23 @@ namespace DCFApixels.DragonECS
|
||||
int e = NewEntity();
|
||||
return GetEntityLong(e);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void TryDelEntity(int entityID)
|
||||
{
|
||||
if (IsUsed(entityID))
|
||||
{
|
||||
DelEntity(entityID);
|
||||
}
|
||||
}
|
||||
public void DelEntity(int entityID)
|
||||
{
|
||||
#if DEBUG
|
||||
if(IsUsed(entityID) == false)
|
||||
{
|
||||
Throw.UndefinedException();
|
||||
}
|
||||
#endif
|
||||
_allEntites.Remove(entityID);
|
||||
_delEntBuffer[_delEntBufferCount++] = entityID;
|
||||
_gens[entityID] |= DEATH_GEN_BIT;
|
||||
@ -339,12 +404,12 @@ namespace DCFApixels.DragonECS
|
||||
#region DelEntBuffer
|
||||
public AutoReleaseDelEntBufferLonkUnloker DisableAutoReleaseDelEntBuffer()
|
||||
{
|
||||
_isEnableReleaseDelEntBuffer = false;
|
||||
_isEnableAutoReleaseDelEntBuffer = false;
|
||||
return new AutoReleaseDelEntBufferLonkUnloker(this);
|
||||
}
|
||||
public void EnableAutoReleaseDelEntBuffer()
|
||||
{
|
||||
_isEnableReleaseDelEntBuffer = true;
|
||||
_isEnableAutoReleaseDelEntBuffer = true;
|
||||
}
|
||||
public readonly struct AutoReleaseDelEntBufferLonkUnloker : IDisposable
|
||||
{
|
||||
@ -393,25 +458,29 @@ namespace DCFApixels.DragonECS
|
||||
#endregion
|
||||
|
||||
#region Upsize
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void Upsize()
|
||||
public void Upsize(int minSize)
|
||||
{
|
||||
Array.Resize(ref _gens, _gens.Length << 1);
|
||||
Array.Resize(ref _componentCounts, _gens.Length);
|
||||
Array.Resize(ref _delEntBuffer, _gens.Length);
|
||||
Array.Resize(ref _entitiesComponentMasks, _gens.Length);
|
||||
for (int i = _entitesCapacity; i < _gens.Length; i++)
|
||||
Upsize_Internal(ArrayUtility.NormalizeSizeToPowerOfTwo(minSize));
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
private void Upsize_Internal(int newSize)
|
||||
{
|
||||
Array.Resize(ref _gens, newSize);
|
||||
Array.Resize(ref _componentCounts, newSize);
|
||||
Array.Resize(ref _delEntBuffer, newSize);
|
||||
Array.Resize(ref _entitiesComponentMasks, newSize);
|
||||
for (int i = _entitesCapacity; i < newSize; i++)
|
||||
_entitiesComponentMasks[i] = new int[_pools.Length / 32 + 1];
|
||||
|
||||
_delEntBufferMinCount = Math.Max(_delEntBuffer.Length >> DEL_ENT_BUFFER_SIZE_OFFSET, DEL_ENT_BUFFER_MIN_SIZE);
|
||||
ArrayUtility.Fill(_gens, DEATH_GEN_BIT, _entitesCapacity);
|
||||
_entitesCapacity = _gens.Length;
|
||||
_entitesCapacity = newSize;
|
||||
|
||||
for (int i = 0; i < _groups.Count; i++)
|
||||
{
|
||||
if (_groups[i].TryGetTarget(out EcsGroup group))
|
||||
{
|
||||
group.OnWorldResize(_gens.Length);
|
||||
group.OnWorldResize(newSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -421,9 +490,11 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
foreach (var item in _pools)
|
||||
item.OnWorldResize(_gens.Length);
|
||||
{
|
||||
item.OnWorldResize(newSize);
|
||||
}
|
||||
|
||||
_listeners.InvokeOnWorldResize(_gens.Length);
|
||||
_listeners.InvokeOnWorldResize(newSize);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -500,6 +571,21 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region EmptyConfig
|
||||
private class EmptyConfig : IEcsWorldConfig
|
||||
{
|
||||
public static readonly EmptyConfig Instance = new EmptyConfig();
|
||||
private EmptyConfig() { }
|
||||
public bool IsLocked => true;
|
||||
public T Get<T>(string valueName) { return default; }
|
||||
public bool Has(string valueName) { return false; }
|
||||
public void Lock() { }
|
||||
public void Remove(string valueName) { }
|
||||
public void Set<T>(string valueName, T value) { }
|
||||
public bool TryGet<T>(string valueName, out T value) { value = default; return false; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
#region Callbacks Interface
|
||||
@ -551,4 +637,4 @@ namespace DCFApixels.DragonECS
|
||||
public static entlong ToEntityLong(this int self, EcsWorld world) => world.GetEntityLong(self);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@ -23,6 +23,14 @@ namespace DCFApixels.DragonECS
|
||||
public int GetComponentID(Type type) => DeclareComponentType(EcsTypeCode.Get(type));
|
||||
public bool IsComponentTypeDeclared<T>() => _componentIds.Contains(EcsTypeCode.Get<T>());
|
||||
public bool IsComponentTypeDeclared(Type type) => _componentIds.Contains(EcsTypeCode.Get(type));
|
||||
public bool IsComponentTypeDeclared(int componentTypeID)
|
||||
{
|
||||
if (componentTypeID >= 0 && componentTypeID < _pools.Length)
|
||||
{
|
||||
return _pools[componentTypeID] != _nullPool;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public Type GetComponentType(int componentID) => _pools[componentID].ComponentType;
|
||||
#endregion
|
||||
|
||||
|
@ -22,13 +22,14 @@ namespace DCFApixels.DragonECS
|
||||
private const int DEL_ENT_BUFFER_MIN_SIZE = 64;
|
||||
|
||||
private static EcsWorld[] Worlds = new EcsWorld[4];
|
||||
private static IdDispenser _worldIdDispenser = new IdDispenser(0);
|
||||
private static IdDispenser _worldIdDispenser = new IdDispenser(4);
|
||||
|
||||
private static List<DataReleaser> _dataReleaseres = new List<DataReleaser>();
|
||||
//public static int Copacity => Worlds.Length;
|
||||
|
||||
static EcsWorld()
|
||||
{
|
||||
Worlds[0] = new EcsNullWorld();
|
||||
Worlds[0] = new NullWorld();
|
||||
}
|
||||
private static void ReleaseData(int worldID)
|
||||
{
|
||||
@ -41,7 +42,7 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T GetData<T>(int worldID) => ref WorldComponentPool<T>.GetForWorld(worldID);
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static ref T UncheckedGetData<T>(int worldID) => ref WorldComponentPool<T>.GetForWorldUnchecked(worldID);
|
||||
public static ref T GetDataUnchecked<T>(int worldID) => ref WorldComponentPool<T>.GetForWorldUnchecked(worldID);
|
||||
|
||||
private abstract class DataReleaser
|
||||
{
|
||||
@ -81,9 +82,7 @@ namespace DCFApixels.DragonECS
|
||||
if (_mapping.Length < Worlds.Length)
|
||||
{
|
||||
Array.Resize(ref _mapping, Worlds.Length);
|
||||
|
||||
}
|
||||
|
||||
ref short itemIndex = ref _mapping[worldID];
|
||||
if (itemIndex <= 0)
|
||||
{
|
||||
@ -122,9 +121,9 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
internal sealed class EcsNullWorld : EcsWorld
|
||||
{
|
||||
internal EcsNullWorld() : base(false) { }
|
||||
private sealed class NullWorld : EcsWorld
|
||||
{
|
||||
internal NullWorld() : base(EmptyConfig.Instance, false) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
128
src/EcsWorldConfig.cs
Normal file
128
src/EcsWorldConfig.cs
Normal file
@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
public interface IEcsWorldConfig
|
||||
{
|
||||
bool IsLocked { get; }
|
||||
void Lock();
|
||||
void Set<T>(string valueName, T value);
|
||||
bool Has(string valueName);
|
||||
T Get<T>(string valueName);
|
||||
bool TryGet<T>(string valueName, out T value);
|
||||
void Remove(string valueName);
|
||||
}
|
||||
public class EcsWorldConfig : IEcsWorldConfig
|
||||
{
|
||||
private Dictionary<string, object> _storage = new Dictionary<string, object>();
|
||||
private bool _isLocked = false;
|
||||
public bool IsLocked { get { return _isLocked; } }
|
||||
public void Lock()
|
||||
{
|
||||
_isLocked = true;
|
||||
}
|
||||
public T Get<T>(string valueName)
|
||||
{
|
||||
return (T)_storage[valueName];
|
||||
}
|
||||
public bool Has(string valueName)
|
||||
{
|
||||
return _storage.ContainsKey(valueName);
|
||||
}
|
||||
public void Remove(string valueName)
|
||||
{
|
||||
if (_isLocked)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
_storage.Remove(valueName);
|
||||
}
|
||||
public void Set<T>(string valueName, T value)
|
||||
{
|
||||
if (_isLocked)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
_storage[valueName] = value;
|
||||
}
|
||||
public bool TryGet<T>(string valueName, out T value)
|
||||
{
|
||||
bool result = _storage.TryGetValue(valueName, out object rawValue);
|
||||
value = rawValue == null ? default : (T)rawValue;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
public static class EcsWorldConfigExtensions
|
||||
{
|
||||
public static T GetOrDefault<T>(this IEcsWorldConfig self, string valueName, T defaultValue)
|
||||
{
|
||||
if (self.TryGet(valueName, out T value))
|
||||
{
|
||||
return value;
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private const string ENTITIES_CAPACITY = nameof(ENTITIES_CAPACITY);
|
||||
private const int ENTITIES_CAPACITY_DEFAULT = 512;
|
||||
public static TConfig Set_EntitiesCapacity<TConfig>(this TConfig self, int value)
|
||||
where TConfig : IEcsWorldConfig
|
||||
{
|
||||
self.Set(ENTITIES_CAPACITY, value);
|
||||
return self;
|
||||
}
|
||||
public static int Get_EntitiesCapacity(this IEcsWorldConfig self)
|
||||
{
|
||||
return self.GetOrDefault(ENTITIES_CAPACITY, ENTITIES_CAPACITY_DEFAULT);
|
||||
}
|
||||
|
||||
//private const string RECYCLED_ENTITIES_CAPACITY = nameof(RECYCLED_ENTITIES_CAPACITY);
|
||||
//public static void Set_RecycledEntitiesCapacity(this IEcsWorldConfig self, int value)
|
||||
//{
|
||||
// self.Set(RECYCLED_ENTITIES_CAPACITY, value);
|
||||
//}
|
||||
//public static int Get_RecycledEntitiesCapacity(this IEcsWorldConfig self)
|
||||
//{
|
||||
// return self.GetOrDefault(RECYCLED_ENTITIES_CAPACITY, self.Get_EntitiesCapacity() / 2);
|
||||
//}
|
||||
|
||||
private const string POOLS_CAPACITY = nameof(POOLS_CAPACITY);
|
||||
private const int POOLS_CAPACITY_DEFAULT = 512;
|
||||
public static TConfig Set_PoolsCapacity<TConfig>(this TConfig self, int value)
|
||||
where TConfig : IEcsWorldConfig
|
||||
{
|
||||
self.Set(POOLS_CAPACITY, value);
|
||||
return self;
|
||||
}
|
||||
public static int Get_PoolsCapacity(this IEcsWorldConfig self)
|
||||
{
|
||||
return self.GetOrDefault(POOLS_CAPACITY, POOLS_CAPACITY_DEFAULT);
|
||||
}
|
||||
|
||||
private const string COMPONENT_POOL_CAPACITY = nameof(COMPONENT_POOL_CAPACITY);
|
||||
private const int COMPONENT_POOL_CAPACITY_DEFAULT = 512;
|
||||
public static TConfig Set_PoolComponentsCapacity<TConfig>(this TConfig self, int value)
|
||||
where TConfig : IEcsWorldConfig
|
||||
{
|
||||
self.Set(COMPONENT_POOL_CAPACITY, value);
|
||||
return self;
|
||||
}
|
||||
public static int Get_PoolComponentsCapacity(this IEcsWorldConfig self)
|
||||
{
|
||||
return self.GetOrDefault(COMPONENT_POOL_CAPACITY, COMPONENT_POOL_CAPACITY_DEFAULT);
|
||||
}
|
||||
|
||||
private const string POOL_RECYCLED_COMPONENTS_CAPACITY = nameof(POOL_RECYCLED_COMPONENTS_CAPACITY);
|
||||
public static TConfig Set_PoolRecycledComponentsCapacity<TConfig>(this TConfig self, int value)
|
||||
where TConfig : IEcsWorldConfig
|
||||
{
|
||||
self.Set(POOL_RECYCLED_COMPONENTS_CAPACITY, value);
|
||||
return self;
|
||||
}
|
||||
public static int Get_PoolRecycledComponentsCapacity(this IEcsWorldConfig self)
|
||||
{
|
||||
return self.GetOrDefault(POOL_RECYCLED_COMPONENTS_CAPACITY, self.Get_PoolComponentsCapacity() / 2);
|
||||
}
|
||||
}
|
||||
}
|
11
src/EcsWorldConfig.cs.meta
Normal file
11
src/EcsWorldConfig.cs.meta
Normal file
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0bd5947405343044b9e716c787ad4945
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -71,7 +71,9 @@ namespace DCFApixels.DragonECS
|
||||
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
|
||||
_listeners.InvokeOnAdd(entityID);
|
||||
if (isMain)
|
||||
{
|
||||
component.OnAddToPool(_source.GetEntityLong(entityID));
|
||||
}
|
||||
_items[itemIndex] = component;
|
||||
_entities[itemIndex] = entityID;
|
||||
}
|
||||
@ -122,9 +124,13 @@ namespace DCFApixels.DragonECS
|
||||
ref int itemIndex = ref _mapping[entityID];
|
||||
T component = _items[itemIndex];
|
||||
if (isMain)
|
||||
{
|
||||
component.OnDelFromPool(_source.GetEntityLong(entityID));
|
||||
}
|
||||
if (_recycledItemsCount >= _recycledItems.Length)
|
||||
{
|
||||
Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
|
||||
}
|
||||
_recycledItems[_recycledItemsCount++] = itemIndex;
|
||||
_mapping[entityID] = 0;
|
||||
_entities[itemIndex] = 0;
|
||||
@ -138,7 +144,9 @@ namespace DCFApixels.DragonECS
|
||||
HybridMapping mapping = _source.GetHybridMapping(component.GetType());
|
||||
mapping.GetTargetTypePool().DelInternal(entityID, true);
|
||||
foreach (var pool in mapping.GetPools())
|
||||
{
|
||||
pool.DelInternal(entityID, false);
|
||||
}
|
||||
}
|
||||
public void TryDel(int entityID)
|
||||
{
|
||||
|
@ -1,3 +1,4 @@
|
||||
using DCFApixels.DragonECS.Internal;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
@ -20,7 +21,9 @@ namespace DCFApixels.DragonECS
|
||||
private int _recycledItemsCount;
|
||||
|
||||
private IEcsComponentReset<T> _componentResetHandler = EcsComponentResetHandler<T>.instance;
|
||||
private bool _isHasComponentResetHandler = EcsComponentResetHandler<T>.isHasHandler;
|
||||
private IEcsComponentCopy<T> _componentCopyHandler = EcsComponentCopyHandler<T>.instance;
|
||||
private bool _isHasComponentCopyHandler = EcsComponentCopyHandler<T>.isHasHandler;
|
||||
|
||||
private List<IEcsPoolEventListener> _listeners = new List<IEcsPoolEventListener>();
|
||||
|
||||
@ -54,6 +57,7 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
_mediator.RegisterComponent(entityID, _componentTypeID, _maskBit);
|
||||
_listeners.InvokeOnAddAndGet(entityID);
|
||||
ResetComponent(ref _items[itemIndex]);
|
||||
return ref _items[itemIndex];
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@ -93,6 +97,7 @@ namespace DCFApixels.DragonECS
|
||||
_listeners.InvokeOnAdd(entityID);
|
||||
}
|
||||
_listeners.InvokeOnGet(entityID);
|
||||
ResetComponent(ref _items[itemIndex]);
|
||||
return ref _items[itemIndex];
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@ -106,9 +111,11 @@ namespace DCFApixels.DragonECS
|
||||
if (!Has(entityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(entityID);
|
||||
#endif
|
||||
ref int itemIndex = ref _mapping[entityID];
|
||||
_componentResetHandler.Reset(ref _items[itemIndex]);
|
||||
ResetComponent(ref _items[itemIndex]);
|
||||
if (_recycledItemsCount >= _recycledItems.Length)
|
||||
{
|
||||
Array.Resize(ref _recycledItems, _recycledItems.Length << 1);
|
||||
}
|
||||
_recycledItems[_recycledItemsCount++] = itemIndex;
|
||||
_mapping[entityID] = 0;
|
||||
_itemsCount--;
|
||||
@ -124,14 +131,14 @@ namespace DCFApixels.DragonECS
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(fromEntityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID);
|
||||
#endif
|
||||
_componentCopyHandler.Copy(ref Get(fromEntityID), ref TryAddOrGet(toEntityID));
|
||||
CopyComponent(ref Get(fromEntityID), ref TryAddOrGet(toEntityID));
|
||||
}
|
||||
public void Copy(int fromEntityID, EcsWorld toWorld, int toEntityID)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!Has(fromEntityID)) EcsPoolThrowHalper.ThrowNotHaveComponent<T>(fromEntityID);
|
||||
#endif
|
||||
_componentCopyHandler.Copy(ref Get(fromEntityID), ref toWorld.GetPool<T>().TryAddOrGet(toEntityID));
|
||||
CopyComponent(ref Get(fromEntityID), ref toWorld.GetPool<T>().TryAddOrGet(toEntityID));
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -143,12 +150,10 @@ namespace DCFApixels.DragonECS
|
||||
_componentTypeID = componentTypeID;
|
||||
_maskBit = EcsMaskChunck.FromID(componentTypeID);
|
||||
|
||||
const int capacity = 512;
|
||||
|
||||
_mapping = new int[world.Capacity];
|
||||
_recycledItems = new int[128];
|
||||
_recycledItems = new int[world.Config.Get_PoolRecycledComponentsCapacity()];
|
||||
_recycledItemsCount = 0;
|
||||
_items = new T[capacity];
|
||||
_items = new T[ArrayUtility.NormalizeSizeToPowerOfTwo(world.Config.Get_PoolComponentsCapacity())];
|
||||
_itemsCount = 0;
|
||||
}
|
||||
void IEcsPoolImplementation.OnWorldResize(int newSize)
|
||||
@ -159,7 +164,9 @@ namespace DCFApixels.DragonECS
|
||||
void IEcsPoolImplementation.OnReleaseDelEntityBuffer(ReadOnlySpan<int> buffer)
|
||||
{
|
||||
foreach (var entityID in buffer)
|
||||
{
|
||||
TryDel(entityID);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
@ -184,6 +191,33 @@ namespace DCFApixels.DragonECS
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Reset/Copy
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void ResetComponent(ref T component)
|
||||
{
|
||||
if (_isHasComponentResetHandler)
|
||||
{
|
||||
_componentResetHandler.Reset(ref component);
|
||||
}
|
||||
else
|
||||
{
|
||||
component = default;
|
||||
}
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void CopyComponent(ref T from, ref T to)
|
||||
{
|
||||
if (_isHasComponentCopyHandler)
|
||||
{
|
||||
_componentCopyHandler.Copy(ref from, ref to);
|
||||
}
|
||||
else
|
||||
{
|
||||
to = from;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region IEnumerator - IntelliSense hack
|
||||
IEnumerator<T> IEnumerable<T>.GetEnumerator() => throw new NotImplementedException();
|
||||
IEnumerator IEnumerable.GetEnumerator() => throw new NotImplementedException();
|
||||
|
@ -5,18 +5,61 @@ using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace DCFApixels.DragonECS.Utils
|
||||
namespace DCFApixels.DragonECS.Internal
|
||||
{
|
||||
internal static class ArrayUtility
|
||||
{
|
||||
private static int GetHighBitNumber(uint bits)
|
||||
{
|
||||
if (bits == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
int bit = 0;
|
||||
if ((bits & 0xFFFF0000) != 0)
|
||||
{
|
||||
bits >>= 16;
|
||||
bit |= 16;
|
||||
}
|
||||
if ((bits & 0xFF00) != 0)
|
||||
{
|
||||
bits >>= 8;
|
||||
bit |= 8;
|
||||
}
|
||||
if ((bits & 0xF0) != 0)
|
||||
{
|
||||
bits >>= 4;
|
||||
bit |= 4;
|
||||
}
|
||||
if ((bits & 0xC) != 0)
|
||||
{
|
||||
bits >>= 2;
|
||||
bit |= 2;
|
||||
}
|
||||
if ((bits & 0x2) != 0)
|
||||
{
|
||||
bit |= 1;
|
||||
}
|
||||
return bit;
|
||||
}
|
||||
public static int NormalizeSizeToPowerOfTwo(int minSize)
|
||||
{
|
||||
return 1 << (GetHighBitNumber((uint)minSize - 1u) + 1);
|
||||
}
|
||||
public static void Fill<T>(T[] array, T value, int startIndex = 0, int length = -1)
|
||||
{
|
||||
if (length < 0)
|
||||
{
|
||||
length = array.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = startIndex + length;
|
||||
}
|
||||
for (int i = startIndex; i < length; i++)
|
||||
{
|
||||
array[i] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
internal readonly struct EnumerableInt : IEnumerable<int>
|
||||
@ -113,7 +156,9 @@ namespace DCFApixels.DragonECS.Utils
|
||||
{
|
||||
T* clone = New<T>(length);
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
clone[i] = sourcePtr[i];
|
||||
}
|
||||
return clone;
|
||||
}
|
||||
|
||||
|
@ -2,89 +2,95 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
|
||||
namespace DCFApixels.DragonECS.Internal
|
||||
{
|
||||
namespace Internal
|
||||
internal static class Throw
|
||||
{
|
||||
internal static class Throw
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void ArgumentNull()
|
||||
{
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void ArgumentNull()
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void ConstraintIsAlreadyContainedInMask(Type type)
|
||||
{
|
||||
throw new EcsFrameworkException($"The {EcsDebugUtility.GetGenericTypeName(type)} constraint is already contained in the mask.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void ConstraintIsAlreadyContainedInMask(Type type)
|
||||
{
|
||||
throw new EcsFrameworkException($"The {EcsDebugUtility.GetGenericTypeName(type)} constraint is already contained in the mask.");
|
||||
}
|
||||
|
||||
//[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
//public static void ArgumentDifferentWorldsException()
|
||||
//{
|
||||
// throw new ArgumentException("The groups belong to different worlds.");
|
||||
//}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void ArgumentOutOfRange()
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"index is less than 0 or is equal to or greater than Count.");
|
||||
}
|
||||
//[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
//public static void ArgumentDifferentWorldsException()
|
||||
//{
|
||||
// throw new ArgumentException("The groups belong to different worlds.");
|
||||
//}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void ArgumentOutOfRange()
|
||||
{
|
||||
throw new ArgumentOutOfRangeException($"index is less than 0 or is equal to or greater than Count.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Group_AlreadyContains(int entityID)
|
||||
{
|
||||
throw new EcsFrameworkException($"This group already contains entity {entityID}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Group_DoesNotContain(int entityID)
|
||||
{
|
||||
throw new EcsFrameworkException($"This group does not contain entity {entityID}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Group_ArgumentDifferentWorldsException()
|
||||
{
|
||||
throw new ArgumentException("The groups belong to different worlds.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Group_AlreadyContains(int entityID)
|
||||
{
|
||||
throw new EcsFrameworkException($"This group already contains entity {entityID}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Group_DoesNotContain(int entityID)
|
||||
{
|
||||
throw new EcsFrameworkException($"This group does not contain entity {entityID}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Group_ArgumentDifferentWorldsException()
|
||||
{
|
||||
throw new ArgumentException("The groups belong to different worlds.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Pipeline_MethodCalledAfterInitialisation(string methodName)
|
||||
{
|
||||
throw new MethodAccessException($"It is forbidden to call {methodName}, after initialization {nameof(EcsPipeline)}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Pipeline_MethodCalledBeforeInitialisation(string methodName)
|
||||
{
|
||||
throw new MethodAccessException($"It is forbidden to call {methodName}, before initialization {nameof(EcsPipeline)}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Pipeline_MethodCalledAfterDestruction(string methodName)
|
||||
{
|
||||
throw new MethodAccessException($"It is forbidden to call {methodName}, after destroying {nameof(EcsPipeline)}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Pipeline_MethodCalledAfterInitialisation(string methodName)
|
||||
{
|
||||
throw new MethodAccessException($"It is forbidden to call {methodName}, after initialization {nameof(EcsPipeline)}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Pipeline_MethodCalledBeforeInitialisation(string methodName)
|
||||
{
|
||||
throw new MethodAccessException($"It is forbidden to call {methodName}, before initialization {nameof(EcsPipeline)}.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Pipeline_MethodCalledAfterDestruction(string methodName)
|
||||
{
|
||||
throw new MethodAccessException($"It is forbidden to call {methodName}, after destroying {nameof(EcsPipeline)}.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void World_InvalidIncrementComponentsBalance()
|
||||
{
|
||||
throw new MethodAccessException("Invalid increment components balance.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void World_GroupDoesNotBelongWorld()
|
||||
{
|
||||
throw new MethodAccessException("The Group does not belong in this world.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void World_InvalidIncrementComponentsBalance()
|
||||
{
|
||||
throw new MethodAccessException("Invalid increment components balance.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void World_GroupDoesNotBelongWorld()
|
||||
{
|
||||
throw new MethodAccessException("The Group does not belong in this world.");
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Ent_ThrowIsNotAlive(entlong entity)
|
||||
{
|
||||
if (entity.IsNull)
|
||||
throw new EcsFrameworkException($"The {entity} is null.");
|
||||
else
|
||||
throw new EcsFrameworkException($"The {entity} is not alive.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void Ent_ThrowIsNotAlive(entlong entity)
|
||||
{
|
||||
if (entity.IsNull)
|
||||
throw new EcsFrameworkException($"The {entity} is null.");
|
||||
else
|
||||
throw new EcsFrameworkException($"The {entity} is not alive.");
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.NoInlining)]
|
||||
internal static void UndefinedException()
|
||||
{
|
||||
throw new Exception();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace DCFApixels.DragonECS
|
||||
{
|
||||
[Serializable]
|
||||
public class EcsFrameworkException : Exception
|
||||
{
|
||||
|
@ -14,12 +14,7 @@ namespace DCFApixels.DragonECS.Utils
|
||||
#endregion
|
||||
|
||||
#region Constructor
|
||||
public IntDispenser()
|
||||
{
|
||||
_freeInts = new ConcurrentQueue<int>();
|
||||
_increment = 0;
|
||||
}
|
||||
public IntDispenser(int startIncrement)
|
||||
public IntDispenser(int startIncrement = 0)
|
||||
{
|
||||
_freeInts = new ConcurrentQueue<int>();
|
||||
_increment = startIncrement;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma warning disable IDE1006
|
||||
#pragma warning disable CS8981
|
||||
using DCFApixels.DragonECS.Internal;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -154,9 +155,27 @@ namespace DCFApixels.DragonECS
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator entlong(long a) => new entlong(a);
|
||||
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static explicit operator int(entlong a) => a.ID;
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Deconstruct(out int id, out int gen, out int world)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!IsAlive) Throw.Ent_ThrowIsNotAlive(this);
|
||||
#endif
|
||||
id = this.id;
|
||||
gen = this.gen;
|
||||
world = this.world;
|
||||
}
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void Deconstruct(out int id, out int world)
|
||||
{
|
||||
#if (DEBUG && !DISABLE_DEBUG) || ENABLE_DRAGONECS_ASSERT_CHEKS
|
||||
if (!IsAlive) Throw.Ent_ThrowIsNotAlive(this);
|
||||
#endif
|
||||
id = this.id;
|
||||
world = this.world;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Other
|
||||
|
Loading…
Reference in New Issue
Block a user