Merge branch 'dev'

This commit is contained in:
Mikhail 2024-03-26 16:09:53 +08:00
commit 8920dbb5e5
7 changed files with 147 additions and 27 deletions

View File

@ -10,7 +10,46 @@ namespace DCFApixels.DragonECS
{ {
internal EcsWorld _source; internal EcsWorld _source;
internal EcsMask _mask; internal EcsMask _mask;
private bool _isInit = false; private bool _isBuilt = false;
[ThreadStatic]
private static bool _isConstructorStream;
[ThreadStatic]
private static Builder _constructorStreamBuilder;
protected static IncludeMarker Inc
{
get
{
if(_isConstructorStream == false)
{ //TODO перевести
throw new InvalidOperationException($"{nameof(Inc)} можно использовать только во время инициализации полей и в конструкторе");//TODO Перевести
}
return _constructorStreamBuilder.Inc;
}
}
protected static ExcludeMarker Exc
{
get
{
if (_isConstructorStream == false)
{ //TODO перевести
throw new InvalidOperationException($"{nameof(Exc)} можно использовать только во время инициализации полей и в конструкторе");//TODO Перевести
}
return _constructorStreamBuilder.Exc;
}
}
protected static OptionalMarker Opt
{
get
{
if (_isConstructorStream == false)
{ //TODO перевести
throw new InvalidOperationException($"{nameof(Opt)} можно использовать только во время инициализации полей и в конструкторе");//TODO Перевести
}
return _constructorStreamBuilder.Opt;
}
}
private UnsafeArray<int> _sortIncBuffer; private UnsafeArray<int> _sortIncBuffer;
private UnsafeArray<int> _sortExcBuffer; private UnsafeArray<int> _sortExcBuffer;
@ -28,7 +67,7 @@ namespace DCFApixels.DragonECS
} }
public bool IsInit public bool IsInit
{ {
get { return _isInit; } get { return _isBuilt; }
} }
#endregion #endregion
@ -45,6 +84,7 @@ namespace DCFApixels.DragonECS
{ {
private EcsWorld _world; private EcsWorld _world;
private EcsMask.Builder _maskBuilder; private EcsMask.Builder _maskBuilder;
private bool _isBuilt = false;
public IncludeMarker Inc public IncludeMarker Inc
{ {
@ -74,9 +114,18 @@ namespace DCFApixels.DragonECS
//TODO добавить оповещение что инициализация через конструктор не работает //TODO добавить оповещение что инициализация через конструктор не работает
#if !REFLECTION_DISABLED #if !REFLECTION_DISABLED
ConstructorInfo constructorInfo = aspectType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Builder) }, null); ConstructorInfo constructorInfo = aspectType.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { typeof(Builder) }, null);
if (_isConstructorStream == true)
{
throw new InvalidOperationException("Нельзя рекурсивно вызывать конструктор аспекта");//TODO Перевести
}
_constructorStreamBuilder = builder;
_isConstructorStream = true;
if (constructorInfo != null) if (constructorInfo != null)
{ {
newAspect = (EcsAspect)constructorInfo.Invoke(new object[] { builder }); newAspect = (EcsAspect)constructorInfo.Invoke(new object[] { builder });
_constructorStreamBuilder = null;
_isConstructorStream = false;
} }
else else
#endif #endif
@ -84,11 +133,13 @@ namespace DCFApixels.DragonECS
#pragma warning disable IL2091 // Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The generic parameter of the source method or type does not have matching annotations. #pragma warning disable IL2091 // Target generic argument does not satisfy 'DynamicallyAccessedMembersAttribute' in target method or type. The generic parameter of the source method or type does not have matching annotations.
newAspect = Activator.CreateInstance<TAspect>(); newAspect = Activator.CreateInstance<TAspect>();
#pragma warning restore IL2091 #pragma warning restore IL2091
_constructorStreamBuilder = null;
_isConstructorStream = false;
newAspect.Init(builder); newAspect.Init(builder);
} }
newAspect._source = world; newAspect._source = world;
builder.Build(out newAspect._mask); builder.Build(out newAspect._mask);
newAspect._isInit = true; newAspect._isBuilt = true;
newAspect._sortIncBuffer = new UnsafeArray<int>(newAspect._mask.inc.Length, true); newAspect._sortIncBuffer = new UnsafeArray<int>(newAspect._mask.inc.Length, true);
newAspect._sortExcBuffer = new UnsafeArray<int>(newAspect._mask.exc.Length, true); newAspect._sortExcBuffer = new UnsafeArray<int>(newAspect._mask.exc.Length, true);
@ -152,6 +203,7 @@ namespace DCFApixels.DragonECS
private void Build(out EcsMask mask) private void Build(out EcsMask mask)
{ {
mask = _maskBuilder.Build(); mask = _maskBuilder.Build();
_isBuilt = true;
} }
#region SupportReflectionHack #region SupportReflectionHack

View File

@ -40,6 +40,10 @@ namespace DCFApixels.DragonECS
{ {
get { return exc; } get { return exc; }
} }
public bool IsEmpty
{
get { return inc.Length == 0 && exc.Length == 0; }
}
#endregion #endregion
#region Constructors #region Constructors

View File

@ -13,6 +13,10 @@ namespace DCFApixels.DragonECS
{ {
EcsPipeline Pipeline { get; set; } EcsPipeline Pipeline { get; set; }
} }
public interface IEcsSystemDefaultLayer : IEcsProcess
{
string Layer { get; }
}
public sealed class EcsPipeline public sealed class EcsPipeline
{ {
private readonly IConfigContainer _configs; private readonly IConfigContainer _configs;
@ -261,20 +265,27 @@ namespace DCFApixels.DragonECS
} }
private void AddInternal(IEcsProcess system, string layerName, bool isUnique) private void AddInternal(IEcsProcess system, string layerName, bool isUnique)
{ {
if (layerName == null) layerName = _basicLayer; if (string.IsNullOrEmpty(layerName))
{
layerName = system is IEcsSystemDefaultLayer defaultLayer ? defaultLayer.Layer : _basicLayer;
}
List<IEcsProcess> list; List<IEcsProcess> list;
if (!_systems.TryGetValue(layerName, out list)) if (!_systems.TryGetValue(layerName, out list))
{ {
list = new List<IEcsProcess> { new SystemsLayerMarkerSystem(layerName.ToString()) }; list = new List<IEcsProcess> { new SystemsLayerMarkerSystem(layerName) };
_systems.Add(layerName, list); _systems.Add(layerName, list);
} }
if ((_uniqueTypes.Add(system.GetType()) == false && isUnique)) if (_uniqueTypes.Add(system.GetType()) == false && isUnique)
{
return; return;
}
list.Add(system); list.Add(system);
if (system is IEcsModule module)//если система одновременно явялется и системой и модулем то за один Add будет вызван Add и AddModule if (system is IEcsModule module)//если система одновременно явялется и системой и модулем то за один Add будет вызван Add и AddModule
{
AddModule(module); AddModule(module);
} }
}
public Builder AddModule(IEcsModule module) public Builder AddModule(IEcsModule module)
{ {
module.Import(this); module.Import(this);

View File

@ -5,15 +5,15 @@ namespace DCFApixels.DragonECS
public abstract class EcsQueryExecutor public abstract class EcsQueryExecutor
{ {
private EcsWorld _source; private EcsWorld _source;
public int WorldID public short WorldID
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _source.id; get { return _source.id; }
} }
public EcsWorld World public EcsWorld World
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => _source; get { return _source; }
} }
public abstract long Version { get; } public abstract long Version { get; }
internal void Initialize(EcsWorld world) internal void Initialize(EcsWorld world)

View File

@ -30,29 +30,11 @@ namespace DCFApixels.DragonECS.Internal
{ {
internal static class Throw internal static class Throw
{ {
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ArgumentNull()
{
throw new ArgumentNullException();
}
[MethodImpl(MethodImplOptions.NoInlining)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void ConstraintIsAlreadyContainedInMask(Type type) internal static void ConstraintIsAlreadyContainedInMask(Type type)
{ {
throw new EcsFrameworkException($"The {EcsDebugUtility.GetGenericTypeName(type)} constraint is already contained in the mask."); 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)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void Group_AlreadyContains(int entityID) internal static void Group_AlreadyContains(int entityID)
{ {
@ -128,6 +110,18 @@ namespace DCFApixels.DragonECS.Internal
else else
throw new EcsFrameworkException($"The {entity} is not alive."); throw new EcsFrameworkException($"The {entity} is not alive.");
} }
[MethodImpl(MethodImplOptions.NoInlining)]
internal static void ArgumentNull()
{
throw new ArgumentNullException();
}
[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)] [MethodImpl(MethodImplOptions.NoInlining)]
internal static void UndefinedException() internal static void UndefinedException()
{ {

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace DCFApixels.DragonECS.UncheckedCore
{
public static class UncheckedCoreUtility
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsSpan CreateSpan(short worldID, ReadOnlySpan<int> entitesArray)
{
return new EcsSpan(worldID, entitesArray);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsSpan CreateSpan(short worldID, int[] entitesArray, int startIndex, int length)
{
return new EcsSpan(worldID, entitesArray, startIndex, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsSpan CreateSpan(short worldID, int[] entitesArray, int length)
{
return new EcsSpan(worldID, entitesArray, length);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsSpan CreateSpan(short worldID, int[] entitesArray)
{
return new EcsSpan(worldID, entitesArray);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static EcsSpan CreateEmptySpan(short worldID)
{
return new EcsSpan(worldID, Array.Empty<int>());
}
public static bool CheckSpanValideDebug(EcsSpan span)
{
HashSet<int> set = new HashSet<int>(span.Count);
foreach (var e in span)
{
if (set.Add(e) == false)
{
return false;
}
}
return true;
}
}
}

View File

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9d505e05a1757344fa2237b4b9be4409
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: