From 9876f882d79c29ac5862deb35b3c853ebb801dc9 Mon Sep 17 00:00:00 2001 From: Mikhail <99481254+DCFApixels@users.noreply.github.com> Date: Tue, 26 Mar 2024 16:06:03 +0800 Subject: [PATCH] simplify aspect builder syntax --- src/EcsAspect.cs | 58 +++++++++++++++++++++++++++++++++++++++++++--- src/EcsPipeline.cs | 17 +++++++++++--- 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/EcsAspect.cs b/src/EcsAspect.cs index 5aa3595..cb6f8f6 100644 --- a/src/EcsAspect.cs +++ b/src/EcsAspect.cs @@ -10,7 +10,46 @@ namespace DCFApixels.DragonECS { internal EcsWorld _source; 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 _sortIncBuffer; private UnsafeArray _sortExcBuffer; @@ -28,7 +67,7 @@ namespace DCFApixels.DragonECS } public bool IsInit { - get { return _isInit; } + get { return _isBuilt; } } #endregion @@ -45,6 +84,7 @@ namespace DCFApixels.DragonECS { private EcsWorld _world; private EcsMask.Builder _maskBuilder; + private bool _isBuilt = false; public IncludeMarker Inc { @@ -74,9 +114,18 @@ namespace DCFApixels.DragonECS //TODO добавить оповещение что инициализация через конструктор не работает #if !REFLECTION_DISABLED 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) { newAspect = (EcsAspect)constructorInfo.Invoke(new object[] { builder }); + _constructorStreamBuilder = null; + _isConstructorStream = false; } else #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. newAspect = Activator.CreateInstance(); #pragma warning restore IL2091 + _constructorStreamBuilder = null; + _isConstructorStream = false; newAspect.Init(builder); } newAspect._source = world; builder.Build(out newAspect._mask); - newAspect._isInit = true; + newAspect._isBuilt = true; newAspect._sortIncBuffer = new UnsafeArray(newAspect._mask.inc.Length, true); newAspect._sortExcBuffer = new UnsafeArray(newAspect._mask.exc.Length, true); @@ -152,6 +203,7 @@ namespace DCFApixels.DragonECS private void Build(out EcsMask mask) { mask = _maskBuilder.Build(); + _isBuilt = true; } #region SupportReflectionHack diff --git a/src/EcsPipeline.cs b/src/EcsPipeline.cs index 9baba80..084665c 100644 --- a/src/EcsPipeline.cs +++ b/src/EcsPipeline.cs @@ -13,6 +13,10 @@ namespace DCFApixels.DragonECS { EcsPipeline Pipeline { get; set; } } + public interface IEcsSystemDefaultLayer : IEcsProcess + { + string Layer { get; } + } public sealed class EcsPipeline { private readonly IConfigContainer _configs; @@ -261,19 +265,26 @@ namespace DCFApixels.DragonECS } 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 list; if (!_systems.TryGetValue(layerName, out list)) { - list = new List { new SystemsLayerMarkerSystem(layerName.ToString()) }; + list = new List { new SystemsLayerMarkerSystem(layerName) }; _systems.Add(layerName, list); } - if ((_uniqueTypes.Add(system.GetType()) == false && isUnique)) + if (_uniqueTypes.Add(system.GetType()) == false && isUnique) + { return; + } list.Add(system); if (system is IEcsModule module)//если система одновременно явялется и системой и модулем то за один Add будет вызван Add и AddModule + { AddModule(module); + } } public Builder AddModule(IEcsModule module) {