#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 implementations access to them by property name /// instead of by magic string. /// public class RelativePropertyCache : LazyDictionaryBase { #region Variables #region Protected /// /// The property used for initializing relative property values the first time. /// protected SerializedProperty p_serializedProperty; #endregion #region Private /// /// The stored properties, accessable by name. /// private Dictionary _relativeProperties = 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 RelativePropertyCache(SerializedProperty serializedProperty) { if (serializedProperty == null) throw new LazyDictionaryException("Serialized property can't be null"); p_serializedProperty = serializedProperty; } #endregion #region Methods #region Public /// /// Updates the serialized object representation. Call this before drawing /// your properties and eventuall changes. /// public void UpdateObjectRepresentation() => p_serializedProperty.serializedObject.Update(); /// /// Applies modified changes of properties to the serialized object. /// Call this after a has returned true. /// public void ApplyChangesToObject() => p_serializedProperty.serializedObject.ApplyModifiedProperties(); #endregion #region Protected /// /// Tries retrieving a relative 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 (!_relativeProperties.ContainsKey(nameOfProperty)) { // Find a property using the given name. SerializedProperty property = p_serializedProperty.FindPropertyRelative(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_serializedProperty.FindPropertyRelative(privatePrefixed); if (property == null) throw new InvalidOperationException($"{nameOfProperty} and {privatePrefixed} don't match a property."); } _relativeProperties.Add(nameOfProperty, property); } return _relativeProperties[nameOfProperty]; } #endregion #endregion } } #endif