using System; using System.Collections.Generic; namespace AlicizaX.UI { public class MixedViewProvider : ViewProvider { private readonly MixedObjectPool objectPool; private readonly Dictionary templatesByName = new(StringComparer.Ordinal); public override string PoolStats => $"hits={objectPool.HitCount}, misses={objectPool.MissCount}, destroys={objectPool.DestroyCount}"; public MixedViewProvider(RecyclerView recyclerView, ViewHolder[] templates) : base(recyclerView, templates) { for (int i = 0; i < templates.Length; i++) { ViewHolder template = templates[i]; if (template == null) { continue; } templatesByName[template.GetType().Name] = template; } UnityMixedComponentFactory factory = new(templatesByName, recyclerView.Content); objectPool = new MixedObjectPool(factory); } public override ViewHolder GetTemplate(string viewName) { if (templates == null || templates.Length == 0) { throw new NullReferenceException("ViewProvider templates can not null or empty."); } if (!templatesByName.TryGetValue(viewName, out ViewHolder template)) { throw new KeyNotFoundException($"ViewProvider template '{viewName}' was not found."); } return template; } public override ViewHolder[] GetTemplates() { if (templates == null || templates.Length == 0) { throw new NullReferenceException("ViewProvider templates can not null or empty."); } ViewHolder[] values = new ViewHolder[templatesByName.Count]; templatesByName.Values.CopyTo(values, 0); return values; } public override ViewHolder Allocate(string viewName) { var viewHolder = objectPool.Allocate(viewName); viewHolder.gameObject.SetActive(true); return viewHolder; } public override void Free(string viewName, ViewHolder viewHolder) { objectPool.Free(viewName, viewHolder); } public override void Reset() { Clear(); (Adapter as IItemRenderCacheOwner)?.ReleaseAllItemRenders(); objectPool.Dispose(); } public override void PreparePool() { int warmCount = GetRecommendedWarmCount(); if (warmCount <= 0) { return; } int itemCount = GetItemCount(); int start = Math.Max(0, LayoutManager.GetStartIndex()); int end = Math.Min(itemCount - 1, start + warmCount - 1); Dictionary counts = new(StringComparer.Ordinal); for (int index = start; index <= end; index++) { string viewName = Adapter.GetViewName(index); if (string.IsNullOrEmpty(viewName)) { continue; } counts.TryGetValue(viewName, out int count); counts[viewName] = count + 1; } foreach (var pair in counts) { int targetCount = pair.Value + Math.Max(1, LayoutManager.Unit); objectPool.EnsureCapacity(pair.Key, targetCount); objectPool.Warm(pair.Key, targetCount); } } } }