Merge branch 'dev'

This commit is contained in:
Mikhail 2023-05-30 04:39:31 +08:00
commit 05bebb50df
8 changed files with 69 additions and 112 deletions

View File

@ -31,7 +31,6 @@ namespace DCFApixels.DragonECS
internal IEcsPoolImplementation[] _pools; internal IEcsPoolImplementation[] _pools;
private EcsNullPool _nullPool; private EcsNullPool _nullPool;
private int _poolsCount = 0;
private EcsSubject[] _subjects; private EcsSubject[] _subjects;
private EcsQueryExecutor[] _executors; private EcsQueryExecutor[] _executors;
@ -48,15 +47,10 @@ namespace DCFApixels.DragonECS
public int Capacity => _entitesCapacity; //_denseEntities.Length; public int Capacity => _entitesCapacity; //_denseEntities.Length;
public EcsReadonlyGroup Entities => _allEntites.Readonly; public EcsReadonlyGroup Entities => _allEntites.Readonly;
public ReadOnlySpan<IEcsPoolImplementation> AllPools => _pools;// new ReadOnlySpan<IEcsPoolImplementation>(pools, 0, _poolsCount); public ReadOnlySpan<IEcsPoolImplementation> AllPools => _pools;// new ReadOnlySpan<IEcsPoolImplementation>(pools, 0, _poolsCount);
public int PoolsCount => _poolsCount;
#endregion #endregion
#region Constructors/Destroy #region Constructors/Destroy
static EcsWorld() static EcsWorld() => Worlds[0] = new EcsNullWorld();
{
EcsNullWorld nullWorld = new EcsNullWorld();
Worlds[0] = nullWorld;
}
public EcsWorld() : this(true) { } public EcsWorld() : this(true) { }
internal EcsWorld(bool isIndexable) internal EcsWorld(bool isIndexable)
{ {
@ -95,25 +89,24 @@ namespace DCFApixels.DragonECS
public void Destroy() public void Destroy()
{ {
_entityDispenser = null; _entityDispenser = null;
//_denseEntities = null;
_gens = null; _gens = null;
_pools = null; _pools = null;
_nullPool = null; _nullPool = null;
_subjects = null; _subjects = null;
_executors = null; _executors = null;
Worlds[uniqueID] = null; Worlds[uniqueID] = null;
_worldIdDispenser.Release(uniqueID); _worldIdDispenser.Release(uniqueID);
} }
#endregion #endregion
#region GetComponentID #region ComponentInfo
public int GetComponentID<T>() => WorldMetaStorage.GetComponentId<T>(_worldTypeID); public int GetComponentID<T>() => WorldMetaStorage.GetComponentId<T>(_worldTypeID);
public bool IsComponentTypeDeclared<T>() => WorldMetaStorage.IsComponentTypeDeclared<T>(_worldTypeID); public Type GetComponentType(int componentID) => WorldMetaStorage.GetComponentType(_worldTypeID, componentID);
public bool IsComponentTypeDeclared<T>() => IsComponentTypeDeclared(typeof(T));
public bool IsComponentTypeDeclared(Type type) => WorldMetaStorage.IsComponentTypeDeclared(_worldTypeID, type);
#endregion #endregion
#region GetPool #region Getters
#if UNITY_2020_3_OR_NEWER #if UNITY_2020_3_OR_NEWER
[UnityEngine.Scripting.Preserve] [UnityEngine.Scripting.Preserve]
#endif #endif
@ -131,13 +124,9 @@ namespace DCFApixels.DragonECS
var pool = new TPool(); var pool = new TPool();
_pools[uniqueID] = pool; _pools[uniqueID] = pool;
pool.OnInit(this, uniqueID); pool.OnInit(this, uniqueID);
_poolsCount++;
} }
return (TPool)_pools[uniqueID]; return (TPool)_pools[uniqueID];
} }
#endregion
#region Subjects
public TSubject GetSubject<TSubject>() where TSubject : EcsSubject public TSubject GetSubject<TSubject>() where TSubject : EcsSubject
{ {
int uniqueID = WorldMetaStorage.GetSubjectId<TSubject>(_worldTypeID); int uniqueID = WorldMetaStorage.GetSubjectId<TSubject>(_worldTypeID);
@ -147,9 +136,6 @@ namespace DCFApixels.DragonECS
_subjects[uniqueID] = EcsSubject.Builder.Build<TSubject>(this); _subjects[uniqueID] = EcsSubject.Builder.Build<TSubject>(this);
return (TSubject)_subjects[uniqueID]; return (TSubject)_subjects[uniqueID];
} }
#endregion
#region Queries
public TExecutor GetExecutor<TExecutor>() where TExecutor : EcsQueryExecutor, new() public TExecutor GetExecutor<TExecutor>() where TExecutor : EcsQueryExecutor, new()
{ {
int id = WorldMetaStorage.GetExecutorId<TExecutor>(_worldTypeID); int id = WorldMetaStorage.GetExecutorId<TExecutor>(_worldTypeID);
@ -163,6 +149,9 @@ namespace DCFApixels.DragonECS
} }
return (TExecutor)_executors[id]; return (TExecutor)_executors[id];
} }
#endregion
#region Where Query
public EcsWhereResult<TSubject> WhereFor<TSubject>(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject public EcsWhereResult<TSubject> WhereFor<TSubject>(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject
{ {
var executor = GetExecutor<EcsWhereExecutor<TSubject>>(); var executor = GetExecutor<EcsWhereExecutor<TSubject>>();
@ -185,27 +174,6 @@ namespace DCFApixels.DragonECS
} }
#endregion #endregion
#region IsMatchesMask
public bool IsMatchesMask(EcsMask mask, int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
if (mask._worldType != Archetype)
throw new EcsFrameworkException("mask.WorldArchetypeType != typeof(TTableArhetype)");
#endif
for (int i = 0, iMax = mask._inc.Length; i < iMax; i++)
{
if (!_pools[mask._inc[i]].Has(entityID))
return false;
}
for (int i = 0, iMax = mask._exc.Length; i < iMax; i++)
{
if (_pools[mask._exc[i]].Has(entityID))
return false;
}
return true;
}
#endregion
#region Entity #region Entity
public int NewEmptyEntity() public int NewEmptyEntity()
{ {
@ -247,7 +215,6 @@ namespace DCFApixels.DragonECS
int e = NewEmptyEntity(); int e = NewEmptyEntity();
return GetEntityLong(e); return GetEntityLong(e);
} }
public void DelEntity(int entityID) public void DelEntity(int entityID)
{ {
_allEntites.Remove(entityID); _allEntites.Remove(entityID);
@ -265,6 +232,29 @@ namespace DCFApixels.DragonECS
public bool IsAlive(int entityID, short gen) => _gens[entityID] == gen; public bool IsAlive(int entityID, short gen) => _gens[entityID] == gen;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool IsUsed(int entityID) => _gens[entityID] >= 0; public bool IsUsed(int entityID) => _gens[entityID] >= 0;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short GetGen(int entityID) => _gens[entityID];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short GetComponentsCount(int entityID) => _componentCounts[entityID];
public bool IsMatchesMask(EcsMask mask, int entityID)
{
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
if (mask._worldType != Archetype)
throw new EcsFrameworkException("The types of the target world of the mask and this world are different.");
#endif
for (int i = 0, iMax = mask._inc.Length; i < iMax; i++)
{
if (!_pools[mask._inc[i]].Has(entityID))
return false;
}
for (int i = 0, iMax = mask._exc.Length; i < iMax; i++)
{
if (_pools[mask._exc[i]].Has(entityID))
return false;
}
return true;
}
public void ReleaseDelEntityBuffer() public void ReleaseDelEntityBuffer()
{ {
ReadOnlySpan<int> buffser = new ReadOnlySpan<int>(_delEntBuffer, 0, _delEntBufferCount); ReadOnlySpan<int> buffser = new ReadOnlySpan<int>(_delEntBuffer, 0, _delEntBufferCount);
@ -275,10 +265,6 @@ namespace DCFApixels.DragonECS
_entityDispenser.Release(_delEntBuffer[i]); _entityDispenser.Release(_delEntBuffer[i]);
_delEntBufferCount = 0; _delEntBufferCount = 0;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short GetGen(int entityID) => _gens[entityID];
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short GetComponentsCount(int entityID) => _componentCounts[entityID];
public void DeleteEmptyEntites() public void DeleteEmptyEntites()
{ {
foreach (var e in _allEntites) foreach (var e in _allEntites)
@ -287,11 +273,12 @@ namespace DCFApixels.DragonECS
} }
} }
#region Copy/Clone
public void CopyEntity(int fromEntityID, int toEntityID) public void CopyEntity(int fromEntityID, int toEntityID)
{ {
foreach (var pool in _pools) foreach (var pool in _pools)
{ {
if(pool.Has(fromEntityID)) pool.Copy(fromEntityID, toEntityID); if (pool.Has(fromEntityID)) pool.Copy(fromEntityID, toEntityID);
} }
} }
public int CloneEntity(int fromEntityID) public int CloneEntity(int fromEntityID)
@ -305,24 +292,28 @@ namespace DCFApixels.DragonECS
CopyEntity(fromEntityID, toEntityID); CopyEntity(fromEntityID, toEntityID);
foreach (var pool in _pools) foreach (var pool in _pools)
{ {
if (!pool.Has(fromEntityID)&& pool.Has(toEntityID)) if (!pool.Has(fromEntityID) && pool.Has(toEntityID))
pool.Del(toEntityID); pool.Del(toEntityID);
} }
} }
#endregion
#region Components Increment
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void IncrementEntityComponentCount(int entityID) => _componentCounts[entityID]++; internal void IncrementEntityComponentCount(int entityID) => _componentCounts[entityID]++;
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
internal void DecrementEntityComponentCount(int entityID) internal void DecrementEntityComponentCount(int entityID)
{ {
var count = --_componentCounts[entityID]; var count = --_componentCounts[entityID];
if(count == 0 && _allEntites.Has(entityID)) DelEntity(entityID); if (count == 0 && _allEntites.Has(entityID)) DelEntity(entityID);
#if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS
if (count < 0) throw new EcsFrameworkException("нарушен баланс инкремента/декремента компонентов"); if (count < 0) throw new EcsFrameworkException("нарушен баланс инкремента/декремента компонентов");
#endif #endif
} }
#endregion #endregion
#endregion
#region Groups Pool #region Groups Pool
internal void RegisterGroup(EcsGroup group) internal void RegisterGroup(EcsGroup group)
{ {
@ -363,14 +354,12 @@ namespace DCFApixels.DragonECS
} }
} }
#endregion #endregion
}
#region NullWorld internal sealed class EcsNullWorld : EcsWorld<EcsNullWorld>
private sealed class EcsNullWorld : EcsWorld<EcsNullWorld>
{ {
public EcsNullWorld() : base(false) { } public EcsNullWorld() : base(false) { }
} }
#endregion
}
public abstract class EcsWorld<TWorldArchetype> : EcsWorld public abstract class EcsWorld<TWorldArchetype> : EcsWorld
where TWorldArchetype : EcsWorld<TWorldArchetype> where TWorldArchetype : EcsWorld<TWorldArchetype>
@ -422,7 +411,6 @@ namespace DCFApixels.DragonECS
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int GetExecutorId<T>(int worldID) => Executor<T>.Get(worldID); public static int GetExecutorId<T>(int worldID) => Executor<T>.Get(worldID);
public static bool IsComponentTypeDeclared<TComponent>(int worldID) => IsComponentTypeDeclared(worldID, typeof(TComponent));
public static bool IsComponentTypeDeclared(int worldID, Type type) => _metas[worldID].IsDeclaredType(type); public static bool IsComponentTypeDeclared(int worldID, Type type) => _metas[worldID].IsDeclaredType(type);
public static Type GetComponentType(int worldID, int componentID) => _metas[worldID].GetComponentType(componentID); public static Type GetComponentType(int worldID, int componentID) => _metas[worldID].GetComponentType(componentID);

View File

@ -1,15 +0,0 @@
using System;
namespace DCFApixels.DragonECS
{
[Serializable]
public class EcsFrameworkException : Exception
{
public EcsFrameworkException() { }
public EcsFrameworkException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
public EcsFrameworkException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
protected EcsFrameworkException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}

View File

@ -1,15 +0,0 @@
using System;
namespace DCFApixels.DragonECS
{
[Serializable]
public class EcsRelationException : EcsFrameworkException
{
public EcsRelationException() { }
public EcsRelationException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
public EcsRelationException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
protected EcsRelationException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}

View File

@ -1,15 +0,0 @@
using System;
namespace DCFApixels.DragonECS
{
[Serializable]
public class EcsRunnerImplementationException : EcsFrameworkException
{
public EcsRunnerImplementationException() { }
public EcsRunnerImplementationException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
public EcsRunnerImplementationException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
protected EcsRunnerImplementationException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context) : base(info, context) { }
}
}

View File

@ -2,10 +2,10 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using static DCFApixels.DragonECS.EcsPoolThrowHalper;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
using static EcsPoolThrowHalper;
/// <summary>Pool for IEcsComponent components</summary> /// <summary>Pool for IEcsComponent components</summary>
public sealed class EcsPool<T> : IEcsPoolImplementation<T>, IEnumerable<T> //IEnumerable<T> - IntelliSense hack public sealed class EcsPool<T> : IEcsPoolImplementation<T>, IEnumerable<T> //IEnumerable<T> - IntelliSense hack
where T : struct, IEcsComponent where T : struct, IEcsComponent

View File

@ -59,14 +59,6 @@ namespace DCFApixels.DragonECS
{ {
throw new EcsFrameworkException($"Entity({entityID}) has no component {typeof(T).Name}."); throw new EcsFrameworkException($"Entity({entityID}) has no component {typeof(T).Name}.");
} }
public static void ThrowInvalidComponentType<T>(Type invalidType)
{
throw new EcsFrameworkException($"Invalid component type, {typeof(T).Name} required.");
}
public static void ThrowWorldDifferent<T>(int entityID)
{
throw new EcsRelationException($"The world of the target entity({entityID}) in {typeof(T).Name} is not the same as the world of the other entities. ");
}
} }
public static class IEcsPoolImplementationExtensions public static class IEcsPoolImplementationExtensions
{ {

View File

@ -2,10 +2,10 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using static DCFApixels.DragonECS.EcsPoolThrowHalper;
namespace DCFApixels.DragonECS namespace DCFApixels.DragonECS
{ {
using static EcsPoolThrowHalper;
public sealed class EcsTagPool<T> : IEcsPoolImplementation<T>, IEnumerable<T> //IEnumerable<T> - IntelliSense hack public sealed class EcsTagPool<T> : IEcsPoolImplementation<T>, IEnumerable<T> //IEnumerable<T> - IntelliSense hack
where T : struct, IEcsTagComponent where T : struct, IEcsTagComponent
{ {

22
src/Utils/Exceptions.cs Normal file
View File

@ -0,0 +1,22 @@
using System;
using System.Runtime.Serialization;
namespace DCFApixels.DragonECS
{
[Serializable]
public class EcsFrameworkException : Exception
{
public EcsFrameworkException() { }
public EcsFrameworkException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
public EcsFrameworkException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
protected EcsFrameworkException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
[Serializable]
public class EcsRunnerImplementationException : EcsFrameworkException
{
public EcsRunnerImplementationException() { }
public EcsRunnerImplementationException(string message) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message) { }
public EcsRunnerImplementationException(string message, Exception inner) : base(EcsConsts.EXCEPTION_MESSAGE_PREFIX + message, inner) { }
protected EcsRunnerImplementationException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
}