diff --git a/Scripts/UIParticle.cs b/Scripts/UIParticle.cs index a983f7d..0256370 100755 --- a/Scripts/UIParticle.cs +++ b/Scripts/UIParticle.cs @@ -41,11 +41,11 @@ namespace Coffee.UIExtensions private bool _shouldBeRemoved; private Mesh _bakedMesh; - private readonly List _modifiedMaterials = new List(); - private readonly List _maskMaterials = new List(); - private readonly List _activeMeshIndices = new List(); - private static readonly List s_TempMaterials = new List(2); + private List _modifiedMaterials; + private List _maskMaterials; + private List _activeMeshIndices; private static MaterialPropertyBlock s_Mpb; + private static readonly List s_TempMaterials = new List(2); private static readonly List s_PrevMaskMaterials = new List(); private static readonly List s_PrevModifiedMaterials = new List(); private static readonly List s_Components = new List(); @@ -259,7 +259,7 @@ namespace Coffee.UIExtensions { var mat = GetModifiedMaterial(s_TempMaterials[0], ps.GetTextureForSprite()); for (var k = 1; k < s_Components.Count; k++) - mat = (s_Components[k] as IMaterialModifier).GetModifiedMaterial(mat); + mat = ((IMaterialModifier)s_Components[k]).GetModifiedMaterial(mat); canvasRenderer.SetMaterial(mat, j); UpdateMaterialProperties(r, j); j++; @@ -272,7 +272,7 @@ namespace Coffee.UIExtensions { var mat = GetModifiedMaterial(s_TempMaterials[1], null); for (var k = 1; k < s_Components.Count; k++) - mat = (s_Components[k] as IMaterialModifier).GetModifiedMaterial(mat); + mat = ((IMaterialModifier)s_Components[k]).GetModifiedMaterial(mat); canvasRenderer.SetMaterial(mat, j++); } } @@ -362,7 +362,10 @@ namespace Coffee.UIExtensions #if !SERIALIZE_FIELD_MASKABLE maskable = m_Maskable; #endif - activeMeshIndices.Clear(); + + _modifiedMaterials = ListPool.Rent(); + _maskMaterials = ListPool.Rent(); + _activeMeshIndices = ListPool.Rent(); UIParticleUpdater.Register(this); particles.Exec(p => p.GetComponent().enabled = false); @@ -407,6 +410,16 @@ namespace Coffee.UIExtensions MeshPool.Return(_bakedMesh); _bakedMesh = null; + activeMeshIndices.Clear(); + UpdateMaterial(); + + ListPool.Return(_modifiedMaterials); + ListPool.Return(_maskMaterials); + ListPool.Return(_activeMeshIndices); + _modifiedMaterials = null; + _maskMaterials = null; + _activeMeshIndices = null; + base.OnDisable(); } diff --git a/Scripts/Utils.cs b/Scripts/Utils.cs index 44b47d5..9c3c8f7 100644 --- a/Scripts/Utils.cs +++ b/Scripts/Utils.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Reflection; using UnityEngine; @@ -6,7 +7,69 @@ using Object = UnityEngine.Object; namespace Coffee.UIParticleExtensions { - internal static class Vector3Extensions + internal static class ListPool + { + private static readonly Dictionary _pools = new Dictionary(); + + public static List Rent() + { + return GetListPool().Rent(); + + } + + public static void Return(List insance) + { + GetListPool().Return(insance); + } + + private static ObjectPool> GetListPool() + { + object pool; + if (!_pools.TryGetValue(typeof(T), out pool)) + { + pool = new ObjectPool>(() => new List(), x => true, x => x.Clear()); + _pools.Add(typeof(T), pool); + } + return pool as ObjectPool>; + } + } + + internal class ObjectPool + { + private readonly Stack _pool = new Stack(32); + private readonly Func _onCreate; + private readonly Predicate _onValid; + private readonly Action _onReturn; + + public ObjectPool(Func onCreate, Predicate onValid, Action onReturn) + { + _onCreate = onCreate; + _onValid = onValid; + _onReturn = onReturn; + } + + public T Rent() + { + while (0 < _pool.Count) + { + var instance = _pool.Pop(); + if (_onValid(instance)) + return instance; + } + + return _onCreate(); + } + + public void Return(T instance) + { + if (instance == null || _pool.Contains(instance)) return; + + _onReturn(instance); + _pool.Push(instance); + } + } + + public static class Vector3Extensions { public static Vector3 Inverse(this Vector3 self) {