using System; using System.Collections.Generic; using UnityEngine; namespace UIWidgets { public class Templates where T : MonoBehaviour, ITemplatable { private Dictionary templates = new Dictionary(); private Dictionary> cache = new Dictionary>(); private bool findTemplatesCalled; private Action onCreateCallback; public Templates(Action onCreateCallback = null) { this.onCreateCallback = onCreateCallback; } public void FindTemplates() { findTemplatesCalled = true; Resources.FindObjectsOfTypeAll().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(); } cache[instance.TemplateName].Push(instance); } } }