com.alicizax.unity.ui.exten.../Runtime/RecyclerView/ViewProvider/MixedViewProvider.cs

112 lines
3.6 KiB
C#
Raw Normal View History

2025-03-12 20:59:12 +08:00
using System;
using System.Collections.Generic;
namespace AlicizaX.UI
2025-03-12 20:59:12 +08:00
{
public class MixedViewProvider : ViewProvider
{
private readonly MixedObjectPool<ViewHolder> objectPool;
private readonly Dictionary<string, ViewHolder> templatesByName = new(StringComparer.Ordinal);
2026-04-15 14:51:57 +08:00
private readonly Dictionary<string, int> warmCounts = new(StringComparer.Ordinal);
2025-03-12 20:59:12 +08:00
public override string PoolStats =>
$"hits={objectPool.HitCount}, misses={objectPool.MissCount}, destroys={objectPool.DestroyCount}";
2025-03-12 20:59:12 +08:00
public MixedViewProvider(RecyclerView recyclerView, ViewHolder[] templates) : base(recyclerView, templates)
{
for (int i = 0; i < templates.Length; i++)
2025-03-12 20:59:12 +08:00
{
ViewHolder template = templates[i];
if (template == null)
{
continue;
}
2026-04-03 11:36:45 +08:00
templatesByName[template.GetType().Name] = template;
2025-03-12 20:59:12 +08:00
}
2025-05-28 19:37:38 +08:00
UnityMixedComponentFactory<ViewHolder> factory = new(templatesByName, recyclerView.Content);
2025-05-28 19:37:38 +08:00
objectPool = new MixedObjectPool<ViewHolder>(factory);
2025-03-12 20:59:12 +08:00
}
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;
2025-03-12 20:59:12 +08:00
}
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;
2025-03-12 20:59:12 +08:00
}
public override ViewHolder Allocate(string viewName)
{
2025-05-28 19:37:38 +08:00
var viewHolder = objectPool.Allocate(viewName);
viewHolder.gameObject.SetActive(true);
return viewHolder;
2025-03-12 20:59:12 +08:00
}
public override void Free(string viewName, ViewHolder viewHolder)
{
2025-05-28 19:37:38 +08:00
objectPool.Free(viewName, viewHolder);
2025-03-12 20:59:12 +08:00
}
public override void Reset()
{
Clear();
(Adapter as IItemRenderCacheOwner)?.ReleaseAllItemRenders();
2025-05-28 19:37:38 +08:00
objectPool.Dispose();
2025-03-12 20:59:12 +08:00
}
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);
2026-04-15 14:51:57 +08:00
warmCounts.Clear();
for (int index = start; index <= end; index++)
{
string viewName = Adapter.GetViewName(index);
if (string.IsNullOrEmpty(viewName))
{
continue;
}
2026-04-15 14:51:57 +08:00
warmCounts.TryGetValue(viewName, out int count);
warmCounts[viewName] = count + 1;
}
2026-04-15 14:51:57 +08:00
foreach (var pair in warmCounts)
{
int targetCount = pair.Value + Math.Max(1, LayoutManager.Unit);
objectPool.EnsureCapacity(pair.Key, targetCount);
objectPool.Warm(pair.Key, targetCount);
}
}
2025-03-12 20:59:12 +08:00
}
}