#if UNITY_EDITOR using DTT.Utils.Exceptions; using DTT.Utils.Optimization; using System; using System.Collections.Generic; using UnityEditor; namespace DTT.Utils.EditorUtilities { /// /// Provides storage of 's from a instance, /// creating them when they are first used. It also provides access to them by property name /// instead of by magic string. /// public class SerializedPropertyCache : LazyDictionaryBase { #region Variables #region Protected /// /// The object used for initializing property values the first time. /// protected SerializedObject p_serializedObject; #endregion #region Private /// /// The stored properties, accessable by name. /// private Dictionary _properties = new Dictionary(); /// /// The prefix used for private variables. /// private const string PRIVATE_PREFIX = "_"; #endregion #endregion #region Constructors /// /// Creates a new instance, initializing the stored properties /// of the given . /// /// The object of which to store the properties. public SerializedPropertyCache(SerializedObject serializedObject) { if (serializedObject == null) throw new LazyDictionaryException("Serialized object can't be null"); p_serializedObject = serializedObject; } #endregion #region Methods #region Public /// /// Updates the serialized object representation. Call this before drawing /// your properties and eventuall changes. /// public void UpdateRepresentation() => p_serializedObject.Update(); /// /// Applies modified changes of properties to the serialized object. /// Call this after a has returned true. /// public void ApplyChanges() => p_serializedObject.ApplyModifiedProperties(); #endregion #region Protected /// /// Tries retrieving a property value from the cache based on given name. /// /// The property name. /// The property value. protected override SerializedProperty GetValue(string nameOfProperty) { // Null or empty property names aren't allowed. if (string.IsNullOrEmpty(nameOfProperty)) throw new NullReferenceException($"Property name is null or empty."); if (!_properties.ContainsKey(nameOfProperty)) { // Find a property using the given name. SerializedProperty property = p_serializedObject.FindProperty(nameOfProperty); if (property == null) { // If the property wasn't found, try finding it might be using a private prefix. string privatePrefixed = PRIVATE_PREFIX + nameOfProperty; property = p_serializedObject.FindProperty(privatePrefixed); if (property == null) throw new InvalidOperationException($"{nameOfProperty} and {privatePrefixed} don't match a property."); } _properties.Add(nameOfProperty, property); } return _properties[nameOfProperty]; } #endregion #endregion } } #endif