From 640c6fcc789f546f1d94611aa929313282866455 Mon Sep 17 00:00:00 2001 From: Ariel Coppes Date: Wed, 7 Jan 2026 10:19:15 -0300 Subject: [PATCH 1/3] added option of creating a mask specifying the type without generics, but it only works if the pools were created before with the proper because of how ecs pool works right now, but this starts allowing creating filters dynamically --- src/worlds.cs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/worlds.cs b/src/worlds.cs index dfd35fb..5051171 100644 --- a/src/worlds.cs +++ b/src/worlds.cs @@ -505,6 +505,19 @@ public Mask Inc () where T : struct { Include[IncludeCount++] = poolId; return this; } + + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public Mask IncByType(Type type) { + var poolId = _world.GetPoolByType(type).GetId (); +#if DEBUG && !LEOECSLITE_NO_SANITIZE_CHECKS + if (_built) { throw new Exception ("Cant change built mask."); } + if (Array.IndexOf (Include, poolId, 0, IncludeCount) != -1) { throw new Exception ($"{type.Name} already in constraints list."); } + if (Array.IndexOf (Exclude, poolId, 0, ExcludeCount) != -1) { throw new Exception ($"{type.Name} already in constraints list."); } +#endif + if (IncludeCount == Include.Length) { Array.Resize (ref Include, IncludeCount << 1); } + Include[IncludeCount++] = poolId; + return this; + } #if UNITY_2020_3_OR_NEWER [UnityEngine.Scripting.Preserve] @@ -521,6 +534,22 @@ public Mask Exc () where T : struct { Exclude[ExcludeCount++] = poolId; return this; } + +#if UNITY_2020_3_OR_NEWER + [UnityEngine.Scripting.Preserve] +#endif + [MethodImpl (MethodImplOptions.AggressiveInlining)] + public Mask ExcByType(Type type) { + var poolId = _world.GetPoolByType(type).GetId (); +#if DEBUG && !LEOECSLITE_NO_SANITIZE_CHECKS + if (_built) { throw new Exception ("Cant change built mask."); } + if (Array.IndexOf (Include, poolId, 0, IncludeCount) != -1) { throw new Exception ($"{type.Name} already in constraints list."); } + if (Array.IndexOf (Exclude, poolId, 0, ExcludeCount) != -1) { throw new Exception ($"{type.Name} already in constraints list."); } +#endif + if (ExcludeCount == Exclude.Length) { Array.Resize (ref Exclude, ExcludeCount << 1); } + Exclude[ExcludeCount++] = poolId; + return this; + } [MethodImpl (MethodImplOptions.AggressiveInlining)] public EcsFilter End (int capacity = 512) { From b45ceb655c6c6db309f59fe72876c4bad3694d1d Mon Sep 17 00:00:00 2001 From: Ariel Coppes Date: Wed, 7 Jan 2026 14:18:56 -0300 Subject: [PATCH 2/3] get pool by type now creates new pool by using reflection for generic type --- src/worlds.cs | 55 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/src/worlds.cs b/src/worlds.cs index 5051171..fa4aae1 100644 --- a/src/worlds.cs +++ b/src/worlds.cs @@ -6,6 +6,7 @@ using System; using System.Collections.Generic; +using System.Reflection; using System.Runtime.CompilerServices; #if ENABLE_IL2CPP @@ -256,8 +257,35 @@ public IEcsPool GetPoolById (int typeId) { } [MethodImpl (MethodImplOptions.AggressiveInlining)] - public IEcsPool GetPoolByType (Type type) { - return _poolHashes.TryGetValue (type, out var pool) ? pool : null; + public IEcsPool GetPoolByType (Type poolType) { + + if (_poolHashes.TryGetValue (poolType, out var rawPool)) { + return rawPool; + } + + var genericPoolType = typeof(EcsPool<>); + var constructed = genericPoolType.MakeGenericType(poolType); + + var poolConstructors = constructed.GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance); + var pool = poolConstructors[0].Invoke(new object[] + { + this, _poolsCount, _poolDenseSize, Entities.Length, _poolRecycledSize + }) as IEcsPool; + + // var pool = Activator.CreateInstance(constructed) as IEcsPool; + // EcsWorld world, int id, int denseCapacity, int sparseCapacity, int recycledCapacity + // var pool = new EcsPool (this, _poolsCount, _poolDenseSize, Entities.Length, _poolRecycledSize); + _poolHashes[poolType] = pool; + if (_poolsCount == _pools.Length) { + var newSize = _poolsCount << 1; + Array.Resize (ref _pools, newSize); + Array.Resize (ref _filtersByIncludedComponents, newSize); + Array.Resize (ref _filtersByExcludedComponents, newSize); + } + _pools[_poolsCount++] = pool; + return pool; + + // return _poolHashes.TryGetValue (type, out var pool) ? pool : null; } public int GetAllEntities (ref int[] entities) { @@ -494,16 +522,9 @@ void Reset () { } [MethodImpl (MethodImplOptions.AggressiveInlining)] - public Mask Inc () where T : struct { - var poolId = _world.GetPool ().GetId (); -#if DEBUG && !LEOECSLITE_NO_SANITIZE_CHECKS - if (_built) { throw new Exception ("Cant change built mask."); } - if (Array.IndexOf (Include, poolId, 0, IncludeCount) != -1) { throw new Exception ($"{typeof (T).Name} already in constraints list."); } - if (Array.IndexOf (Exclude, poolId, 0, ExcludeCount) != -1) { throw new Exception ($"{typeof (T).Name} already in constraints list."); } -#endif - if (IncludeCount == Include.Length) { Array.Resize (ref Include, IncludeCount << 1); } - Include[IncludeCount++] = poolId; - return this; + public Mask Inc () where T : struct + { + return IncByType(typeof(T)); } [MethodImpl (MethodImplOptions.AggressiveInlining)] @@ -524,15 +545,7 @@ public Mask IncByType(Type type) { #endif [MethodImpl (MethodImplOptions.AggressiveInlining)] public Mask Exc () where T : struct { - var poolId = _world.GetPool ().GetId (); -#if DEBUG && !LEOECSLITE_NO_SANITIZE_CHECKS - if (_built) { throw new Exception ("Cant change built mask."); } - if (Array.IndexOf (Include, poolId, 0, IncludeCount) != -1) { throw new Exception ($"{typeof (T).Name} already in constraints list."); } - if (Array.IndexOf (Exclude, poolId, 0, ExcludeCount) != -1) { throw new Exception ($"{typeof (T).Name} already in constraints list."); } -#endif - if (ExcludeCount == Exclude.Length) { Array.Resize (ref Exclude, ExcludeCount << 1); } - Exclude[ExcludeCount++] = poolId; - return this; + return ExcByType(typeof(T)); } #if UNITY_2020_3_OR_NEWER From 46a410b87ade6b22336031199f9dcf532a51cb9a Mon Sep 17 00:00:00 2001 From: Ariel Coppes Date: Thu, 8 Jan 2026 10:08:32 -0300 Subject: [PATCH 3/3] added compile flag to add profiler samples per system --- src/systems.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/systems.cs b/src/systems.cs index a14cd4a..ad7ebaa 100644 --- a/src/systems.cs +++ b/src/systems.cs @@ -164,7 +164,15 @@ public void Init () { public void Run () { for (int i = 0, iMax = _runSystemsCount; i < iMax; i++) { + +#if DEBUG && LEOECSLITE_PROFILESYSTEMS + UnityEngine.Profiling.Profiler.BeginSample(_runSystems[i].GetType().Name); +#endif _runSystems[i].Run (this); +#if DEBUG && LEOECSLITE_PROFILESYSTEMS + UnityEngine.Profiling.Profiler.EndSample(); +#endif + #if DEBUG && !LEOECSLITE_NO_SANITIZE_CHECKS var worldName = CheckForLeakedEntities (); if (worldName != null) { throw new System.Exception ($"Empty entity detected in world \"{worldName}\" after {_runSystems[i].GetType ().Name}.Run()."); }