modify
This commit is contained in:
parent
55da0d4f00
commit
aa1da4de29
@ -1,8 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a22aa56c3da6d724e97aafd9f3e7ed67
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,11 +0,0 @@
|
||||
|
||||
public interface IMixedObjectFactory<T> where T : class
|
||||
{
|
||||
T Create(string typeName);
|
||||
|
||||
void Destroy(string typeName, T obj);
|
||||
|
||||
void Reset(string typeName, T obj);
|
||||
|
||||
bool Validate(string typeName, T obj);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30f89ee61eb3f0949b5300bd9b7cc577
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,8 +0,0 @@
|
||||
using System;
|
||||
|
||||
public interface IMixedObjectPool<T> : IDisposable where T : class
|
||||
{
|
||||
T Allocate(string typeName);
|
||||
|
||||
void Free(string typeName, T obj);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f4c13a4827ebad4a9ff08e636fbc67e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,28 +0,0 @@
|
||||
|
||||
public interface IObjectFactory<T> where T : class
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建对象
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
T Create();
|
||||
|
||||
/// <summary>
|
||||
/// 销毁对象
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
void Destroy(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// 重置对象
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
void Reset(T obj);
|
||||
|
||||
/// <summary>
|
||||
/// 验证对象
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
bool Validate(T obj);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 77a642084db01624c8e5876605195d49
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,23 +0,0 @@
|
||||
using System;
|
||||
|
||||
public interface IObjectPool : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// 从池子中分配一个可用对象,没有的话就创建一个
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
object Allocate();
|
||||
|
||||
/// <summary>
|
||||
/// 将对象回收到池子中去,如果池中的对象数量已经超过了 maxSize,则直接销毁该对象
|
||||
/// </summary>
|
||||
/// <param name="obj"></param>
|
||||
void Free(object obj);
|
||||
}
|
||||
|
||||
public interface IObjectPool<T> : IObjectPool, IDisposable where T : class
|
||||
{
|
||||
new T Allocate();
|
||||
|
||||
void Free(T obj);
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dd12164a5eea20e41bf7f3b7704f4b33
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,5 +0,0 @@
|
||||
|
||||
public interface IPooledObject
|
||||
{
|
||||
void Free();
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b174ccb64b3938c449d4a69a3262d8d5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,101 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class MixedObjectPool<T> : IMixedObjectPool<T> where T : class
|
||||
{
|
||||
private const int DEFAULT_MAX_SIZE_PER_TYPE = 10;
|
||||
|
||||
private readonly ConcurrentDictionary<string, List<T>> entries;
|
||||
private readonly ConcurrentDictionary<string, int> typeSize;
|
||||
private readonly IMixedObjectFactory<T> factory;
|
||||
|
||||
private int defaultMaxSizePerType;
|
||||
|
||||
public MixedObjectPool(IMixedObjectFactory<T> factory) : this(factory, DEFAULT_MAX_SIZE_PER_TYPE)
|
||||
{
|
||||
}
|
||||
|
||||
public MixedObjectPool(IMixedObjectFactory<T> factory, int defaultMaxSizePerType)
|
||||
{
|
||||
this.factory = factory;
|
||||
this.defaultMaxSizePerType = defaultMaxSizePerType;
|
||||
|
||||
if (defaultMaxSizePerType <= 0)
|
||||
{
|
||||
throw new ArgumentException("The maxSize must be greater than 0.");
|
||||
}
|
||||
|
||||
entries = new ConcurrentDictionary<string, List<T>>();
|
||||
typeSize = new ConcurrentDictionary<string, int>();
|
||||
}
|
||||
|
||||
public T Allocate(string typeName)
|
||||
{
|
||||
if (entries.TryGetValue(typeName, out List<T> list) && list.Count > 0)
|
||||
{
|
||||
T obj = list[0];
|
||||
list.RemoveAt(0);
|
||||
return obj;
|
||||
}
|
||||
return factory.Create(typeName);
|
||||
}
|
||||
|
||||
public void Free(string typeName, T obj)
|
||||
{
|
||||
if (obj == null) return;
|
||||
|
||||
if (!factory.Validate(typeName, obj))
|
||||
{
|
||||
factory.Destroy(typeName, obj);
|
||||
return;
|
||||
}
|
||||
|
||||
int maxSize = GetMaxSize(typeName);
|
||||
List<T> list = entries.GetOrAdd(typeName, n => new List<T>());
|
||||
if (list.Count >= maxSize)
|
||||
{
|
||||
factory.Destroy(typeName, obj);
|
||||
return;
|
||||
}
|
||||
|
||||
factory.Reset(typeName, obj);
|
||||
list.Add(obj);
|
||||
}
|
||||
|
||||
public int GetMaxSize(string typeName)
|
||||
{
|
||||
if (typeSize.TryGetValue(typeName, out int size))
|
||||
{
|
||||
return size;
|
||||
}
|
||||
return defaultMaxSizePerType;
|
||||
}
|
||||
|
||||
public void SetMaxSize(string typeName, int value)
|
||||
{
|
||||
typeSize.AddOrUpdate(typeName, value, (key, oldValue) => value);
|
||||
}
|
||||
|
||||
protected virtual void Clear()
|
||||
{
|
||||
foreach (var kv in entries)
|
||||
{
|
||||
string typeName = kv.Key;
|
||||
List<T> list = kv.Value;
|
||||
|
||||
if (list == null || list.Count <= 0) continue;
|
||||
|
||||
list.ForEach(e => factory.Destroy(typeName, e));
|
||||
list.Clear();
|
||||
}
|
||||
entries.Clear();
|
||||
typeSize.Clear();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Clear();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0a62e68f43eac4b419140191eb09ea56
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,108 +0,0 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
|
||||
public class ObjectPool<T> : IObjectPool<T> where T : class
|
||||
{
|
||||
private int maxSize;
|
||||
private int initialSize;
|
||||
protected readonly T[] entries = null;
|
||||
protected readonly IObjectFactory<T> factory;
|
||||
|
||||
public ObjectPool(IObjectFactory<T> factory) : this(factory, Environment.ProcessorCount * 2)
|
||||
{
|
||||
}
|
||||
|
||||
public ObjectPool(IObjectFactory<T> factory, int maxSize) : this(factory, 0, maxSize)
|
||||
{
|
||||
}
|
||||
|
||||
public ObjectPool(IObjectFactory<T> factory, int initialSize, int maxSize)
|
||||
{
|
||||
this.factory = factory;
|
||||
this.initialSize = initialSize;
|
||||
this.maxSize = maxSize;
|
||||
this.entries = new T[maxSize];
|
||||
|
||||
if (maxSize < initialSize)
|
||||
{
|
||||
throw new ArgumentException("The maxSize must be greater than or equal to the initialSize.");
|
||||
}
|
||||
|
||||
for (int i = 0; i < initialSize; i++)
|
||||
{
|
||||
entries[i] = factory.Create();
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxSize => maxSize;
|
||||
|
||||
public int InitialSize => initialSize;
|
||||
|
||||
public virtual T Allocate()
|
||||
{
|
||||
for (var i = 0; i < entries.Length; i++)
|
||||
{
|
||||
T value = entries[i];
|
||||
if (value == null) continue;
|
||||
|
||||
if (Interlocked.CompareExchange(ref entries[i], null, value) == value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
return factory.Create();
|
||||
}
|
||||
|
||||
public virtual void Free(T obj)
|
||||
{
|
||||
if (obj == null) return;
|
||||
|
||||
if (!factory.Validate(obj))
|
||||
{
|
||||
factory.Destroy(obj);
|
||||
return;
|
||||
}
|
||||
|
||||
factory.Reset(obj);
|
||||
|
||||
for (var i = 0; i < entries.Length; i++)
|
||||
{
|
||||
if (Interlocked.CompareExchange(ref entries[i], obj, null) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
factory.Destroy(obj);
|
||||
}
|
||||
|
||||
object IObjectPool.Allocate()
|
||||
{
|
||||
return Allocate();
|
||||
}
|
||||
|
||||
public void Free(object obj)
|
||||
{
|
||||
Free((T)obj);
|
||||
}
|
||||
|
||||
protected virtual void Clear()
|
||||
{
|
||||
for (var i = 0; i < entries.Length; i++)
|
||||
{
|
||||
var value = Interlocked.Exchange(ref entries[i], null);
|
||||
|
||||
if (value != null)
|
||||
{
|
||||
factory.Destroy(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Clear();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 30999e5e03e2b434996100b09960468f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,36 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class UnityComponentFactory<T> : IObjectFactory<T> where T : Component
|
||||
{
|
||||
private T template;
|
||||
private Transform parent;
|
||||
|
||||
public UnityComponentFactory(T template, Transform parent)
|
||||
{
|
||||
this.template = template;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public T Create()
|
||||
{
|
||||
T obj = Object.Instantiate(template, parent);
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void Destroy(T obj)
|
||||
{
|
||||
Object.Destroy(obj.gameObject);
|
||||
}
|
||||
|
||||
public void Reset(T obj)
|
||||
{
|
||||
obj.gameObject.SetActive(false);
|
||||
obj.gameObject.transform.position = Vector3.zero;
|
||||
obj.gameObject.transform.rotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public bool Validate(T obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3e2e3a0444783a7469d494ad630dc705
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,35 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class UnityGameObjectFactory : IObjectFactory<GameObject>
|
||||
{
|
||||
protected GameObject template;
|
||||
protected Transform parent;
|
||||
|
||||
public UnityGameObjectFactory(GameObject template, Transform parent)
|
||||
{
|
||||
this.template = template;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public virtual GameObject Create()
|
||||
{
|
||||
return Object.Instantiate(template, parent);
|
||||
}
|
||||
|
||||
public virtual void Reset(GameObject obj)
|
||||
{
|
||||
obj.SetActive(false);
|
||||
obj.transform.position = Vector3.zero;
|
||||
obj.transform.rotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public virtual void Destroy(GameObject obj)
|
||||
{
|
||||
Object.Destroy(obj);
|
||||
}
|
||||
|
||||
public virtual bool Validate(GameObject obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7373bce96f2a515499c52b060ad9e01e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,61 +0,0 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
public class UnityMixedComponentFactory<T> : IMixedObjectFactory<T> where T : Component
|
||||
{
|
||||
protected T template;
|
||||
protected Transform parent;
|
||||
protected List<T> list;
|
||||
|
||||
private Dictionary<string, T> dict = new();
|
||||
|
||||
public UnityMixedComponentFactory(T template, Transform parent)
|
||||
{
|
||||
this.template = template;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public UnityMixedComponentFactory(List<T> list, Transform parent)
|
||||
{
|
||||
this.list = list;
|
||||
this.parent = parent;
|
||||
|
||||
foreach (var data in list)
|
||||
{
|
||||
dict[data.name] = data;
|
||||
}
|
||||
}
|
||||
|
||||
public UnityMixedComponentFactory(Dictionary<string, T> dict, Transform parent)
|
||||
{
|
||||
this.dict = dict;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public T Create(string typeName)
|
||||
{
|
||||
T obj = Object.Instantiate(dict[typeName], parent);
|
||||
obj.transform.position = Vector3.zero;
|
||||
obj.transform.rotation = Quaternion.identity;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void Destroy(string typeName, T obj)
|
||||
{
|
||||
Object.Destroy(obj.gameObject);
|
||||
}
|
||||
|
||||
public void Reset(string typeName, T obj)
|
||||
{
|
||||
obj.gameObject.SetActive(false);
|
||||
obj.transform.position = Vector3.zero;
|
||||
obj.transform.rotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public bool Validate(string typeName, T obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c2d58d006be3fc458b8c6761d76bc88
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -1,40 +0,0 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class UnityMixedGameObjectFactory : IMixedObjectFactory<GameObject>
|
||||
{
|
||||
protected GameObject template;
|
||||
protected Transform parent;
|
||||
|
||||
public UnityMixedGameObjectFactory(GameObject template, Transform parent)
|
||||
{
|
||||
this.template = template;
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public GameObject Create(string typeName)
|
||||
{
|
||||
GameObject obj = Object.Instantiate(template, parent);
|
||||
GameObject model = Object.Instantiate(Resources.Load<GameObject>("ObjectPools/" + typeName), obj.transform);
|
||||
model.transform.position = Vector3.zero;
|
||||
model.transform.rotation = Quaternion.identity;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
public void Destroy(string typeName, GameObject obj)
|
||||
{
|
||||
Object.Destroy(obj);
|
||||
}
|
||||
|
||||
public void Reset(string typeName, GameObject obj)
|
||||
{
|
||||
obj.SetActive(false);
|
||||
obj.transform.position = Vector3.zero;
|
||||
obj.transform.rotation = Quaternion.identity;
|
||||
}
|
||||
|
||||
public bool Validate(string typeName, GameObject obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 16c8995b85215c6458119d581eea60b0
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -236,6 +236,11 @@ namespace AlicizaX.UI.RecyclerView
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
viewProvider?.Dispose();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
viewProvider?.Reset();
|
||||
|
@ -45,5 +45,6 @@ namespace AlicizaX.UI.RecyclerView
|
||||
public virtual void BindChoiceState(bool state)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
35
Runtime/RecyclerView/ViewHolder/ViewHolderObject.cs
Normal file
35
Runtime/RecyclerView/ViewHolder/ViewHolderObject.cs
Normal file
@ -0,0 +1,35 @@
|
||||
using AlicizaX.ObjectPool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
internal class ViewHolderObject : ObjectBase
|
||||
{
|
||||
public static ViewHolderObject Create(string location, UnityEngine.Object target)
|
||||
{
|
||||
ViewHolderObject item = MemoryPool.Acquire<ViewHolderObject>();
|
||||
item.Initialize(location, target);
|
||||
return item;
|
||||
}
|
||||
|
||||
protected override void OnUnspawn()
|
||||
{
|
||||
base.OnUnspawn();
|
||||
(Target as ViewHolder).gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
protected override void OnSpawn()
|
||||
{
|
||||
base.OnSpawn();
|
||||
(Target as ViewHolder).gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
protected override void Release(bool isShutdown)
|
||||
{
|
||||
if (Target != null)
|
||||
{
|
||||
GameObject.Destroy((Target as ViewHolder).gameObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
3
Runtime/RecyclerView/ViewHolder/ViewHolderObject.cs.meta
Normal file
3
Runtime/RecyclerView/ViewHolder/ViewHolderObject.cs.meta
Normal file
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a241cb39eb24df0ae5db5a7a764dd27
|
||||
timeCreated: 1743476681
|
43
Runtime/RecyclerView/ViewHolder/ViewHolderObjectPool.cs
Normal file
43
Runtime/RecyclerView/ViewHolder/ViewHolderObjectPool.cs
Normal file
@ -0,0 +1,43 @@
|
||||
using AlicizaX.ObjectPool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
internal static class ViewHolderObjectPool
|
||||
{
|
||||
private static readonly IObjectPool<ViewHolderObject> _ObjectPool;
|
||||
private const string OBJECTPOOLNAME = "ViewHolderObjectPool";
|
||||
|
||||
static ViewHolderObjectPool()
|
||||
{
|
||||
_ObjectPool = GameApp.ObjectPool.CreateSingleSpawnObjectPool<ViewHolderObject>(name: OBJECTPOOLNAME, autoReleaseInterval: 60, capacity: 60, expireTime: float.MaxValue, 0);
|
||||
}
|
||||
|
||||
public static ViewHolder Allocate(ViewHolder template, Transform parent)
|
||||
{
|
||||
ViewHolder viewHolder = null;
|
||||
ViewHolderObject viewHolderObject = _ObjectPool.Spawn(template.name);
|
||||
if (viewHolderObject != null)
|
||||
{
|
||||
viewHolder = (ViewHolder)viewHolderObject.Target;
|
||||
}
|
||||
else
|
||||
{
|
||||
viewHolder = UnityEngine.Object.Instantiate(template, parent);
|
||||
_ObjectPool.Register(ViewHolderObject.Create(template.name, viewHolder), true);
|
||||
}
|
||||
|
||||
return viewHolder;
|
||||
}
|
||||
|
||||
public static void Free(ViewHolder viewHolder)
|
||||
{
|
||||
_ObjectPool.Unspawn(viewHolder);
|
||||
}
|
||||
|
||||
public static void Release(ViewHolder viewHolder)
|
||||
{
|
||||
_ObjectPool.ReleaseObject(viewHolder);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cae2bcb0572045019267379f5dab4e23
|
||||
timeCreated: 1743486723
|
@ -1,6 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using AlicizaX.ObjectPool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.UI.RecyclerView
|
||||
@ -10,7 +11,6 @@ namespace AlicizaX.UI.RecyclerView
|
||||
[SerializeField] private ViewHolder chatLeftViewHolder;
|
||||
[SerializeField] private ViewHolder chatRightViewHolder;
|
||||
|
||||
private IMixedObjectPool<ViewHolder> objectPool;
|
||||
private Dictionary<string, ViewHolder> dict = new();
|
||||
|
||||
public MixedViewProvider(RecyclerView recyclerView, ViewHolder[] templates) : base(recyclerView, templates)
|
||||
@ -19,9 +19,6 @@ namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
dict[template.name] = template;
|
||||
}
|
||||
|
||||
UnityMixedComponentFactory<ViewHolder> factory = new(dict, recyclerView.Content);
|
||||
objectPool = new MixedObjectPool<ViewHolder>(factory);
|
||||
}
|
||||
|
||||
public override ViewHolder GetTemplate(string viewName)
|
||||
@ -30,6 +27,7 @@ namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
||||
}
|
||||
|
||||
return dict[viewName];
|
||||
}
|
||||
|
||||
@ -39,25 +37,23 @@ namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
||||
}
|
||||
|
||||
return dict.Values.ToArray();
|
||||
}
|
||||
|
||||
public override ViewHolder Allocate(string viewName)
|
||||
{
|
||||
var viewHolder = objectPool.Allocate(viewName);
|
||||
viewHolder.gameObject.SetActive(true);
|
||||
return viewHolder;
|
||||
return ViewHolderObjectPool.Allocate(GetTemplate(viewName), recyclerView.Content);
|
||||
}
|
||||
|
||||
public override void Free(string viewName, ViewHolder viewHolder)
|
||||
{
|
||||
objectPool.Free(viewName, viewHolder);
|
||||
ViewHolderObjectPool.Free(viewHolder);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Clear();
|
||||
objectPool.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,15 @@
|
||||
using System;
|
||||
using AlicizaX.ObjectPool;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
public sealed class SimpleViewProvider : ViewProvider
|
||||
{
|
||||
private readonly IObjectPool<ViewHolder> objectPool;
|
||||
|
||||
public SimpleViewProvider(RecyclerView recyclerView, ViewHolder[] templates) : base(recyclerView, templates)
|
||||
{
|
||||
UnityComponentFactory<ViewHolder> factory = new(GetTemplate(), recyclerView.Content);
|
||||
objectPool = new ObjectPool<ViewHolder>(factory, 100);
|
||||
|
||||
}
|
||||
|
||||
public override ViewHolder GetTemplate(string viewName = "")
|
||||
@ -18,6 +18,7 @@ namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
||||
}
|
||||
|
||||
return templates[0];
|
||||
}
|
||||
|
||||
@ -27,25 +28,24 @@ namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
||||
}
|
||||
|
||||
return templates;
|
||||
}
|
||||
|
||||
public override ViewHolder Allocate(string viewName)
|
||||
{
|
||||
var viewHolder = objectPool.Allocate();
|
||||
viewHolder.gameObject.SetActive(true);
|
||||
return viewHolder;
|
||||
return ViewHolderObjectPool.Allocate(GetTemplate(),recyclerView.Content);
|
||||
}
|
||||
|
||||
public override void Free(string viewName, ViewHolder viewHolder)
|
||||
{
|
||||
objectPool.Free(viewHolder);
|
||||
ViewHolderObjectPool.Free(viewHolder);
|
||||
}
|
||||
|
||||
public override void Reset()
|
||||
{
|
||||
Clear();
|
||||
objectPool.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using AlicizaX.UI.Runtime;
|
||||
using UnityEngine;
|
||||
|
||||
namespace AlicizaX.UI.RecyclerView
|
||||
@ -6,7 +8,7 @@ namespace AlicizaX.UI.RecyclerView
|
||||
/// <summary>
|
||||
/// 提供和管理 ViewHolder
|
||||
/// </summary>
|
||||
public abstract class ViewProvider
|
||||
public abstract class ViewProvider : IDisposable
|
||||
{
|
||||
private readonly List<ViewHolder> viewHolders = new();
|
||||
|
||||
@ -83,6 +85,7 @@ namespace AlicizaX.UI.RecyclerView
|
||||
return viewHolder;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -100,6 +103,7 @@ namespace AlicizaX.UI.RecyclerView
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -109,6 +113,7 @@ namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
Free(viewHolder.Name, viewHolder);
|
||||
}
|
||||
|
||||
viewHolders.Clear();
|
||||
}
|
||||
|
||||
@ -127,5 +132,16 @@ namespace AlicizaX.UI.RecyclerView
|
||||
{
|
||||
return Adapter == null ? 0 : Adapter.GetItemCount();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
foreach (var viewHolder in viewHolders)
|
||||
{
|
||||
Free(viewHolder.Name, viewHolder);
|
||||
ViewHolderObjectPool.Release(viewHolder);
|
||||
}
|
||||
|
||||
viewHolders.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user