Skip to content

Instantly share code, notes, and snippets.

@Naphier
Last active February 1, 2016 09:36
Show Gist options
  • Save Naphier/bddd14f1f42a0815baa5 to your computer and use it in GitHub Desktop.
Save Naphier/bddd14f1f42a0815baa5 to your computer and use it in GitHub Desktop.
CacheBehaviour alternative
using UnityEngine;
using System.Collections.Generic;
public class ComponentCache
{
public enum LogMessageLevel { all, error, none}
LogMessageLevel logMessageLevel = LogMessageLevel.error;
private GameObject _gameObject;
private List<Component> _components = new List<Component>();
public ComponentCache(GameObject gameObject)
{
_gameObject = gameObject;
}
public ComponentCache(GameObject gameObject , LogMessageLevel messageLevel)
{
_gameObject = gameObject;
logMessageLevel = messageLevel;
}
public T GetComponent<T>() where T : Component
{
for (int i = 0; i < _components.Count; i++)
{
if (_components[i].GetType() == typeof(T))
{
Log(typeof(T).Name + " found in cache.");
return _components[i] as T;
}
}
Component c = _gameObject.GetComponent<T>();
if (c != null)
{
Log(typeof(T).Name + " added to cache.");
_components.Add(c);
return c as T;
}
LogError(typeof(T).Name + " not found.");
return null;
}
public void DestroyAllComponentsOfType<T>() where T : Component
{
bool destroyed = false;
for (int i = 0; i < _components.Count; i++)
{
if (_components[i].GetType() == typeof(T))
{
Log(typeof(T).Name + " removed from cache and destroyed.");
Object.DestroyImmediate(_components[i]);
_components.RemoveAt(i);
destroyed = true;
}
}
if (!destroyed)
LogError(typeof(T).Name + " not found.");
}
public void DestroyComponent(Component component)
{
bool destroyed = false;
for (int i = 0; i < _components.Count; i++)
{
if (_components[i] == component)
{
Log(component.GetType().Name + " removed from cache and destroyed.");
Object.DestroyImmediate(_components[i]);
_components.RemoveAt(i);
destroyed = true;
}
}
if (!destroyed)
LogError(component.GetType().Name + " not found.");
}
void Log(string message)
{
if (logMessageLevel == LogMessageLevel.all)
Debug.Log(message);
}
void LogError(string message)
{
if (logMessageLevel != LogMessageLevel.none)
Debug.LogError(message);
}
}
// Test Case
/*
using UnityEngine;
using UnityEngine.Assertions;
public class TestCacheComponent : MonoBehaviour
{
public ComponentCache cc;
AudioSource asrc1;
void Start()
{
cc = new ComponentCache(gameObject , ComponentCache.LogMessageLevel.all);
Debug.LogWarning("Test Cache");
cc.GetComponent<AudioSource>();
cc.GetComponent<AudioSource>();
cc.DestroyAllComponentsOfType<AudioSource>();
Debug.LogWarning("Add component test");
asrc1 = gameObject.AddComponent<AudioSource>();
asrc1.mute = true;
AudioSource testAs = cc.GetComponent<AudioSource>();
if (testAs != asrc1)
Debug.LogError("Retrieved component not the same?");
testAs = cc.GetComponent<AudioSource>();
if (testAs != asrc1)
Debug.LogError("Retrieved component not the same?");
Debug.LogWarning("Adding second component");
AudioSource asrc2 = gameObject.AddComponent<AudioSource>();
Debug.LogWarning("Destroying first component");
cc.DestroyComponent(asrc1);
cc.GetComponent<AudioSource>();
cc.GetComponent<AudioSource>();
Assert.IsNull(asrc1);
Assert.IsNotNull(asrc2);
}
bool doOnce = true;
void Update()
{
if (doOnce && asrc1 == null)
{
doOnce = false;
Debug.LogWarning("AudioSource 1 is now null");
}
}
}
*/
@paveltimofeev
Copy link

Why you didn't use hashtable? Getting records from it much more quicker than from List.
And what about cases, when GameObject has more than one component of particular type?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment