146 lines
2.9 KiB
C#
146 lines
2.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace UIWidgets
|
|
{
|
|
public class Templates<T> where T : MonoBehaviour, ITemplatable
|
|
{
|
|
private Dictionary<string, T> templates = new Dictionary<string, T>();
|
|
|
|
private Dictionary<string, Stack<T>> cache = new Dictionary<string, Stack<T>>();
|
|
|
|
private bool findTemplatesCalled;
|
|
|
|
private Action<T> onCreateCallback;
|
|
|
|
public Templates(Action<T> onCreateCallback = null)
|
|
{
|
|
this.onCreateCallback = onCreateCallback;
|
|
}
|
|
|
|
public void FindTemplates()
|
|
{
|
|
findTemplatesCalled = true;
|
|
Resources.FindObjectsOfTypeAll<T>().ForEach(AddTemplate);
|
|
}
|
|
|
|
private void AddTemplate(T template)
|
|
{
|
|
Add(template.name, template);
|
|
template.gameObject.SetActive(false);
|
|
}
|
|
|
|
public void ClearCache()
|
|
{
|
|
cache.Keys.ForEach(ClearCache);
|
|
}
|
|
|
|
public void ClearCache(string name)
|
|
{
|
|
if (cache.ContainsKey(name))
|
|
{
|
|
cache[name].ForEach(DestroyCached);
|
|
cache[name].Clear();
|
|
cache[name].TrimExcess();
|
|
}
|
|
}
|
|
|
|
private void DestroyCached(T cached)
|
|
{
|
|
if (cached != null && cached.gameObject != null)
|
|
{
|
|
UnityEngine.Object.Destroy(cached.gameObject);
|
|
}
|
|
}
|
|
|
|
public bool Exists(string name)
|
|
{
|
|
return templates.ContainsKey(name);
|
|
}
|
|
|
|
public T Get(string name)
|
|
{
|
|
if (!Exists(name))
|
|
{
|
|
throw new ArgumentException("Not found template with name '" + name + "'");
|
|
}
|
|
return templates[name];
|
|
}
|
|
|
|
public void Delete(string name)
|
|
{
|
|
if (Exists(name))
|
|
{
|
|
templates.Remove(name);
|
|
ClearCache(name);
|
|
}
|
|
}
|
|
|
|
public void Add(string name, T template, bool replace = true)
|
|
{
|
|
if (Exists(name))
|
|
{
|
|
if (!replace)
|
|
{
|
|
throw new ArgumentException("Template with name '" + name + "' already exists.");
|
|
}
|
|
ClearCache(name);
|
|
templates[name] = template;
|
|
}
|
|
else
|
|
{
|
|
templates.Add(name, template);
|
|
}
|
|
template.IsTemplate = true;
|
|
template.TemplateName = name;
|
|
}
|
|
|
|
public T Instance(string name)
|
|
{
|
|
if (!findTemplatesCalled)
|
|
{
|
|
FindTemplates();
|
|
}
|
|
if (!Exists(name))
|
|
{
|
|
throw new ArgumentException("Not found template with name '" + name + "'");
|
|
}
|
|
if (templates[name] == null)
|
|
{
|
|
templates.Clear();
|
|
FindTemplates();
|
|
}
|
|
T val;
|
|
if (cache.ContainsKey(name) && cache[name].Count > 0)
|
|
{
|
|
val = cache[name].Pop();
|
|
}
|
|
else
|
|
{
|
|
val = UnityEngine.Object.Instantiate(templates[name]);
|
|
val.TemplateName = name;
|
|
val.IsTemplate = false;
|
|
if (onCreateCallback != null)
|
|
{
|
|
onCreateCallback(val);
|
|
}
|
|
}
|
|
Transform transform = val.transform;
|
|
T val2 = templates[name];
|
|
transform.SetParent(val2.transform.parent, false);
|
|
return val;
|
|
}
|
|
|
|
public void ToCache(T instance)
|
|
{
|
|
instance.gameObject.SetActive(false);
|
|
if (!cache.ContainsKey(instance.TemplateName))
|
|
{
|
|
cache[instance.TemplateName] = new Stack<T>();
|
|
}
|
|
cache[instance.TemplateName].Push(instance);
|
|
}
|
|
}
|
|
}
|