Advertisement
lunoland

MonoBehaviourWrapper

Aug 15th, 2018
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.67 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using UnityEngine;
  5.  
  6. public class MonoBehaviourWrapper : MonoBehaviour {
  7.  
  8.     #region Fields
  9.     static Dictionary<GameObject, Dictionary<Type, Component>> components;
  10.  
  11.     public bool debug;
  12.  
  13.     bool thisComponentWasDestroyed;
  14.  
  15.     /// Override this property to change whether or not this component and its game object should be cached on awake (default is true).
  16.     protected virtual bool CacheOnAwake { get { return true; } }
  17.     #endregion
  18.  
  19.  
  20.     #region Unity Magic
  21.     protected virtual void Awake() {
  22.         if (components == null) { components = new Dictionary<GameObject, Dictionary<Type, Component>>(); }
  23.         if (CacheOnAwake) { Cache(this.GetType(), this); }
  24.     }
  25.  
  26.     protected virtual void OnDestroy() {
  27.         if (thisComponentWasDestroyed) {
  28.             Component[] wrappers = GetComponents(typeof(MonoBehaviourWrapper));
  29.             if ( !(wrappers.Length == 1 && wrappers[0] == this) ) { return; }
  30.         }
  31.  
  32.         components.Remove(gameObject);
  33.     }
  34.     #endregion
  35.  
  36.  
  37.     #region Methods
  38.     public void Cache<T>(Component component) where T : Component { Cache(typeof(T), component); }
  39.     public void Cache(Type type, Component component) {
  40.        
  41.         Dictionary<Type, Component> cache;
  42.         if (components.TryGetValue(gameObject, out cache)) {
  43.             if (cache.ContainsKey(type))
  44.                 cache[type] = component;
  45.             else
  46.                 cache.Add(type, component);
  47.         }
  48.         else {
  49.             components.Add(gameObject, new Dictionary<Type, Component>() { { type, component } });
  50.         }
  51.     }
  52.  
  53.     public T Add<T>() where T : Component { return (T)Add(typeof(T)); }
  54.     public Component Add(Type type) {
  55.         Component component = gameObject.AddComponent(type);
  56.  
  57.         Dictionary<Type, Component> cache;
  58.         if (components.TryGetValue(gameObject, out cache))
  59.             cache.Add(type, component);
  60.         else
  61.             components.Add(gameObject, new Dictionary<Type, Component>() { { type, component } });
  62.                
  63.         return component;
  64.     }
  65.  
  66.     public bool Remove<T>() where T : Component { return Remove(typeof(T)); }
  67.     public bool Remove(Type type) {
  68.         Component component = null;
  69.  
  70.         Dictionary<Type, Component> cache;
  71.         if (components.TryGetValue(gameObject, out cache)) {
  72.  
  73.             if (cache.TryGetValue(type, out component))
  74.                 cache.Remove(type);
  75.         }
  76.         else {
  77.             components.Add(gameObject, new Dictionary<Type, Component>());
  78.         }
  79.  
  80.         if (component == null) { component = GetComponent(type); }
  81.  
  82.         if (component != null) {
  83.             thisComponentWasDestroyed = component == this;
  84.             Destroy(component);
  85.             return true;
  86.         }
  87.         else {
  88.             return false;
  89.         }
  90.     }
  91.  
  92.     /// Uses GetComponent to find the component, and then caches the result. Subsequent
  93.     /// calls will return the cached version. Returns null if the component does not exist.
  94.     public T Get<T>() where T : Component { return (T)Get(typeof(T)); }
  95.     public Component Get(Type type) {
  96.         Component component;
  97.  
  98.         Dictionary<Type, Component> cache;
  99.         if (components.TryGetValue(gameObject, out cache)) {
  100.  
  101.             if (cache.TryGetValue(type, out component)) {
  102.                 if (component == null) { cache.Remove(type); }
  103.                 return component;
  104.             }
  105.         }
  106.         else {
  107.             cache = new Dictionary<Type, Component>();
  108.             components.Add(gameObject, cache);
  109.         }
  110.  
  111.         component = GetComponent(type);
  112.  
  113.         if (component != null)
  114.             cache.Add(type, component);
  115.  
  116.         return component;
  117.     }
  118.  
  119.     /// Uses GetComponent to check whether or not this GameObject has a particular component,
  120.     /// and caches any non-null result in the process.
  121.     public bool Has<T>() where T : Component { return Has(typeof(T)); }
  122.     public bool Has(Type type) {
  123.         Component component;
  124.  
  125.         Dictionary<Type, Component> cache;
  126.         if (components.TryGetValue(gameObject, out cache)) {
  127.  
  128.             if (cache.TryGetValue(type, out component)) {
  129.                 if (component == null) {
  130.                     cache.Remove(type);
  131.                     return false;
  132.                 }
  133.  
  134.                 return true;
  135.             }
  136.         }
  137.         else {
  138.             cache = new Dictionary<Type, Component>();
  139.             components.Add(gameObject, cache);
  140.         }
  141.  
  142.         component = GetComponent(type);
  143.  
  144.         if (component != null) {
  145.             cache.Add(type, component);
  146.             return true;
  147.         }
  148.  
  149.         return false;
  150.     }
  151.  
  152.     public string DumpCachedComponents() {
  153.         Dictionary<Type, Component> cache;
  154.         if (!components.TryGetValue(gameObject, out cache)) { return ""; }
  155.  
  156.         System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
  157.         stringBuilder.Append(string.Concat(gameObject.name, " components = {"));
  158.         if (cache.Count == 0) { stringBuilder.Append(" }"); }
  159.  
  160.         int i = 1;
  161.         foreach (KeyValuePair<Type, Component> entry in cache) {
  162.             stringBuilder.Append(string.Concat("\n\t", entry.Key.ToString(), " => ", entry.Value.ToString()));
  163.  
  164.             if (i < cache.Count)
  165.                 stringBuilder.Append(", ");
  166.             else
  167.                 stringBuilder.Append("\n}");
  168.  
  169.             i++;
  170.         }
  171.  
  172.         return stringBuilder.ToString();
  173.     }
  174.  
  175.     public static string DumpAllCachedComponents() {
  176.         System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder();
  177.  
  178.         stringBuilder.Append("components = {");
  179.         if (components.Count == 0) { stringBuilder.Append(" }"); }
  180.  
  181.         int i = 1;
  182.         foreach (KeyValuePair<GameObject, Dictionary<Type, Component>> cache in components) {
  183.             stringBuilder.Append(string.Concat("\n\t", cache.Key.name, " => {"));
  184.             if (cache.Value.Count == 0) { stringBuilder.Append(" }"); }
  185.  
  186.             int j = 1;
  187.             foreach (KeyValuePair<Type, Component> component in cache.Value) {
  188.  
  189.                 stringBuilder.Append(string.Concat("\n\t\t", component.Key.ToString(), " => ", component.Value.ToString()));
  190.  
  191.                 if (j < cache.Value.Count)
  192.                     stringBuilder.Append(',');
  193.                 else
  194.                     stringBuilder.Append("\n\t}");
  195.                
  196.                 j++;
  197.             }
  198.  
  199.             if (i < components.Count)
  200.                 stringBuilder.Append(',');
  201.             else
  202.                 stringBuilder.Append("\n}");
  203.            
  204.             i++;
  205.         }
  206.  
  207.         return stringBuilder.ToString();
  208.     }
  209.     #endregion
  210. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement