modify
This commit is contained in:
parent
98444eeabb
commit
50bae6cea3
3
Runtime/RecyclerView/ObjectPool.meta
Normal file
3
Runtime/RecyclerView/ObjectPool.meta
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3a9bb27da68d4451a7d79cdb7abc1506
|
||||||
|
timeCreated: 1748431180
|
16
Runtime/RecyclerView/ObjectPool/IMixedObjectFactory.cs
Normal file
16
Runtime/RecyclerView/ObjectPool/IMixedObjectFactory.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
internal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Runtime/RecyclerView/ObjectPool/IMixedObjectFactory.cs.meta
Normal file
11
Runtime/RecyclerView/ObjectPool/IMixedObjectFactory.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 30f89ee61eb3f0949b5300bd9b7cc577
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
12
Runtime/RecyclerView/ObjectPool/IMixedObjectPool.cs
Normal file
12
Runtime/RecyclerView/ObjectPool/IMixedObjectPool.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
|
||||||
|
internal interface IMixedObjectPool<T> : IDisposable where T : class
|
||||||
|
{
|
||||||
|
T Allocate(string typeName);
|
||||||
|
|
||||||
|
void Free(string typeName, T obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Runtime/RecyclerView/ObjectPool/IMixedObjectPool.cs.meta
Normal file
11
Runtime/RecyclerView/ObjectPool/IMixedObjectPool.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3f4c13a4827ebad4a9ff08e636fbc67e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
33
Runtime/RecyclerView/ObjectPool/IObjectFactory.cs
Normal file
33
Runtime/RecyclerView/ObjectPool/IObjectFactory.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
internal 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Runtime/RecyclerView/ObjectPool/IObjectFactory.cs.meta
Normal file
11
Runtime/RecyclerView/ObjectPool/IObjectFactory.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 77a642084db01624c8e5876605195d49
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
27
Runtime/RecyclerView/ObjectPool/IObjectPool.cs
Normal file
27
Runtime/RecyclerView/ObjectPool/IObjectPool.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
|
||||||
|
internal interface IObjectPool : IDisposable
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 从池子中分配一个可用对象,没有的话就创建一个
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
object Allocate();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将对象回收到池子中去,如果池中的对象数量已经超过了 maxSize,则直接销毁该对象
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="obj"></param>
|
||||||
|
void Free(object obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal interface IObjectPool<T> : IObjectPool, IDisposable where T : class
|
||||||
|
{
|
||||||
|
new T Allocate();
|
||||||
|
|
||||||
|
void Free(T obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Runtime/RecyclerView/ObjectPool/IObjectPool.cs.meta
Normal file
11
Runtime/RecyclerView/ObjectPool/IObjectPool.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dd12164a5eea20e41bf7f3b7704f4b33
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
10
Runtime/RecyclerView/ObjectPool/IPooledObject.cs
Normal file
10
Runtime/RecyclerView/ObjectPool/IPooledObject.cs
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
internal interface IPooledObject
|
||||||
|
{
|
||||||
|
void Free();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Runtime/RecyclerView/ObjectPool/IPooledObject.cs.meta
Normal file
11
Runtime/RecyclerView/ObjectPool/IPooledObject.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: b174ccb64b3938c449d4a69a3262d8d5
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
108
Runtime/RecyclerView/ObjectPool/MixedObjectPool.cs
Normal file
108
Runtime/RecyclerView/ObjectPool/MixedObjectPool.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
internal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Runtime/RecyclerView/ObjectPool/MixedObjectPool.cs.meta
Normal file
11
Runtime/RecyclerView/ObjectPool/MixedObjectPool.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 0a62e68f43eac4b419140191eb09ea56
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
112
Runtime/RecyclerView/ObjectPool/ObjectPool.cs
Normal file
112
Runtime/RecyclerView/ObjectPool/ObjectPool.cs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
internal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
Runtime/RecyclerView/ObjectPool/ObjectPool.cs.meta
Normal file
11
Runtime/RecyclerView/ObjectPool/ObjectPool.cs.meta
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 30999e5e03e2b434996100b09960468f
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
40
Runtime/RecyclerView/ObjectPool/UnityComponentFactory.cs
Normal file
40
Runtime/RecyclerView/ObjectPool/UnityComponentFactory.cs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
internal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 3e2e3a0444783a7469d494ad630dc705
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
39
Runtime/RecyclerView/ObjectPool/UnityGameObjectFactory.cs
Normal file
39
Runtime/RecyclerView/ObjectPool/UnityGameObjectFactory.cs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
internal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 7373bce96f2a515499c52b060ad9e01e
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,65 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
internal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 5c2d58d006be3fc458b8c6761d76bc88
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -0,0 +1,44 @@
|
|||||||
|
namespace SimpleObjectPool
|
||||||
|
{
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
internal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
fileFormatVersion: 2
|
||||||
|
guid: 16c8995b85215c6458119d581eea60b0
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
@ -1,35 +0,0 @@
|
|||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: 6a241cb39eb24df0ae5db5a7a764dd27
|
|
||||||
timeCreated: 1743476681
|
|
@ -1,43 +0,0 @@
|
|||||||
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: 60 * 3, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
fileFormatVersion: 2
|
|
||||||
guid: cae2bcb0572045019267379f5dab4e23
|
|
||||||
timeCreated: 1743486723
|
|
@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using AlicizaX.ObjectPool;
|
using SimpleObjectPool;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
|
||||||
namespace AlicizaX.UI.RecyclerView
|
namespace AlicizaX.UI.RecyclerView
|
||||||
@ -11,6 +11,7 @@ namespace AlicizaX.UI.RecyclerView
|
|||||||
[SerializeField] private ViewHolder chatLeftViewHolder;
|
[SerializeField] private ViewHolder chatLeftViewHolder;
|
||||||
[SerializeField] private ViewHolder chatRightViewHolder;
|
[SerializeField] private ViewHolder chatRightViewHolder;
|
||||||
|
|
||||||
|
private IMixedObjectPool<ViewHolder> objectPool;
|
||||||
private Dictionary<string, ViewHolder> dict = new();
|
private Dictionary<string, ViewHolder> dict = new();
|
||||||
|
|
||||||
public MixedViewProvider(RecyclerView recyclerView, ViewHolder[] templates) : base(recyclerView, templates)
|
public MixedViewProvider(RecyclerView recyclerView, ViewHolder[] templates) : base(recyclerView, templates)
|
||||||
@ -19,6 +20,9 @@ namespace AlicizaX.UI.RecyclerView
|
|||||||
{
|
{
|
||||||
dict[template.name] = template;
|
dict[template.name] = template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnityMixedComponentFactory<ViewHolder> factory = new(dict, recyclerView.Content);
|
||||||
|
objectPool = new MixedObjectPool<ViewHolder>(factory);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ViewHolder GetTemplate(string viewName)
|
public override ViewHolder GetTemplate(string viewName)
|
||||||
@ -27,7 +31,6 @@ namespace AlicizaX.UI.RecyclerView
|
|||||||
{
|
{
|
||||||
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return dict[viewName];
|
return dict[viewName];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,23 +40,25 @@ namespace AlicizaX.UI.RecyclerView
|
|||||||
{
|
{
|
||||||
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return dict.Values.ToArray();
|
return dict.Values.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ViewHolder Allocate(string viewName)
|
public override ViewHolder Allocate(string viewName)
|
||||||
{
|
{
|
||||||
return ViewHolderObjectPool.Allocate(GetTemplate(viewName), recyclerView.Content);
|
var viewHolder = objectPool.Allocate(viewName);
|
||||||
|
viewHolder.gameObject.SetActive(true);
|
||||||
|
return viewHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Free(string viewName, ViewHolder viewHolder)
|
public override void Free(string viewName, ViewHolder viewHolder)
|
||||||
{
|
{
|
||||||
ViewHolderObjectPool.Free(viewHolder);
|
objectPool.Free(viewName, viewHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
|
objectPool.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,16 @@
|
|||||||
using System;
|
using System;
|
||||||
using AlicizaX.ObjectPool;
|
using SimpleObjectPool;
|
||||||
using UnityEngine;
|
|
||||||
|
|
||||||
namespace AlicizaX.UI.RecyclerView
|
namespace AlicizaX.UI.RecyclerView
|
||||||
{
|
{
|
||||||
public sealed class SimpleViewProvider : ViewProvider
|
public sealed class SimpleViewProvider : ViewProvider
|
||||||
{
|
{
|
||||||
|
private readonly IObjectPool<ViewHolder> objectPool;
|
||||||
|
|
||||||
public SimpleViewProvider(RecyclerView recyclerView, ViewHolder[] templates) : base(recyclerView, templates)
|
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 = "")
|
public override ViewHolder GetTemplate(string viewName = "")
|
||||||
@ -18,7 +19,6 @@ namespace AlicizaX.UI.RecyclerView
|
|||||||
{
|
{
|
||||||
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return templates[0];
|
return templates[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,24 +28,25 @@ namespace AlicizaX.UI.RecyclerView
|
|||||||
{
|
{
|
||||||
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
throw new NullReferenceException("ViewProvider templates can not null or empty.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return templates;
|
return templates;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ViewHolder Allocate(string viewName)
|
public override ViewHolder Allocate(string viewName)
|
||||||
{
|
{
|
||||||
return ViewHolderObjectPool.Allocate(GetTemplate(),recyclerView.Content);
|
var viewHolder = objectPool.Allocate();
|
||||||
|
viewHolder.gameObject.SetActive(true);
|
||||||
|
return viewHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Free(string viewName, ViewHolder viewHolder)
|
public override void Free(string viewName, ViewHolder viewHolder)
|
||||||
{
|
{
|
||||||
ViewHolderObjectPool.Free(viewHolder);
|
objectPool.Free(viewHolder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Reset()
|
public override void Reset()
|
||||||
{
|
{
|
||||||
Clear();
|
Clear();
|
||||||
}
|
objectPool.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,6 @@ namespace AlicizaX.UI.RecyclerView
|
|||||||
foreach (var viewHolder in viewHolders)
|
foreach (var viewHolder in viewHolders)
|
||||||
{
|
{
|
||||||
Free(viewHolder.Name, viewHolder);
|
Free(viewHolder.Name, viewHolder);
|
||||||
ViewHolderObjectPool.Release(viewHolder);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
viewHolders.Clear();
|
viewHolders.Clear();
|
||||||
|
Loading…
Reference in New Issue
Block a user