mirror of
https://github.com/DCFApixels/DragonECS.git
synced 2025-11-15 02:25:54 +08:00
Update
This commit is contained in:
parent
9a8e4a6995
commit
e2ebe33b57
8
src/Attributes.meta
Normal file
8
src/Attributes.meta
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 269d1f5d46517e14a8563d7f239fa559
|
||||||
|
folderAsset: yes
|
||||||
|
DefaultImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
78
src/Attributes/DebugColorAttribute.cs
Normal file
78
src/Attributes/DebugColorAttribute.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
[AttributeUsage(AttributeTargets.Struct | AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
||||||
|
public sealed class DebugColorAttribute : Attribute
|
||||||
|
{
|
||||||
|
private ColorRecord color;
|
||||||
|
public byte r => color.r;
|
||||||
|
public byte g => color.g;
|
||||||
|
public byte b => color.b;
|
||||||
|
|
||||||
|
public DebugColorAttribute(byte r, byte g, byte b)
|
||||||
|
{
|
||||||
|
color = new ColorRecord(r, g, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DebugColorAttribute(DebugColor color)
|
||||||
|
{
|
||||||
|
this.color = new ColorRecord((int)color);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Explicit, Pack = 1, Size = 4)]
|
||||||
|
private readonly struct ColorRecord
|
||||||
|
{
|
||||||
|
[FieldOffset(0)]
|
||||||
|
public readonly int full;
|
||||||
|
[FieldOffset(3)]
|
||||||
|
public readonly byte r;
|
||||||
|
[FieldOffset(2)]
|
||||||
|
public readonly byte g;
|
||||||
|
[FieldOffset(1)]
|
||||||
|
public readonly byte b;
|
||||||
|
|
||||||
|
public ColorRecord(byte r, byte g, byte b) : this()
|
||||||
|
{
|
||||||
|
this.r = r;
|
||||||
|
this.g = g;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
public ColorRecord(int full) : this()
|
||||||
|
{
|
||||||
|
this.full = full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum DebugColor
|
||||||
|
{
|
||||||
|
/// <summary> Red. RGB is (255, 0, 0)</summary>
|
||||||
|
Red = 255 << 8 * 3 + 000 << 8 * 2 + 000 << 8,
|
||||||
|
/// <summary> Green. RGB is (0, 255, 0)</summary>
|
||||||
|
Green = 000 << 8 * 3 + 255 << 8 * 2 + 000 << 8,
|
||||||
|
/// <summary> Blue. RGB is (0, 0, 255)</summary>
|
||||||
|
Blue = 000 << 8 * 3 + 000 << 8 * 2 + 255 << 8,
|
||||||
|
|
||||||
|
/// <summary> Yellow. RGB is (255, 255, 0)</summary>
|
||||||
|
Yellow = 255 << 8 * 3 + 255 << 8 * 2 + 000 << 8,
|
||||||
|
/// <summary> Cyan. RGB is (0, 255, 255)</summary>
|
||||||
|
Cyan = 000 << 8 * 3 + 255 << 8 * 2 + 255 << 8,
|
||||||
|
/// <summary> Magenta. RGB is (255, 0, 255)</summary>
|
||||||
|
Magenta = 255 << 8 * 3 + 000 << 8 * 2 + 000 << 8,
|
||||||
|
|
||||||
|
/// <summary> Yellow. RGB is (255, 127, 0)</summary>
|
||||||
|
Orange = (255 << 24) + (127 << 16) + (000 << 8),
|
||||||
|
|
||||||
|
/// <summary> Grey/Gray. RGB is (127, 127, 127)</summary>
|
||||||
|
Gray = 127 << 8 * 3 + 127 << 8 * 2 + 127 << 8,
|
||||||
|
/// <summary> Grey/Gray. RGB is (127, 127, 127)</summary>
|
||||||
|
Grey = Gray,
|
||||||
|
/// <summary> White. RGB is (255, 255, 255)</summary>
|
||||||
|
White = -1,
|
||||||
|
/// <summary> Black. RGB is (0, 0, 0)</summary>
|
||||||
|
Black = 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: 2ae31658c78bbf04cb755ac72be367dd
|
guid: 4b96ad0ff9cf7124d8539afccec8f1ae
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
@ -2,53 +2,49 @@
|
|||||||
{
|
{
|
||||||
public interface IEcsPreInitSystem : IEcsSystem
|
public interface IEcsPreInitSystem : IEcsSystem
|
||||||
{
|
{
|
||||||
public void PreInit(EcsSession session);
|
public void PreInit(EcsSystems systems);
|
||||||
}
|
}
|
||||||
public interface IEcsInitSystem : IEcsSystem
|
public interface IEcsInitSystem : IEcsSystem
|
||||||
{
|
{
|
||||||
public void Init(EcsSession session);
|
public void Init(EcsSystems systems);
|
||||||
}
|
}
|
||||||
public interface IEcsRunSystem : IEcsSystem
|
public interface IEcsRunSystem : IEcsSystem
|
||||||
{
|
{
|
||||||
public void Run(EcsSession session);
|
public void Run(EcsSystems systems);
|
||||||
}
|
}
|
||||||
public interface IEcsDestroySystem : IEcsSystem
|
public interface IEcsDestroySystem : IEcsSystem
|
||||||
{
|
{
|
||||||
public void Destroy(EcsSession session);
|
public void Destroy(EcsSystems systems);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface IEcsBaseSystem :
|
public interface IEcsBaseSystem : IEcsInitSystem, IEcsRunSystem, IEcsDestroySystem { }
|
||||||
IEcsInitSystem,
|
|
||||||
IEcsRunSystem,
|
|
||||||
IEcsDestroySystem
|
|
||||||
{ }
|
|
||||||
|
|
||||||
public sealed class EcsPreInitRunner : EcsRunner<IEcsPreInitSystem>, IEcsPreInitSystem
|
public sealed class EcsPreInitRunner : EcsRunner<IEcsPreInitSystem>, IEcsPreInitSystem
|
||||||
{
|
{
|
||||||
void IEcsPreInitSystem.PreInit(EcsSession session)
|
void IEcsPreInitSystem.PreInit(EcsSystems systems)
|
||||||
{
|
{
|
||||||
foreach (var item in targets) item.PreInit(session);
|
foreach (var item in targets) item.PreInit(systems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public sealed class EcsInitRunner : EcsRunner<IEcsInitSystem>, IEcsInitSystem
|
public sealed class EcsInitRunner : EcsRunner<IEcsInitSystem>, IEcsInitSystem
|
||||||
{
|
{
|
||||||
void IEcsInitSystem.Init(EcsSession session)
|
void IEcsInitSystem.Init(EcsSystems systems)
|
||||||
{
|
{
|
||||||
foreach (var item in targets) item.Init(session);
|
foreach (var item in targets) item.Init(systems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public sealed class EcsRunRunner : EcsRunner<IEcsRunSystem>, IEcsRunSystem
|
public sealed class EcsRunRunner : EcsRunner<IEcsRunSystem>, IEcsRunSystem
|
||||||
{
|
{
|
||||||
void IEcsRunSystem.Run(EcsSession session)
|
void IEcsRunSystem.Run(EcsSystems systems)
|
||||||
{
|
{
|
||||||
foreach (var item in targets) item.Run(session);
|
foreach (var item in targets) item.Run(systems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public sealed class EcsDestroyRunner : EcsRunner<IEcsDestroySystem>, IEcsDestroySystem
|
public sealed class EcsDestroyRunner : EcsRunner<IEcsDestroySystem>, IEcsDestroySystem
|
||||||
{
|
{
|
||||||
void IEcsDestroySystem.Destroy(EcsSession session)
|
void IEcsDestroySystem.Destroy(EcsSystems systems)
|
||||||
{
|
{
|
||||||
foreach (var item in targets) item.Destroy(session);
|
foreach (var item in targets) item.Destroy(systems);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
{
|
{
|
||||||
public void Inject(T obj);
|
public void Inject(T obj);
|
||||||
}
|
}
|
||||||
|
[DebugColor(DebugColor.Gray)]
|
||||||
public sealed class InjectRunner<T> : EcsRunner<IEcsInject<T>>, IEcsInject<T>
|
public sealed class InjectRunner<T> : EcsRunner<IEcsInject<T>>, IEcsInject<T>
|
||||||
{
|
{
|
||||||
void IEcsInject<T>.Inject(T obj)
|
void IEcsInject<T>.Inject(T obj)
|
||||||
@ -15,6 +16,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[DebugColor(DebugColor.Gray)]
|
||||||
public class InjectSystem<T> : IEcsPreInitSystem
|
public class InjectSystem<T> : IEcsPreInitSystem
|
||||||
{
|
{
|
||||||
private T _injectedData;
|
private T _injectedData;
|
||||||
@ -24,37 +26,38 @@
|
|||||||
_injectedData = injectedData;
|
_injectedData = injectedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PreInit(EcsSession session)
|
public void PreInit(EcsSystems systems)
|
||||||
{
|
{
|
||||||
var injector = session.GetRunner<IEcsInject<T>>();
|
var injector = systems.GetRunner<IEcsInject<T>>();
|
||||||
injector.Inject(_injectedData);
|
injector.Inject(_injectedData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class InjectSystemExstensions
|
public static class InjectSystemExstensions
|
||||||
{
|
{
|
||||||
public static EcsSession Inject<T>(this EcsSession self, T data)
|
public static EcsSystems.Builder Inject<T>(this EcsSystems.Builder self, T data)
|
||||||
{
|
{
|
||||||
self.Add(new InjectSystem<T>(data));
|
self.Add(new InjectSystem<T>(data));
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
public static EcsSystems.Builder Inject<A, B>(this EcsSystems.Builder self, A a, B b)
|
||||||
public static EcsSession Inject<A, B>(this EcsSession self, A dataA, B dataB)
|
|
||||||
{
|
{
|
||||||
self.Inject(dataA).Inject(dataB);
|
self.Inject(a).Inject(b);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
public static EcsSystems.Builder Inject<A, B, C, D>(this EcsSystems.Builder self, A a, B b, C c, D d)
|
||||||
public static EcsSession Inject<A, B, C, D>(this EcsSession self, A dataA, B dataB, C dataC, D dataD)
|
|
||||||
{
|
{
|
||||||
self.Inject(dataA).Inject(dataB).Inject(dataC).Inject(dataD);
|
self.Inject(a).Inject(b).Inject(c).Inject(d);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
public static EcsSystems.Builder Inject<A, B, C, D, E>(this EcsSystems.Builder self, A a, B b, C c, D d, E e)
|
||||||
public static EcsSession Inject<A, B, C, D, E>(this EcsSession self,
|
|
||||||
A dataA, B dataB, C dataC, D dataD, E dataE)
|
|
||||||
{
|
{
|
||||||
self.Inject(dataA).Inject(dataB).Inject(dataC).Inject(dataD).Inject(dataE);
|
self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
public static EcsSystems.Builder Inject<A, B, C, D, E, F>(this EcsSystems.Builder self, A a, B b, C c, D d, E e, F f)
|
||||||
|
{
|
||||||
|
self.Inject(a).Inject(b).Inject(c).Inject(d).Inject(e).Inject(f);
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/Consts.cs
Normal file
8
src/Consts.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public class EcsConsts
|
||||||
|
{
|
||||||
|
public const string EXCEPTION_MESSAGE_PREFIX = "[DragonECS] ";
|
||||||
|
public const string DEBUG_PREFIX = "[DEBUG] ";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,5 @@
|
|||||||
fileFormatVersion: 2
|
fileFormatVersion: 2
|
||||||
guid: f04087406e09f6042a341cf8fc41fabf
|
guid: 3c30dd6d8ecfdbd4aaceccd22bfb85c4
|
||||||
MonoImporter:
|
MonoImporter:
|
||||||
externalObjects: {}
|
externalObjects: {}
|
||||||
serializedVersion: 2
|
serializedVersion: 2
|
||||||
254
src/EcsFilter.cs
254
src/EcsFilter.cs
@ -13,31 +13,193 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Incs
|
#region Incs
|
||||||
public interface IInc : IMaskCondition { }
|
public interface IInc : IMaskCondition { }
|
||||||
|
|
||||||
public struct Inc : IInc
|
public struct Inc : IInc
|
||||||
{
|
{
|
||||||
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype => Array.Empty<int>();
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype => Array.Empty<int>();
|
||||||
}
|
}
|
||||||
public struct Inc<T0> : IInc
|
public struct Inc<T0> : IInc
|
||||||
{
|
{
|
||||||
public int[] GetComponentsIDs<TWorldArchetype>()
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
where TWorldArchetype : IWorldArchetype
|
|
||||||
{
|
{
|
||||||
return new int[]
|
return new int[]
|
||||||
{
|
{
|
||||||
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public struct Inc<T0, T1> : IInc
|
public struct Inc<T0, T1> : IInc
|
||||||
{
|
{
|
||||||
public int[] GetComponentsIDs<TWorldArchetype>()
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
where TWorldArchetype : IWorldArchetype
|
|
||||||
{
|
{
|
||||||
return new int[]
|
return new int[]
|
||||||
{
|
{
|
||||||
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3, T4> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3, T4, T5> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T5>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3, T4, T5, T6> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T5>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T6>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3, T4, T5, T6, T7> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T5>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T6>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T7>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3, T4, T5, T6, T7, T8> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T5>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T6>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T7>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T8>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T5>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T6>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T7>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T8>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T9>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T5>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T6>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T7>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T8>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T9>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T10>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Inc<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> : IInc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T5>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T6>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T7>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T8>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T9>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T10>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T11>.uniqueID,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,15 +207,13 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Excs
|
#region Excs
|
||||||
public interface IExc : IMaskCondition { }
|
public interface IExc : IMaskCondition { }
|
||||||
|
|
||||||
public struct Exc : IExc
|
public struct Exc : IExc
|
||||||
{
|
{
|
||||||
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype => Array.Empty<int>();
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype => Array.Empty<int>();
|
||||||
}
|
}
|
||||||
public struct Exc<T0> : IExc
|
public struct Exc<T0> : IExc
|
||||||
{
|
{
|
||||||
public int[] GetComponentsIDs<TWorldArchetype>()
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
where TWorldArchetype : IWorldArchetype
|
|
||||||
{
|
{
|
||||||
return new int[]
|
return new int[]
|
||||||
{
|
{
|
||||||
@ -63,13 +223,66 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
public struct Exc<T0, T1> : IExc
|
public struct Exc<T0, T1> : IExc
|
||||||
{
|
{
|
||||||
public int[] GetComponentsIDs<TWorldArchetype>()
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
where TWorldArchetype : IWorldArchetype
|
|
||||||
{
|
{
|
||||||
return new int[]
|
return new int[]
|
||||||
{
|
{
|
||||||
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Exc<T0, T1, T2> : IExc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Exc<T0, T1, T2, T3> : IExc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Exc<T0, T1, T2, T3, T4> : IExc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public struct Exc<T0, T1, T2, T3, T4, T5> : IExc
|
||||||
|
{
|
||||||
|
public int[] GetComponentsIDs<TWorldArchetype>() where TWorldArchetype : IWorldArchetype
|
||||||
|
{
|
||||||
|
return new int[]
|
||||||
|
{
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T0>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T1>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T2>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T3>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T4>.uniqueID,
|
||||||
|
EcsWorld<TWorldArchetype>.ComponentType<T5>.uniqueID,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,19 +451,4 @@ 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
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -31,7 +31,7 @@ namespace DCFApixels.DragonECS
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Constrcutors
|
#region Constrcutors
|
||||||
public EcsGroup(IEcsWorld world, int entitiesCapacity, int delayedOpsCapacity = 128)
|
public EcsGroup(IEcsWorld world, int entitiesCapacity, int delayedOpsCapacity = 32)
|
||||||
{
|
{
|
||||||
_source = world;
|
_source = world;
|
||||||
_entities = new SparseSet(entitiesCapacity, entitiesCapacity);
|
_entities = new SparseSet(entitiesCapacity, entitiesCapacity);
|
||||||
@ -67,6 +67,11 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region Contains
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool Contains(int entityID) => _entities.Contains(entityID);
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region AddGroup/RemoveGroup
|
#region AddGroup/RemoveGroup
|
||||||
public void AddGroup(IEcsReadonlyGroup group)
|
public void AddGroup(IEcsReadonlyGroup group)
|
||||||
{
|
{
|
||||||
@ -124,44 +129,28 @@ namespace DCFApixels.DragonECS
|
|||||||
private readonly EcsGroup _source;
|
private readonly EcsGroup _source;
|
||||||
private readonly SparseSet _entities;
|
private readonly SparseSet _entities;
|
||||||
private int _index;
|
private int _index;
|
||||||
private Entity _currentEntity;
|
|
||||||
|
|
||||||
public Enumerator(EcsGroup group)
|
public Enumerator(EcsGroup group)
|
||||||
{
|
{
|
||||||
_source = group;
|
_source = group;
|
||||||
_entities = group._entities;
|
_entities = group._entities;
|
||||||
_index = -1;
|
_index = -1;
|
||||||
_currentEntity = new Entity(group.World, -1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Entity Current
|
public ent Current
|
||||||
{
|
{
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
get
|
get { return _source.World.GetEntity(_entities[_index]); }
|
||||||
{
|
|
||||||
_currentEntity.id = _entities[_index];
|
|
||||||
return _currentEntity;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool MoveNext()
|
public bool MoveNext() => ++_index < _entities.Count;
|
||||||
{
|
|
||||||
return ++_index < _entities.Count;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Dispose()
|
public void Dispose() => _source.Unlock();
|
||||||
{
|
|
||||||
_source.Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public void Reset()
|
public void Reset() => _index = -1;
|
||||||
{
|
|
||||||
_index = -1;
|
|
||||||
_currentEntity.id = -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct DelayedOp
|
private struct DelayedOp
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
using System.Collections;
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using UnityEngine;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|||||||
@ -1,5 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Linq.Expressions;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
@ -25,7 +28,12 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
|
|
||||||
public interface IEcsSystem { }
|
public interface IEcsSystem { }
|
||||||
public interface IEcsRunner { }
|
public interface IEcsRunner
|
||||||
|
{
|
||||||
|
public IList Targets { get; }
|
||||||
|
public object Filter { get; }
|
||||||
|
public bool IsHasFilter { get; }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class IEcsProcessorExtensions
|
public static class IEcsProcessorExtensions
|
||||||
@ -36,10 +44,9 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal static class EcsRunnerActivator
|
internal static class EcsRunnerActivator
|
||||||
{
|
{
|
||||||
private static Dictionary<Guid, Type> _runnerTypes; //interface guid/ Runner type pairs;
|
private static Dictionary<Guid, Type> _runnerHandlerTypes; //interface guid/Runner handler type pairs;
|
||||||
|
|
||||||
static EcsRunnerActivator()
|
static EcsRunnerActivator()
|
||||||
{
|
{
|
||||||
@ -47,28 +54,28 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
Type runnerBaseType = typeof(EcsRunner<>);
|
Type runnerBaseType = typeof(EcsRunner<>);
|
||||||
|
|
||||||
List<Type> newRunnerTypes = new List<Type>();
|
List<Type> runnerHandlerTypes = new List<Type>();
|
||||||
newRunnerTypes = Assembly.GetAssembly(runnerBaseType)
|
runnerHandlerTypes = Assembly.GetAssembly(runnerBaseType)
|
||||||
.GetTypes()
|
.GetTypes()
|
||||||
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && runnerBaseType == type.BaseType.GetGenericTypeDefinition())
|
.Where(type => type.BaseType != null && type.BaseType.IsGenericType && runnerBaseType == type.BaseType.GetGenericTypeDefinition())
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
for (int i = 0; i < newRunnerTypes.Count; i++)
|
for (int i = 0; i < runnerHandlerTypes.Count; i++)
|
||||||
{
|
{
|
||||||
var e = CheckRunnerValide(newRunnerTypes[i]);
|
var e = CheckRunnerValide(runnerHandlerTypes[i]);
|
||||||
if (e != null)
|
if (e != null)
|
||||||
{
|
{
|
||||||
newRunnerTypes.RemoveAt(i--);
|
runnerHandlerTypes.RemoveAt(i--);
|
||||||
exceptions.Add(e);
|
exceptions.Add(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
_runnerTypes = new Dictionary<Guid, Type>();
|
_runnerHandlerTypes = new Dictionary<Guid, Type>();
|
||||||
foreach (var item in newRunnerTypes)
|
foreach (var item in runnerHandlerTypes)
|
||||||
{
|
{
|
||||||
Type intrf = item.GetInterfaces().Where(o => o != typeof(IEcsRunner) && o != typeof(IEcsSystem)).First(); //TODO оптимизировать это место
|
Type interfaceType = item.GetInterfaces().Where(o => o != typeof(IEcsRunner) && o != typeof(IEcsSystem)).First(); //TODO оптимизировать это место
|
||||||
_runnerTypes.Add(intrf.GUID, item);
|
_runnerHandlerTypes.Add(interfaceType.GUID, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exceptions.Count > 0)
|
if (exceptions.Count > 0)
|
||||||
@ -102,7 +109,7 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
Guid interfaceGuid = nonGenericInterfaceType.GUID;
|
Guid interfaceGuid = nonGenericInterfaceType.GUID;
|
||||||
|
|
||||||
if (!_runnerTypes.TryGetValue(interfaceGuid, out Type runnerType))
|
if (!_runnerHandlerTypes.TryGetValue(interfaceGuid, out Type runnerType))
|
||||||
{
|
{
|
||||||
throw new Exception();
|
throw new Exception();
|
||||||
}
|
}
|
||||||
@ -111,16 +118,17 @@ namespace DCFApixels.DragonECS
|
|||||||
Type[] genericTypes = interfaceType.GetGenericArguments();
|
Type[] genericTypes = interfaceType.GetGenericArguments();
|
||||||
runnerType = runnerType.MakeGenericType(genericTypes);
|
runnerType = runnerType.MakeGenericType(genericTypes);
|
||||||
}
|
}
|
||||||
EcsRunner<TInterface>.Init(runnerType);
|
EcsRunner<TInterface>.Register(runnerType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract class EcsRunner<TInterface> : IEcsSystem, IEcsRunner
|
public abstract class EcsRunner<TInterface> : IEcsSystem, IEcsRunner
|
||||||
where TInterface : IEcsSystem
|
where TInterface : IEcsSystem
|
||||||
{
|
{
|
||||||
internal static void Init(Type subclass)
|
#region Register
|
||||||
|
private static Type _subclass;
|
||||||
|
internal static void Register(Type subclass)
|
||||||
{
|
{
|
||||||
|
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
if (_subclass != null)
|
if (_subclass != null)
|
||||||
{
|
{
|
||||||
@ -141,8 +149,14 @@ namespace DCFApixels.DragonECS
|
|||||||
#endif
|
#endif
|
||||||
_subclass = subclass;
|
_subclass = subclass;
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
public static TInterface Instantiate(IEnumerable<IEcsSystem> targets, object filter)
|
#region FilterSystems
|
||||||
|
private static TInterface[] FilterSystems(IEnumerable<IEcsSystem> targets)
|
||||||
|
{
|
||||||
|
return targets.Where(o => o is TInterface).Select(o => (TInterface)o).ToArray();
|
||||||
|
}
|
||||||
|
private static TInterface[] FilterSystems(IEnumerable<IEcsSystem> targets, object filter)
|
||||||
{
|
{
|
||||||
Type interfaceType = typeof(TInterface);
|
Type interfaceType = typeof(TInterface);
|
||||||
|
|
||||||
@ -166,32 +180,52 @@ namespace DCFApixels.DragonECS
|
|||||||
return atr == null || atr.interfaceType == interfaceType && atr.filter == null;
|
return atr == null || atr.interfaceType == interfaceType && atr.filter == null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return newTargets.Select(o => (TInterface)o).ToArray();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
return Instantiate(newTargets.Select(o => (TInterface)o).ToArray());
|
#region Instantiate
|
||||||
}
|
private static TInterface Instantiate(TInterface[] targets, bool isHasFilter, object filter)
|
||||||
public static TInterface Instantiate(IEnumerable<IEcsSystem> targets)
|
|
||||||
{
|
|
||||||
return Instantiate(targets.Where(o => o is TInterface).Select(o => (TInterface)o).ToArray());
|
|
||||||
}
|
|
||||||
internal static TInterface Instantiate(TInterface[] targets)
|
|
||||||
{
|
{
|
||||||
if (_subclass == null)
|
if (_subclass == null)
|
||||||
EcsRunnerActivator.InitFor<TInterface>();
|
EcsRunnerActivator.InitFor<TInterface>();
|
||||||
|
|
||||||
var instance = (EcsRunner<TInterface>)Activator.CreateInstance(_subclass);
|
var instance = (EcsRunner<TInterface>)Activator.CreateInstance(_subclass);
|
||||||
return (TInterface)(IEcsSystem)instance.Set(targets);
|
return (TInterface)(IEcsSystem)instance.Set(targets, isHasFilter, filter);
|
||||||
}
|
}
|
||||||
|
public static TInterface Instantiate(IEnumerable<IEcsSystem> targets)
|
||||||
private static Type _subclass;
|
{
|
||||||
|
return Instantiate(FilterSystems(targets), false, null);
|
||||||
protected static void SetSublcass(Type type) => _subclass = type;
|
}
|
||||||
|
public static TInterface Instantiate(IEnumerable<IEcsSystem> targets, object filter)
|
||||||
|
{
|
||||||
|
return Instantiate(FilterSystems(targets, filter), true, filter);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
protected TInterface[] targets;
|
protected TInterface[] targets;
|
||||||
|
private ReadOnlyCollection<TInterface> _targetsSealed;
|
||||||
|
private object _filter;
|
||||||
|
private bool _isHasFilter;
|
||||||
|
|
||||||
private EcsRunner<TInterface> Set(TInterface[] targets)
|
public IList Targets => _targetsSealed;
|
||||||
|
public object Filter => _filter;
|
||||||
|
public bool IsHasFilter => _isHasFilter;
|
||||||
|
private EcsRunner<TInterface> Set(TInterface[] targets, bool isHasFilter, object filter)
|
||||||
{
|
{
|
||||||
this.targets = targets;
|
this.targets = targets;
|
||||||
|
_targetsSealed = new ReadOnlyCollection<TInterface>(targets);
|
||||||
|
_filter = filter;
|
||||||
|
_isHasFilter = isHasFilter;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal void Rebuild(IEnumerable<IEcsSystem> targets)
|
||||||
|
{
|
||||||
|
if(_isHasFilter)
|
||||||
|
Set(FilterSystems(targets), _isHasFilter, _filter);
|
||||||
|
else
|
||||||
|
Set(FilterSystems(targets, _filter), _isHasFilter, _filter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,160 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
public class EcsWorldMap
|
|
||||||
{
|
|
||||||
private Dictionary<(Type, string), IEcsWorld> _worlds = new Dictionary<(Type, string), IEcsWorld>(8);
|
|
||||||
private bool _built = false;
|
|
||||||
|
|
||||||
public void Add<TArchetype>(EcsWorld<TArchetype> world, string name = "")
|
|
||||||
where TArchetype : IWorldArchetype
|
|
||||||
{
|
|
||||||
if(_built) { throw new Exception($"Cant change built {nameof(EcsWorldMap)}"); }
|
|
||||||
_worlds.Add((typeof(TArchetype), name), world);
|
|
||||||
}
|
|
||||||
|
|
||||||
public EcsWorld<TArchetype> Get<TArchetype>(string name ="")
|
|
||||||
where TArchetype : IWorldArchetype
|
|
||||||
{
|
|
||||||
return (EcsWorld<TArchetype>)_worlds[(typeof(TArchetype), name)];
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEcsWorld Get(Type type, string name = "")
|
|
||||||
{
|
|
||||||
return _worlds[(type, name)];
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Build()
|
|
||||||
{
|
|
||||||
_built = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class EcsSession
|
|
||||||
{
|
|
||||||
private int _id;
|
|
||||||
|
|
||||||
|
|
||||||
private readonly List<IEcsSystem> _allSystems;
|
|
||||||
private ReadOnlyCollection<IEcsSystem> _allSystemsSealed;
|
|
||||||
|
|
||||||
private bool _isInit = false;
|
|
||||||
private bool _isDestoryed = false;
|
|
||||||
|
|
||||||
|
|
||||||
private readonly Dictionary<Type, IEcsRunner> _runners;
|
|
||||||
private IEcsRunSystem _runRunnerCache;
|
|
||||||
|
|
||||||
private readonly EcsWorldMap _worldMap;
|
|
||||||
|
|
||||||
#region Properties
|
|
||||||
public ReadOnlyCollection<IEcsSystem> AllProcessors => _allSystemsSealed;
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
public EcsSession()
|
|
||||||
{
|
|
||||||
_allSystems = new List<IEcsSystem>(128);
|
|
||||||
_runners = new Dictionary<Type, IEcsRunner>();
|
|
||||||
_worldMap = new EcsWorldMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Runners
|
|
||||||
public T GetRunner<T>() where T : IEcsSystem
|
|
||||||
{
|
|
||||||
Type type = typeof(T);
|
|
||||||
if (_runners.TryGetValue(type, out IEcsRunner result))
|
|
||||||
{
|
|
||||||
return (T)result;
|
|
||||||
}
|
|
||||||
result = (IEcsRunner)EcsRunner<T>.Instantiate(_allSystems);
|
|
||||||
_runners.Add(type, result);
|
|
||||||
return (T)result;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Configuration
|
|
||||||
public EcsSession Add(IEcsSystem system)
|
|
||||||
{
|
|
||||||
CheckInitForMethod(nameof(AddWorld));
|
|
||||||
_allSystems.Add(system);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public EcsSession AddWorld<TArchetype>(EcsWorld<TArchetype> world, string name = "")
|
|
||||||
where TArchetype : IWorldArchetype
|
|
||||||
{
|
|
||||||
CheckInitForMethod(nameof(AddWorld));
|
|
||||||
_worldMap.Add(world, name);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region LifeCycle
|
|
||||||
public EcsSession Init()
|
|
||||||
{
|
|
||||||
CheckInitForMethod(nameof(Init));
|
|
||||||
_worldMap.Build();
|
|
||||||
_allSystemsSealed = _allSystems.AsReadOnly();
|
|
||||||
_isInit = true;
|
|
||||||
|
|
||||||
GetRunner<IEcsInject<EcsWorldMap>>().Inject(_worldMap);
|
|
||||||
|
|
||||||
GetRunner<IEcsPreInitSystem>().PreInit(this);
|
|
||||||
GetRunner<IEcsInitSystem>().Init(this);
|
|
||||||
|
|
||||||
_runRunnerCache = GetRunner<IEcsRunSystem>();
|
|
||||||
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public void Run()
|
|
||||||
{
|
|
||||||
CheckDestroyForMethod(nameof(Run));
|
|
||||||
|
|
||||||
_runRunnerCache.Run(this);
|
|
||||||
}
|
|
||||||
public void Destroy()
|
|
||||||
{
|
|
||||||
CheckDestroyForMethod(nameof(Destroy));
|
|
||||||
_isDestoryed = true;
|
|
||||||
|
|
||||||
GetRunner<IEcsDestroySystem>().Destroy(this);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region StateChecks
|
|
||||||
private void CheckInitForMethod(string methodName)
|
|
||||||
{
|
|
||||||
if (_isInit)
|
|
||||||
throw new MethodAccessException($"Запрещено вызывать метод {methodName}, после инициализации {nameof(EcsSession)}");
|
|
||||||
}
|
|
||||||
private void CheckDestroyForMethod(string methodName)
|
|
||||||
{
|
|
||||||
if (_isDestoryed)
|
|
||||||
throw new MethodAccessException($"Запрещено вызывать метод {methodName}, после уничтожения {nameof(EcsSession)}");
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region EntityConvert
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public Entity ToEntity(in ent target)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
// return new Entity(null, target.id);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public ent ToEnt(in Entity target)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
// return new ent(target.id, target.world._gens[target.id], -1000);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Utils
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
196
src/EcsSystems.cs
Normal file
196
src/EcsSystems.cs
Normal file
@ -0,0 +1,196 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace DCFApixels.DragonECS
|
||||||
|
{
|
||||||
|
public sealed class EcsSystems
|
||||||
|
{
|
||||||
|
private IEcsSystem[] _allSystems;
|
||||||
|
private Dictionary<Type, IEcsRunner> _runners;
|
||||||
|
private IEcsRunSystem _runRunnerCache;
|
||||||
|
|
||||||
|
private ReadOnlyCollection<IEcsSystem> _allSystemsSealed;
|
||||||
|
private ReadOnlyDictionary<Type, IEcsRunner> _allRunnersSealed;
|
||||||
|
|
||||||
|
private bool _isDestoryed;
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
public ReadOnlyCollection<IEcsSystem> AllSystems => _allSystemsSealed;
|
||||||
|
public ReadOnlyDictionary<Type, IEcsRunner> AllRunners => _allRunnersSealed;
|
||||||
|
public bool IsDestoryed => _isDestoryed;
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
private EcsSystems(IEcsSystem[] systems)
|
||||||
|
{
|
||||||
|
_allSystems = systems;
|
||||||
|
_runners = new Dictionary<Type, IEcsRunner>();
|
||||||
|
|
||||||
|
_allSystemsSealed = new ReadOnlyCollection<IEcsSystem>(_allSystems);
|
||||||
|
_allRunnersSealed = new ReadOnlyDictionary<Type, IEcsRunner>(_runners);
|
||||||
|
|
||||||
|
_isDestoryed = false;
|
||||||
|
|
||||||
|
GetRunner<IEcsPreInitSystem>().PreInit(this);
|
||||||
|
GetRunner<IEcsInitSystem>().Init(this);
|
||||||
|
|
||||||
|
_runRunnerCache = GetRunner<IEcsRunSystem>();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Runners
|
||||||
|
public T GetRunner<T>() where T : IEcsSystem
|
||||||
|
{
|
||||||
|
Type type = typeof(T);
|
||||||
|
if (_runners.TryGetValue(type, out IEcsRunner result))
|
||||||
|
return (T)result;
|
||||||
|
result = (IEcsRunner)EcsRunner<T>.Instantiate(_allSystems);
|
||||||
|
_runners.Add(type, result);
|
||||||
|
return (T)result;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region LifeCycle
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public void Run()
|
||||||
|
{
|
||||||
|
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
|
CheckAfterDestroyForMethod(nameof(Run));
|
||||||
|
#endif
|
||||||
|
_runRunnerCache.Run(this);
|
||||||
|
}
|
||||||
|
public void Destroy()
|
||||||
|
{
|
||||||
|
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
|
CheckAfterDestroyForMethod(nameof(Destroy));
|
||||||
|
#endif
|
||||||
|
_isDestoryed = true;
|
||||||
|
GetRunner<IEcsDestroySystem>().Destroy(this);
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region StateChecks
|
||||||
|
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
|
private void CheckAfterDestroyForMethod(string methodName)
|
||||||
|
{
|
||||||
|
if (_isDestoryed)
|
||||||
|
throw new MethodAccessException($"It is forbidden to call method {methodName}, after destroying {nameof(EcsSystems)}");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Builder
|
||||||
|
public static Builder New()
|
||||||
|
{
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
public class Builder
|
||||||
|
{
|
||||||
|
private const int KEYS_CAPACITY = 4;
|
||||||
|
private readonly HashSet<object> _declaredBlockKeys;
|
||||||
|
private readonly List<object> _blockExecutionOrder;
|
||||||
|
private readonly Dictionary<object, List<IEcsSystem>> _systems;
|
||||||
|
private readonly object _basicBlocKey;
|
||||||
|
private bool _isBasicBlockDeclared;
|
||||||
|
private bool _isOnlyBasicBlock;
|
||||||
|
public Builder()
|
||||||
|
{
|
||||||
|
_basicBlocKey = new object();
|
||||||
|
_declaredBlockKeys = new HashSet<object>(KEYS_CAPACITY);
|
||||||
|
_blockExecutionOrder = new List<object>(KEYS_CAPACITY);
|
||||||
|
_systems = new Dictionary<object, List<IEcsSystem>>(KEYS_CAPACITY);
|
||||||
|
_isBasicBlockDeclared = false;
|
||||||
|
_isOnlyBasicBlock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder Add(IEcsSystem system, object blockKey = null)
|
||||||
|
{
|
||||||
|
if (blockKey == null) blockKey = _basicBlocKey;
|
||||||
|
List<IEcsSystem> list;
|
||||||
|
if (!_systems.TryGetValue(blockKey, out list))
|
||||||
|
{
|
||||||
|
list = new List<IEcsSystem>();
|
||||||
|
_systems.Add(blockKey, list);
|
||||||
|
}
|
||||||
|
list.Add(system);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder Add(IEcsModule module)
|
||||||
|
{
|
||||||
|
module.ImportSystems(this);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder BasicSystemsBlock()
|
||||||
|
{
|
||||||
|
_isBasicBlockDeclared = true;
|
||||||
|
_blockExecutionOrder.Add(_basicBlocKey);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
public Builder SystemsBlock(object blockKey)
|
||||||
|
{
|
||||||
|
if (blockKey == null)
|
||||||
|
return BasicSystemsBlock();
|
||||||
|
|
||||||
|
_isOnlyBasicBlock = false;
|
||||||
|
_blockExecutionOrder.Add(blockKey);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EcsSystems Build()
|
||||||
|
{
|
||||||
|
if (_isOnlyBasicBlock)
|
||||||
|
{
|
||||||
|
return new EcsSystems(_systems[_basicBlocKey].ToArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_isBasicBlockDeclared == false)
|
||||||
|
_blockExecutionOrder.Insert(0, _basicBlocKey);
|
||||||
|
|
||||||
|
List<IEcsSystem> result = new List<IEcsSystem>(32);
|
||||||
|
|
||||||
|
List<IEcsSystem> basicBlockList = _systems[_basicBlocKey];
|
||||||
|
|
||||||
|
foreach (var item in _systems)
|
||||||
|
{
|
||||||
|
if (!_blockExecutionOrder.Contains(item.Key))
|
||||||
|
{
|
||||||
|
basicBlockList.AddRange(item.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach (var item in _blockExecutionOrder)
|
||||||
|
{
|
||||||
|
result.AddRange(_systems[item]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new EcsSystems(result.ToArray());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface IEcsModule
|
||||||
|
{
|
||||||
|
public void ImportSystems(EcsSystems.Builder builder);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class EcsSystemsExt
|
||||||
|
{
|
||||||
|
public static bool IsNullOrDestroyed(this EcsSystems self)
|
||||||
|
{
|
||||||
|
return self == null || self.IsDestoryed;
|
||||||
|
}
|
||||||
|
public static EcsSystems.Builder Add(this EcsSystems.Builder self, IEnumerable<IEcsSystem> range, object blockKey = null)
|
||||||
|
{
|
||||||
|
foreach (var item in range)
|
||||||
|
{
|
||||||
|
self.Add(item, blockKey);
|
||||||
|
}
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
src/EcsSystems.cs.meta
Normal file
11
src/EcsSystems.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: bb5d6e45240ecad428d33758c4cc4c49
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
@ -21,9 +21,11 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Methods
|
#region Methods
|
||||||
public EcsPool<T> GetPool<T>() where T : struct;
|
public EcsPool<T> GetPool<T>() where T : struct;
|
||||||
public EcsFilter GetFilter<TInc>() where TInc : struct, IInc;
|
public EcsFilter Filter<TInc>() where TInc : struct, IInc;
|
||||||
public EcsFilter GetFilter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc;
|
public EcsFilter GetFilter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc;
|
||||||
public ent NewEntity();
|
public ent NewEntity();
|
||||||
|
public bool EntityIsAlive(int entityID, short gen);
|
||||||
|
public ent GetEntity(int entityID);
|
||||||
public void DelEntity(int entityID);
|
public void DelEntity(int entityID);
|
||||||
public void Destroy();
|
public void Destroy();
|
||||||
|
|
||||||
@ -64,7 +66,7 @@ namespace DCFApixels.DragonECS
|
|||||||
private EcsGroup _entities;
|
private EcsGroup _entities;
|
||||||
|
|
||||||
private short[] _gens;
|
private short[] _gens;
|
||||||
private short[] _componentCounts;
|
//private short[] _componentCounts; //TODO
|
||||||
|
|
||||||
private IEcsPool[] _pools;
|
private IEcsPool[] _pools;
|
||||||
private EcsNullPool _nullPool;
|
private EcsNullPool _nullPool;
|
||||||
@ -86,7 +88,8 @@ namespace DCFApixels.DragonECS
|
|||||||
_entityDispenser = new IntDispenser();
|
_entityDispenser = new IntDispenser();
|
||||||
_nullPool = new EcsNullPool(this);
|
_nullPool = new EcsNullPool(this);
|
||||||
_pools = new IEcsPool[512];
|
_pools = new IEcsPool[512];
|
||||||
Array.Fill(_pools, _nullPool);
|
FillArray(_pools, _nullPool);
|
||||||
|
//Array.Fill(_pools, _nullPool); //TODO Fix it
|
||||||
_gens = new short[512];
|
_gens = new short[512];
|
||||||
_filters = new EcsFilter[64];
|
_filters = new EcsFilter[64];
|
||||||
_entities = new EcsGroup(this, 512);
|
_entities = new EcsGroup(this, 512);
|
||||||
@ -104,7 +107,8 @@ namespace DCFApixels.DragonECS
|
|||||||
{
|
{
|
||||||
int oldCapacity = _pools.Length;
|
int oldCapacity = _pools.Length;
|
||||||
Array.Resize(ref _pools, ComponentType.Capacity);
|
Array.Resize(ref _pools, ComponentType.Capacity);
|
||||||
Array.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
|
FillArray(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length);
|
||||||
|
//Array.Fill(_pools, _nullPool, oldCapacity, oldCapacity - _pools.Length); //TODO Fix it
|
||||||
|
|
||||||
Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity);
|
Array.Resize(ref _filtersByIncludedComponents, ComponentType.Capacity);
|
||||||
Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity);
|
Array.Resize(ref _filtersByExcludedComponents, ComponentType.Capacity);
|
||||||
@ -121,7 +125,7 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region GetFilter
|
#region GetFilter
|
||||||
|
|
||||||
public EcsFilter GetFilter<TInc>() where TInc : struct, IInc => GetFilter<TInc, Exc>();
|
public EcsFilter Filter<TInc>() where TInc : struct, IInc => GetFilter<TInc, Exc>();
|
||||||
public EcsFilter GetFilter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc
|
public EcsFilter GetFilter<TInc, TExc>() where TInc : struct, IInc where TExc : struct, IExc
|
||||||
{
|
{
|
||||||
var mask = EcsMaskMap<TArchetype>.GetMask<TInc, Exc>();
|
var mask = EcsMaskMap<TArchetype>.GetMask<TInc, Exc>();
|
||||||
@ -277,19 +281,32 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region NewEntity/DelEntity
|
#region Entity
|
||||||
public ent NewEntity()
|
public ent NewEntity()
|
||||||
{
|
{
|
||||||
int entid = _entityDispenser.GetFree();
|
int entityID = _entityDispenser.GetFree();
|
||||||
_entities.Add(entid);
|
_entities.Add(entityID);
|
||||||
if (_gens.Length < entid) Array.Resize(ref _gens, _gens.Length << 1);
|
if (_gens.Length <= entityID)
|
||||||
return new ent(entid, _gens[entid]++, id);
|
Array.Resize(ref _gens, _gens.Length << 1);
|
||||||
|
return new ent(entityID, _gens[entityID]++, id);
|
||||||
|
}
|
||||||
|
public ent GetEntity(int entityID)
|
||||||
|
{
|
||||||
|
if (_entities.Contains(entityID) == false)
|
||||||
|
return ent.NULL;
|
||||||
|
|
||||||
|
return new ent(entityID, _gens[entityID], id);
|
||||||
}
|
}
|
||||||
public void DelEntity(int entityID)
|
public void DelEntity(int entityID)
|
||||||
{
|
{
|
||||||
_entityDispenser.Release(entityID);
|
_entityDispenser.Release(entityID);
|
||||||
_entities.Remove(entityID);
|
_entities.Remove(entityID);
|
||||||
}
|
}
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public bool EntityIsAlive(int entityID, short gen)
|
||||||
|
{
|
||||||
|
return _entities.Contains(entityID) && _gens[entityID] == gen;
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Destroy
|
#region Destroy
|
||||||
@ -329,6 +346,22 @@ namespace DCFApixels.DragonECS
|
|||||||
ComponentType.types[uniqueID] = typeof(T);
|
ComponentType.types[uniqueID] = typeof(T);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void FillArray<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;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
130
src/Entity.cs
130
src/Entity.cs
@ -5,52 +5,34 @@ using System.Runtime.InteropServices;
|
|||||||
|
|
||||||
namespace DCFApixels.DragonECS
|
namespace DCFApixels.DragonECS
|
||||||
{
|
{
|
||||||
[StructLayout(LayoutKind.Sequential, Pack = 0, Size = 8)]
|
// id - 32 bits
|
||||||
|
// gen - 16 bits
|
||||||
|
// world - 16 bits
|
||||||
|
[StructLayout(LayoutKind.Explicit, Pack = 2, Size = 8)]
|
||||||
public readonly struct ent : IEquatable<long>, IEquatable<ent>
|
public readonly struct ent : IEquatable<long>, IEquatable<ent>
|
||||||
{
|
{
|
||||||
public static readonly ent NULL = default;
|
public static readonly ent NULL = default;
|
||||||
|
|
||||||
// id - 32 bits
|
[FieldOffset(0)]
|
||||||
// gen - 16 bits
|
private readonly long _full;
|
||||||
// world - 16 bits
|
[FieldOffset(3)]
|
||||||
public readonly long _full;
|
public readonly int id;
|
||||||
|
[FieldOffset(1)]
|
||||||
#region Properties
|
public readonly short gen;
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
[FieldOffset(0)]
|
||||||
public int id
|
public readonly short world;
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => (int)(_full >> 32);
|
|
||||||
}
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
public ushort gen
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => (ushort)((_full << 32) >> 48);
|
|
||||||
|
|
||||||
}
|
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
|
||||||
public short world
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
get => (short)((_full << 48) >> 48);
|
|
||||||
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region Constructors
|
#region Constructors
|
||||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
public ent(int id, short gen, short world)
|
public ent(int id, short gen, short world): this()
|
||||||
{
|
{
|
||||||
_full = ((long)id) << 32;
|
this.id = id;
|
||||||
_full += ((long)gen) << 16;
|
this.gen = gen;
|
||||||
_full += world;
|
this.world = world;
|
||||||
}
|
}
|
||||||
|
internal ent(long full) : this()
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public ent(long value)
|
|
||||||
{
|
{
|
||||||
_full = value;
|
_full = full;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@ -64,14 +46,9 @@ namespace DCFApixels.DragonECS
|
|||||||
|
|
||||||
#region Equals
|
#region Equals
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Equals(in ent other)
|
|
||||||
{
|
|
||||||
return _full == other._full;
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
return obj is ent other && Equals(in other);
|
return obj is ent other && _full == other._full;
|
||||||
}
|
}
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public bool Equals(ent other)
|
public bool Equals(ent other)
|
||||||
@ -85,26 +62,39 @@ namespace DCFApixels.DragonECS
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
#region ToString
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public override string ToString() => $"ent(id:{id} gen:{gen} world:{world})";
|
||||||
|
#endregion
|
||||||
|
|
||||||
#region operators
|
#region operators
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool operator ==(in ent left, in ent right) => left.Equals(in right);
|
public static bool operator ==(in ent a, in ent b) => a._full == b._full;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool operator !=(in ent left, in ent right) => !left.Equals(in right);
|
public static bool operator !=(in ent a, in ent b) => a._full != b._full;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator long(in ent eent) => eent._full;
|
public static explicit operator long(in ent a) => a._full;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator int(in ent eent) => eent.id;
|
public static explicit operator int(in ent a) => a.id;
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static implicit operator ent(in long value) => new ent(value);
|
public static explicit operator ent(in long a) => new ent(a);
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public static partial class entExtensions
|
public static partial class entExtensions
|
||||||
{
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
public static bool IsAlive(this ref ent self)
|
||||||
|
{
|
||||||
|
bool result = EcsWorld.Worlds[self.world].EntityIsAlive(self.id, self.gen);
|
||||||
|
if (!result) self = ent.NULL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
public static bool IsNull(this in ent self)
|
public static bool IsNull(this in ent self)
|
||||||
{
|
{
|
||||||
@ -136,50 +126,4 @@ namespace DCFApixels.DragonECS
|
|||||||
EcsWorld.Worlds[self.world].GetPool<T>().Del(self.id);
|
EcsWorld.Worlds[self.world].GetPool<T>().Del(self.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Entity
|
|
||||||
{
|
|
||||||
public IEcsWorld world;
|
|
||||||
public int id;
|
|
||||||
|
|
||||||
public Entity(IEcsWorld world, int id)
|
|
||||||
{
|
|
||||||
this.world = world;
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static partial class EntityExtensions
|
|
||||||
{
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool IsNull(this in Entity self)
|
|
||||||
{
|
|
||||||
return self.world == null;
|
|
||||||
}
|
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static ref readonly T Read<T>(this in Entity self)
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
return ref self.world.GetPool<T>().Read(self.id);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static ref T Write<T>(this in Entity self)
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
return ref self.world.GetPool<T>().Write(self.id);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static bool Has<T>(this in Entity self)
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
return self.world.GetPool<T>().Has(self.id);
|
|
||||||
}
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
||||||
public static void Del<T>(this in Entity self)
|
|
||||||
where T : struct
|
|
||||||
{
|
|
||||||
self.world.GetPool<T>().Del(self.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,8 +7,8 @@ namespace DCFApixels.DragonECS
|
|||||||
public class EcsFrameworkException : Exception
|
public class EcsFrameworkException : Exception
|
||||||
{
|
{
|
||||||
public EcsFrameworkException() { }
|
public EcsFrameworkException() { }
|
||||||
public EcsFrameworkException(string message) : base(Exceptions.MESSAGE_SUFFIX + message) { }
|
public EcsFrameworkException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
|
||||||
public EcsFrameworkException(string message, Exception inner) : base(Exceptions.MESSAGE_SUFFIX + message, inner) { }
|
public EcsFrameworkException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
|
||||||
protected EcsFrameworkException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
protected EcsFrameworkException(SerializationInfo info, StreamingContext context) : base(info, context) { }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +0,0 @@
|
|||||||
namespace DCFApixels.DragonECS
|
|
||||||
{
|
|
||||||
internal static class Exceptions
|
|
||||||
{
|
|
||||||
public const string MESSAGE_SUFFIX = "[DragonECS] ";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -8,3 +8,9 @@ DCFAECS_NO_SANITIZE_CHECKS - отвключение дополнительных
|
|||||||
|
|
||||||
|
|
||||||
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
#if DEBUG || !DRAGONECS_NO_SANITIZE_CHECKS
|
||||||
|
|
||||||
|
|
||||||
|
// [EditorBrowsable(EditorBrowsableState.Never)]
|
||||||
|
|
||||||
|
|
||||||
|
//throw new EcsFrameworkException($"There is no suitable EcsRunner implementation for the {typeof(T).FullName} interface");
|
||||||
|
|||||||
@ -80,7 +80,7 @@ namespace DCFApixels.DragonECS
|
|||||||
if (_count >= _dense.Length)
|
if (_count >= _dense.Length)
|
||||||
Array.Resize(ref _dense, _dense.Length << 1);
|
Array.Resize(ref _dense, _dense.Length << 1);
|
||||||
|
|
||||||
if (value > _sparse.Length)
|
if (value >= _sparse.Length)
|
||||||
{
|
{
|
||||||
int neadedSpace = _sparse.Length;
|
int neadedSpace = _sparse.Length;
|
||||||
while (value >= neadedSpace)
|
while (value >= neadedSpace)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user