2025-03-12 20:59:12 +08:00
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
2025-11-20 15:40:38 +08:00
|
|
|
namespace AlicizaX.UI
|
2025-03-12 20:59:12 +08:00
|
|
|
{
|
|
|
|
|
public class MixedViewProvider : ViewProvider
|
|
|
|
|
{
|
2026-03-31 15:18:50 +08:00
|
|
|
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
|
|
|
|
2026-03-31 15:18:50 +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)
|
|
|
|
|
{
|
2026-03-31 15:18:50 +08:00
|
|
|
for (int i = 0; i < templates.Length; i++)
|
2025-03-12 20:59:12 +08:00
|
|
|
{
|
2026-03-31 15:18:50 +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
|
|
|
|
2026-03-31 15:18:50 +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.");
|
|
|
|
|
}
|
2026-03-31 15:18:50 +08:00
|
|
|
|
|
|
|
|
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.");
|
|
|
|
|
}
|
2026-03-31 15:18:50 +08:00
|
|
|
|
|
|
|
|
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();
|
2026-03-27 18:38:29 +08:00
|
|
|
(Adapter as IItemRenderCacheOwner)?.ReleaseAllItemRenders();
|
2025-05-28 19:37:38 +08:00
|
|
|
objectPool.Dispose();
|
2025-03-12 20:59:12 +08:00
|
|
|
}
|
2026-03-31 15:18:50 +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();
|
2026-03-31 15:18:50 +08:00
|
|
|
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-03-31 15:18:50 +08:00
|
|
|
}
|
|
|
|
|
|
2026-04-15 14:51:57 +08:00
|
|
|
foreach (var pair in warmCounts)
|
2026-03-31 15:18:50 +08:00
|
|
|
{
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
}
|