// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 Kybernetik //
using System;
using System.Reflection;
#if UNITY_EDITOR
using Animancer.Editor;
using UnityEditor;
#endif
namespace Animancer
{
/// [Editor-Conditional] Specifies the default value of a field and a secondary fallback.
/// https://kybernetik.com.au/animancer/api/Animancer/DefaultValueAttribute
///
[AttributeUsage(AttributeTargets.Field)]
[System.Diagnostics.Conditional(Strings.UnityEditor)]
public class DefaultValueAttribute : Attribute
{
/************************************************************************************************************************/
/// The main default value.
public virtual object Primary { get; protected set; }
/************************************************************************************************************************/
/// The fallback value to use if the target value was already equal to the .
public virtual object Secondary { get; protected set; }
/************************************************************************************************************************/
/// Creates a new .
public DefaultValueAttribute(object primary, object secondary = null)
{
Primary = primary;
Secondary = secondary;
}
/************************************************************************************************************************/
/// Creates a new .
protected DefaultValueAttribute() { }
/************************************************************************************************************************/
#if UNITY_EDITOR
/************************************************************************************************************************/
/// [Editor-Only]
/// If the field represented by the `property` has a , this method sets
/// the `value` to its value. If it was already at the value, it sets it to the
/// value instead. And if the field has no attribute, it uses the default for the type.
///
public static void SetToDefault(ref T value, SerializedProperty property)
{
var accessor = property.GetAccessor();
var field = accessor.GetField(property);
if (field == null)
accessor.SetValue(property, null);
else
SetToDefault(ref value, field);
}
/************************************************************************************************************************/
/// [Editor-Only]
/// If the field represented by the `property` has a , this method sets
/// the `value` to its value. If it was already at the value, it sets it to the
/// value instead. And if the field has no attribute, it uses the default for the type.
///
public static void SetToDefault(ref T value, FieldInfo field)
{
var defaults = field.GetAttribute();
if (defaults != null)
defaults.SetToDefault(ref value);
else
value = default;
}
/************************************************************************************************************************/
/// [Editor-Only]
/// Sets the `value` equal to the value. If it was already at the value, it sets it equal
/// to the value instead.
///
public void SetToDefault(ref T value)
{
var primary = Primary;
if (!Equals(value, primary))
{
value = (T)primary;
return;
}
var secondary = Secondary;
if (secondary != null || !typeof(T).IsValueType)
{
value = (T)secondary;
return;
}
}
/************************************************************************************************************************/
/// [Editor-Only]
/// Sets the `value` equal to the `primary` value. If it was already at the value, it sets it equal to the
/// `secondary` value instead.
///
public static void SetToDefault(ref T value, T primary, T secondary)
{
if (!Equals(value, primary))
value = primary;
else
value = secondary;
}
/************************************************************************************************************************/
#endif
/************************************************************************************************************************/
}
}