You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

140 lines
3.0 KiB

using System;
using System.Collections.Generic;
using UnityEngine;
public interface IMonoObjectPool<T> where T : MonoBehaviour
{
IReadOnlyCollection<T> Instances { get; }
void Initialize(Func<T> creator, Action<T> disposer, Action<T> onEnterPool, Action<T> onExitPool, int count);
T Get();
void Return(T obj);
void Dispose();
}
public class FixedMonoObjectPool<T> : IMonoObjectPool<T> where T : MonoBehaviour
{
Action<T> disposer;
HashSet<T> instances = new();
Queue<T> pool = new();
Action<T> onEnterPool;
Action<T> onExitPool;
public IReadOnlyCollection<T> Instances => instances;
public void Initialize(Func<T> creator, Action<T> disposer, Action<T> onEnterPool, Action<T> onExitPool, int count)
{
this.disposer = disposer;
this.onEnterPool = onEnterPool;
this.onExitPool = onExitPool;
for (int i = 0; i < count; ++i)
{
T obj = creator.Invoke();
onEnterPool.Invoke(obj);
instances.Add(obj);
pool.Enqueue(obj);
}
}
public T Get()
{
Debug.Assert(pool.Count > 0, "pool is empty");
var result = pool.Dequeue();
onExitPool.Invoke(result);
return result;
}
public void Return(T obj)
{
if(instances.Contains(obj))
{
onEnterPool.Invoke(obj);
pool.Enqueue(obj);
}
}
public void Dispose()
{
pool.Clear();
foreach (var obj in instances)
{
disposer.Invoke(obj);
}
instances.Clear();
}
}
public class DynamicMonoObjectPool<T> : IMonoObjectPool<T> where T : MonoBehaviour
{
Func<T> creator;
Action<T> disposer;
HashSet<T> instances = new();
Queue<T> pool = new();
Action<T> onEnterPool;
Action<T> onExitPool;
public IReadOnlyCollection<T> Instances => instances;
public void Initialize(Func<T> creator, Action<T> disposer, Action<T> onEnterPool, Action<T> onExitPool, int count = 0)
{
this.creator = creator;
this.disposer = disposer;
this.onEnterPool = onEnterPool;
this.onExitPool = onExitPool;
for (int i = 0; i < count; ++i)
{
T obj = creator.Invoke();
onEnterPool.Invoke(obj);
instances.Add(obj);
pool.Enqueue(obj);
}
}
public T Get()
{
if (pool.Count == 0)
{
T obj = creator.Invoke();
instances.Add(obj);
pool.Enqueue(obj);
}
var result = pool.Dequeue();
onExitPool.Invoke(result);
return result;
}
public void Return(T obj)
{
if(instances.Contains(obj))
{
onEnterPool.Invoke(obj);
pool.Enqueue(obj);
}
}
public void Dispose()
{
pool.Clear();
foreach (var obj in instances)
{
disposer.Invoke(obj);
}
instances.Clear();
}
}