using System;
using System.Collections.Generic;
using UnityEngine;
public class Pool : MonoBehaviour
{
public static Pool Instance;
[SerializeField]
private List<PoolTable> items = new List<PoolTable>();
private Dictionary<GameObject, PoolTable> overriddenPoolTables = new Dictionary<GameObject, PoolTable>();
private Dictionary<GameObject, PoolInstance> poolInstances = new Dictionary<GameObject, PoolInstance>();
private Dictionary<GameObject, PoolTable> poolTables = new Dictionary<GameObject, PoolTable>();
public Preallocation[] preallocations;
private void Awake()
{
Instance = this;
foreach (Preallocation preallocation in this.preallocations)
{
this.DoPreallocate(preallocation.prefab, preallocation.count);
}
}
public static void Despawn(GameObject obj)
{
if (Instance != null)
{
Instance.DoDespawn(obj);
}
}
public static void Despawn<T>(T obj) where T: Component
{
if (Instance != null)
{
Instance.DoDespawn(obj.gameObject);
}
}
public static void DespawnAll()
{
if (Instance != null)
{
Instance.DoDespawnAll();
}
}
private void DoDespawn(GameObject obj)
{
PoolInstance instance;
if (this.poolInstances.TryGetValue(obj, out instance))
{
PoolTable table = instance.Table;
if (table != null)
{
instance.InUse = false;
table.Despawn(obj);
base.enabled = true;
return;
}
}
UnityEngine.Object.Destroy(obj);
}
private void DoDespawnAll()
{
foreach (KeyValuePair<GameObject, PoolInstance> pair in this.poolInstances)
{
PoolInstance instance = pair.Value;
if (instance.Table != null)
{
instance.InUse = false;
instance.Table.Despawn(pair.Key);
}
}
base.enabled = true;
}
private void DoPreallocate(GameObject prefab, int count)
{
this.GetOrCreateTable(prefab).Preallocate(count);
}
private void DoReplace(GameObject prefab, GameObject otherPrefab)
{
PoolTable table;
if (!this.poolTables.TryGetValue(prefab, out table))
{
Debug.LogError("Prefab does not exist to replace: " + prefab.name + " with: " + otherPrefab.name);
}
else if (table.Prefab != otherPrefab)
{
PoolTable table2;
foreach (KeyValuePair<GameObject, PoolInstance> pair in this.poolInstances)
{
if (pair.Value.Table == table)
{
pair.Value.InUse = false;
table.Despawn(pair.Key);
}
}
Instance.enabled = true;
if (this.overriddenPoolTables.TryGetValue(otherPrefab, out table2))
{
this.overriddenPoolTables.Remove(otherPrefab);
}
else
{
table2 = new PoolTable(otherPrefab);
this.items.Add(table2);
table2.Preallocate(table.ActiveCount + table.FreeCount);
}
this.overriddenPoolTables[table.Prefab] = table;
this.poolTables[prefab] = table2;
}
}
private GameObject DoSpawn(GameObject prefab, Vector3 position, Quaternion rotation)
{
base.enabled = true;
PoolTable orCreateTable = this.GetOrCreateTable(prefab);
GameObject instance = orCreateTable.Spawn(position, rotation);
this.poolInstances[instance] = new PoolInstance(instance, true, orCreateTable);
return instance;
}
public int GetActiveCount(GameObject prefab)
{
PoolTable table;
if (this.poolTables.TryGetValue(prefab, out table))
{
return table.ActiveCount;
}
return 0;
}
private PoolTable GetOrCreateTable(GameObject prefab)
{
PoolTable table;
if (!this.poolTables.TryGetValue(prefab, out table))
{
table = new PoolTable(prefab);
this.poolTables[prefab] = table;
this.items.Add(table);
}
return table;
}
public PoolInstance GetPoolInstance(GameObject obj)
{
PoolInstance instance;
this.poolInstances.TryGetValue(obj, out instance);
return instance;
}
public static PoolTable GetTable(GameObject prefab)
{
return ((Instance == null) ? null : Instance.GetOrCreateTable(prefab));
}
private void LateUpdate()
{
foreach (PoolTable table in this.items)
{
table.Update();
}
base.enabled = false;
}
public static void Replace(GameObject prefab, GameObject otherPrefab)
{
if (Instance != null)
{
Instance.DoReplace(prefab, otherPrefab);
}
}
public static void Revert(GameObject prefab)
{
if (Instance != null)
{
Instance.DoReplace(prefab, prefab);
}
}
public static GameObject Spawn(GameObject prefab)
{
return ((Instance == null) ? null : Instance.DoSpawn(prefab, Vector3.zero, Quaternion.identity));
}
public static T Spawn<T>(T prefab) where T: Component
{
if (Instance != null)
{
GameObject obj2 = Instance.DoSpawn(prefab.gameObject, Vector3.zero, Quaternion.identity);
if (obj2 != null)
{
return obj2.GetComponent<T>();
}
}
return null;
}
public static GameObject Spawn(GameObject prefab, Vector3 position, Quaternion rotation)
{
return ((Instance == null) ? null : Instance.DoSpawn(prefab, position, rotation));
}
public static T Spawn<T>(T prefab, Vector3 position, Quaternion rotation) where T: Component
{
if (Instance != null)
{
GameObject obj2 = Instance.DoSpawn(prefab.gameObject, position, rotation);
if (obj2 != null)
{
return obj2.GetComponent<T>();
}
}
return null;
}
public List<PoolTable> Items
{
get
{
return this.items;
}
}
[Serializable]
public class Preallocation
{
public int count;
public GameObject prefab;
}
}