diff --git a/src/Builtin/InjectSystem.cs b/src/Builtin/InjectSystem.cs index e387514..b4f9151 100644 --- a/src/Builtin/InjectSystem.cs +++ b/src/Builtin/InjectSystem.cs @@ -4,9 +4,6 @@ using System.Linq; namespace DCFApixels.DragonECS { - //TODO развить идею инжектов - //добавить контейнер, который автоматически создается, собирает в себя все пре-инжекты и авто-инжектится во все системы. - //но это спорная идея public interface IEcsPreInject : IEcsSystem { void PreInject(object obj); diff --git a/src/Debug/EcsDebug.cs b/src/Debug/EcsDebug.cs index 1e29074..57bbc1e 100644 --- a/src/Debug/EcsDebug.cs +++ b/src/Debug/EcsDebug.cs @@ -36,7 +36,14 @@ namespace DCFApixels.DragonECS public static void Set(DebugService service) => DebugService.Set(service); [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Print(object v) => DebugService.Instance.Print(v); + public static void PrintWarning(object v) => Print(EcsConsts.DEBUG_WARNING_TAG, v); + public static void PrintError(object v) => Print(EcsConsts.DEBUG_ERROR_TAG, v); + public static void Print(object v) + { +#if !DISABLE_DRAGONECS_DEBUGGER + DebugService.Instance.Print(v); +#endif + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Print(string tag, object v) { diff --git a/src/EcsGroup.cs b/src/EcsGroup.cs index c7126d9..2bb9460 100644 --- a/src/EcsGroup.cs +++ b/src/EcsGroup.cs @@ -219,12 +219,11 @@ namespace DCFApixels.DragonECS } #endregion - #region Sort/Clear - //public void Sort() { } //TODO прошлай реализация сортировки не удачная, так как в dense могут храниться занчения больше чем dense.Length + #region Clear public void Clear() { _count = 0; - //массив _dense нет смысла очищать, испольщуется только область от 1 до _count + //массив _dense нет смысла очищать for (int i = 0; i < _sparse.Length; i++) _sparse[i] = 0; } diff --git a/src/EcsWorld.cs b/src/EcsWorld.cs index 011e480..e5ff6e6 100644 --- a/src/EcsWorld.cs +++ b/src/EcsWorld.cs @@ -26,9 +26,6 @@ namespace DCFApixels.DragonECS private short[] _componentCounts; private EcsGroup _allEntites; - //буфер удаления откладывает освобождение андишников сущностей. - //Нужен для того чтобы запускать некоторые процесыы связанные с удалением сущности не по одному при каждом удалении, а пачкой - //В теории такой подход частично улучшает ситуацию с переполнением поколений private int[] _delEntBuffer; private int _delEntBufferCount; @@ -138,7 +135,6 @@ namespace DCFApixels.DragonECS _pools[uniqueID] = pool; pool.OnInit(this, uniqueID); _poolsCount++; - //EcsDebug.Print(pool.GetType().FullName); } return (TPool)_pools[uniqueID]; @@ -158,39 +154,39 @@ namespace DCFApixels.DragonECS #endregion #region Queries - public TExecutor GetExecutor(Func builder) where TExecutor: EcsQueryExecutor + public TExecutor GetExecutor() where TExecutor : EcsQueryExecutor, new() { int id = WorldMetaStorage.GetExecutorId(_worldTypeID); if (id >= _executors.Length) Array.Resize(ref _executors, _executors.Length << 1); if (_executors[id] == null) - _executors[id] = builder(this); + { + var executor = new TExecutor(); + executor.Initialize(this); + _executors[id] = executor; + } return (TExecutor)_executors[id]; } - private EcsWhereExecutor EcsWhereExecutorBuilder(EcsWorld world) where TSubject : EcsSubject - { - return new EcsWhereExecutor(world.GetSubject()); - } public EcsWhereResult WhereFor(EcsReadonlyGroup sourceGroup, out TSubject subject) where TSubject : EcsSubject { - var executor = GetExecutor(EcsWhereExecutorBuilder); + var executor = GetExecutor>(); subject = executor.Subject; return executor.ExecuteFor(sourceGroup); } public EcsWhereResult WhereFor(EcsReadonlyGroup sourceGroup) where TSubject : EcsSubject { - return GetExecutor(EcsWhereExecutorBuilder).ExecuteFor(sourceGroup); + return GetExecutor>().ExecuteFor(sourceGroup); } public EcsWhereResult Where(out TSubject subject) where TSubject : EcsSubject { - var executor = GetExecutor(EcsWhereExecutorBuilder); + var executor = GetExecutor>(); subject = executor.Subject; return executor.Execute(); } public EcsWhereResult Where() where TSubject : EcsSubject { - return GetExecutor(EcsWhereExecutorBuilder).Execute(); + return GetExecutor>().Execute(); } #endregion @@ -369,40 +365,6 @@ namespace DCFApixels.DragonECS break; } } - - // public int GetComponents(int entity, ref object[] list) - // { - // var entityOffset = GetRawEntityOffset(entity); - // var itemsCount = _entities[entityOffset + RawEntityOffsets.ComponentsCount]; - // if (itemsCount == 0) { return 0; } - // if (list == null || list.Length < itemsCount) - // { - // list = new object[_pools.Length]; - // } - // var dataOffset = entityOffset + RawEntityOffsets.Components; - // for (var i = 0; i < itemsCount; i++) - // { - // list[i] = _pools[_entities[dataOffset + i]].GetRaw(entity); - // } - // return itemsCount; - // } - - // public int GetComponentTypes(int entity, ref Type[] list) - // { - // var entityOffset = GetRawEntityOffset(entity); - // var itemsCount = _entities[entityOffset + RawEntityOffsets.ComponentsCount]; - // if (itemsCount == 0) { return 0; } - // if (list == null || list.Length < itemsCount) - // { - // list = new Type[_pools.Length]; - // } - // var dataOffset = entityOffset + RawEntityOffsets.Components; - // for (var i = 0; i < itemsCount; i++) - // { - // list[i] = _pools[_entities[dataOffset + i]].GetComponentType(); - // } - // return itemsCount; - // } #endregion } diff --git a/src/Executors/EcsQueryExecutor.cs b/src/Executors/EcsQueryExecutor.cs index 8b8534e..ad6db0b 100644 --- a/src/Executors/EcsQueryExecutor.cs +++ b/src/Executors/EcsQueryExecutor.cs @@ -2,6 +2,14 @@ { public abstract class EcsQueryExecutor { + private EcsWorld _world; + public EcsWorld World => _world; + internal void Initialize(EcsWorld world) + { + _world = world; + OnInitialize(); + } + protected abstract void OnInitialize(); internal void Destroy() => OnDestroy(); protected abstract void OnDestroy(); } diff --git a/src/Executors/EcsWhereExecutor.cs b/src/Executors/EcsWhereExecutor.cs index c7ccc97..db88c69 100644 --- a/src/Executors/EcsWhereExecutor.cs +++ b/src/Executors/EcsWhereExecutor.cs @@ -1,26 +1,28 @@ -using Unity.Profiling; - -namespace DCFApixels.DragonECS +namespace DCFApixels.DragonECS { public sealed class EcsWhereExecutor : EcsQueryExecutor where TSubject : EcsSubject { - private readonly TSubject _subject; - private readonly EcsGroup _filteredGroup; + private TSubject _subject; + private EcsGroup _filteredGroup; private long _executeVersion; - private ProfilerMarker _executeWhere = new ProfilerMarker("JoinAttachQuery.Where"); + private EcsProfilerMarker _executeWhere = new EcsProfilerMarker("Where"); #region Properties public TSubject Subject => _subject; internal long ExecuteVersion => _executeVersion; #endregion - #region Constructors - public EcsWhereExecutor(TSubject subject) + #region OnInitialize/OnDestroy + protected sealed override void OnInitialize() { - _subject = subject; - _filteredGroup = EcsGroup.New(subject.World); + _subject = World.GetSubject(); + _filteredGroup = EcsGroup.New(World); + } + protected sealed override void OnDestroy() + { + _filteredGroup.Release(); } #endregion @@ -33,14 +35,30 @@ namespace DCFApixels.DragonECS #if (DEBUG && !DISABLE_DEBUG) || !DISABLE_DRAGONECS_ASSERT_CHEKS if (sourceGroup.IsNull) throw new System.ArgumentNullException();//TODO составить текст исключения. #endif - _subject.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); + //_subject.GetIteratorFor(sourceGroup).CopyTo(_filteredGroup); + + var pools = _subject.World._pools; + var mask = _subject.Mask; + _filteredGroup.Clear(); + foreach (var e in sourceGroup) + { + for (int i = 0, iMax = mask._inc.Length; i < iMax; i++) + { + if (!pools[mask._inc[i]].Has(e)) + goto next; + } + for (int i = 0, iMax = mask._exc.Length; i < iMax; i++) + { + if (pools[mask._exc[i]].Has(e)) + goto next; + } + _filteredGroup.AddInternal(e); + next: continue; + } + return new EcsWhereResult(this, _filteredGroup.Readonly); } } - protected sealed override void OnDestroy() - { - _filteredGroup.Release(); - } #endregion }