#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