123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511 |
- using System;
- using System.Linq;
- using UnityEngine.Assertions;
- namespace UnityEngine.Rendering
- {
- public partial class DebugUI
- {
- /// <summary>
- /// Generic field - will be serialized in the editor if it's not read-only
- /// </summary>
- /// <typeparam name="T"></typeparam>
- public abstract class Field<T> : Widget, IValueField
- {
- /// <summary>
- /// Getter for this field.
- /// </summary>
- public Func<T> getter { get; set; }
- /// <summary>
- /// Setter for this field.
- /// </summary>
- public Action<T> setter { get; set; }
- // This should be an `event` but they don't play nice with object initializers in the
- // version of C# we use.
- /// <summary>
- /// Callback used when the value of the field changes.
- /// </summary>
- public Action<Field<T>, T> onValueChanged;
- /// <summary>
- /// Function used to validate the value when updating the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- /// <returns>Validated value.</returns>
- object IValueField.ValidateValue(object value)
- {
- return ValidateValue((T)value);
- }
- /// <summary>
- /// Function used to validate the value when updating the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- /// <returns>Validated value.</returns>
- public virtual T ValidateValue(T value)
- {
- return value;
- }
- /// <summary>
- /// Get the value of the field.
- /// </summary>
- /// <returns>Value of the field.</returns>
- object IValueField.GetValue()
- {
- return GetValue();
- }
- /// <summary>
- /// Get the value of the field.
- /// </summary>
- /// <returns>Value of the field.</returns>
- public T GetValue()
- {
- Assert.IsNotNull(getter);
- return getter();
- }
- /// <summary>
- /// Set the value of the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- public void SetValue(object value)
- {
- SetValue((T)value);
- }
- /// <summary>
- /// Set the value of the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- public void SetValue(T value)
- {
- Assert.IsNotNull(setter);
- var v = ValidateValue(value);
- if (!v.Equals(getter()))
- {
- setter(v);
- if (onValueChanged != null)
- onValueChanged(this, v);
- }
- }
- }
- /// <summary>
- /// Boolean field.
- /// </summary>
- public class BoolField : Field<bool> { }
- /// <summary>
- /// Boolean field with history.
- /// </summary>
- public class HistoryBoolField : BoolField
- {
- /// <summary>
- /// History getter for this field.
- /// </summary>
- public Func<bool>[] historyGetter { get; set; }
- /// <summary>
- /// Depth of the field's history.
- /// </summary>
- public int historyDepth => historyGetter?.Length ?? 0;
- /// <summary>
- /// Get the value of the field at a certain history index.
- /// </summary>
- /// <param name="historyIndex">Index of the history to query.</param>
- /// <returns>Value of the field at the provided history index.</returns>
- public bool GetHistoryValue(int historyIndex)
- {
- Assert.IsNotNull(historyGetter);
- Assert.IsTrue(historyIndex >= 0 && historyIndex < historyGetter.Length, "out of range historyIndex");
- Assert.IsNotNull(historyGetter[historyIndex]);
- return historyGetter[historyIndex]();
- }
- }
- /// <summary>
- /// Integer field.
- /// </summary>
- public class IntField : Field<int>
- {
- /// <summary>
- /// Minimum value function.
- /// </summary>
- public Func<int> min;
- /// <summary>
- /// Maximum value function.
- /// </summary>
- public Func<int> max;
- // Runtime-only
- /// <summary>
- /// Step increment.
- /// </summary>
- public int incStep = 1;
- /// <summary>
- /// Step increment multiplier.
- /// </summary>
- public int intStepMult = 10;
- /// <summary>
- /// Function used to validate the value when updating the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- /// <returns>Validated value.</returns>
- public override int ValidateValue(int value)
- {
- if (min != null) value = Mathf.Max(value, min());
- if (max != null) value = Mathf.Min(value, max());
- return value;
- }
- }
- /// <summary>
- /// Unsigned integer field.
- /// </summary>
- public class UIntField : Field<uint>
- {
- /// <summary>
- /// Minimum value function.
- /// </summary>
- public Func<uint> min;
- /// <summary>
- /// Maximum value function.
- /// </summary>
- public Func<uint> max;
- // Runtime-only
- /// <summary>
- /// Step increment.
- /// </summary>
- public uint incStep = 1u;
- /// <summary>
- /// Step increment multiplier.
- /// </summary>
- public uint intStepMult = 10u;
- /// <summary>
- /// Function used to validate the value when updating the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- /// <returns>Validated value.</returns>
- public override uint ValidateValue(uint value)
- {
- if (min != null) value = (uint)Mathf.Max((int)value, (int)min());
- if (max != null) value = (uint)Mathf.Min((int)value, (int)max());
- return value;
- }
- }
- /// <summary>
- /// Float field.
- /// </summary>
- public class FloatField : Field<float>
- {
- /// <summary>
- /// Minimum value function.
- /// </summary>
- public Func<float> min;
- /// <summary>
- /// Maximum value function.
- /// </summary>
- public Func<float> max;
- // Runtime-only
- /// <summary>
- /// Step increment.
- /// </summary>
- public float incStep = 0.1f;
- /// <summary>
- /// Step increment multiplier.
- /// </summary>
- public float incStepMult = 10f;
- /// <summary>
- /// Number of decimals.
- /// </summary>
- public int decimals = 3;
- /// <summary>
- /// Function used to validate the value when updating the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- /// <returns>Validated value.</returns>
- public override float ValidateValue(float value)
- {
- if (min != null) value = Mathf.Max(value, min());
- if (max != null) value = Mathf.Min(value, max());
- return value;
- }
- }
- /// <summary>
- /// Enumerator field.
- /// </summary>
- public class EnumField : Field<int>
- {
- /// <summary>
- /// List of names of the enumerator entries.
- /// </summary>
- public GUIContent[] enumNames;
- /// <summary>
- /// List of values of the enumerator entries.
- /// </summary>
- public int[] enumValues;
- internal int[] quickSeparators;
- internal int[] indexes;
- /// <summary>
- /// Get the enumeration value index.
- /// </summary>
- public Func<int> getIndex { get; set; }
- /// <summary>
- /// Set the enumeration value index.
- /// </summary>
- public Action<int> setIndex { get; set; }
- /// <summary>
- /// Current enumeration value index.
- /// </summary>
- public int currentIndex { get { return getIndex(); } set { setIndex(value); } }
- /// <summary>
- /// Generates enumerator values and names automatically based on the provided type.
- /// </summary>
- public Type autoEnum
- {
- set
- {
- enumNames = Enum.GetNames(value).Select(x => new GUIContent(x)).ToArray();
- // Linq.Cast<T> on a typeless Array breaks the JIT on PS4/Mono so we have to do it manually
- //enumValues = Enum.GetValues(value).Cast<int>().ToArray();
- var values = Enum.GetValues(value);
- enumValues = new int[values.Length];
- for (int i = 0; i < values.Length; i++)
- enumValues[i] = (int)values.GetValue(i);
- InitIndexes();
- InitQuickSeparators();
- }
- }
- internal void InitQuickSeparators()
- {
- var enumNamesPrefix = enumNames.Select(x =>
- {
- string[] splitted = x.text.Split('/');
- if (splitted.Length == 1)
- return "";
- else
- return splitted[0];
- });
- quickSeparators = new int[enumNamesPrefix.Distinct().Count()];
- string lastPrefix = null;
- for (int i = 0, wholeNameIndex = 0; i < quickSeparators.Length; ++i)
- {
- var currentTestedPrefix = enumNamesPrefix.ElementAt(wholeNameIndex);
- while (lastPrefix == currentTestedPrefix)
- {
- currentTestedPrefix = enumNamesPrefix.ElementAt(++wholeNameIndex);
- }
- lastPrefix = currentTestedPrefix;
- quickSeparators[i] = wholeNameIndex++;
- }
- }
- internal void InitIndexes()
- {
- indexes = new int[enumNames.Length];
- for (int i = 0; i < enumNames.Length; i++)
- {
- indexes[i] = i;
- }
- }
- }
- /// <summary>
- /// Enumerator field with history.
- /// </summary>
- public class HistoryEnumField : EnumField
- {
- /// <summary>
- /// History getter for this field.
- /// </summary>
- public Func<int>[] historyIndexGetter { get; set; }
- /// <summary>
- /// Depth of the field's history.
- /// </summary>
- public int historyDepth => historyIndexGetter?.Length ?? 0;
- /// <summary>
- /// Get the value of the field at a certain history index.
- /// </summary>
- /// <param name="historyIndex">Index of the history to query.</param>
- /// <returns>Value of the field at the provided history index.</returns>
- public int GetHistoryValue(int historyIndex)
- {
- Assert.IsNotNull(historyIndexGetter);
- Assert.IsTrue(historyIndex >= 0 && historyIndex < historyIndexGetter.Length, "out of range historyIndex");
- Assert.IsNotNull(historyIndexGetter[historyIndex]);
- return historyIndexGetter[historyIndex]();
- }
- }
- /// <summary>
- /// Bitfield enumeration field.
- /// </summary>
- public class BitField : Field<Enum>
- {
- /// <summary>
- /// List of names of the enumerator entries.
- /// </summary>
- public GUIContent[] enumNames { get; private set; }
- /// <summary>
- /// List of values of the enumerator entries.
- /// </summary>
- public int[] enumValues { get; private set; }
- internal Type m_EnumType;
- /// <summary>
- /// Generates bitfield values and names automatically based on the provided type.
- /// </summary>
- public Type enumType
- {
- set
- {
- enumNames = Enum.GetNames(value).Select(x => new GUIContent(x)).ToArray();
- // Linq.Cast<T> on a typeless Array breaks the JIT on PS4/Mono so we have to do it manually
- //enumValues = Enum.GetValues(value).Cast<int>().ToArray();
- var values = Enum.GetValues(value);
- enumValues = new int[values.Length];
- for (int i = 0; i < values.Length; i++)
- enumValues[i] = (int)values.GetValue(i);
- m_EnumType = value;
- }
- get { return m_EnumType; }
- }
- }
- /// <summary>
- /// Color field.
- /// </summary>
- public class ColorField : Field<Color>
- {
- /// <summary>
- /// HDR color.
- /// </summary>
- public bool hdr = false;
- /// <summary>
- /// Show alpha of the color field.
- /// </summary>
- public bool showAlpha = true;
- // Editor-only
- /// <summary>
- /// Show the color picker.
- /// </summary>
- public bool showPicker = true;
- // Runtime-only
- /// <summary>
- /// Step increment.
- /// </summary>
- public float incStep = 0.025f;
- /// <summary>
- /// Step increment multiplier.
- /// </summary>
- public float incStepMult = 5f;
- /// <summary>
- /// Number of decimals.
- /// </summary>
- public int decimals = 3;
- /// <summary>
- /// Function used to validate the value when updating the field.
- /// </summary>
- /// <param name="value">Input value.</param>
- /// <returns>Validated value.</returns>
- public override Color ValidateValue(Color value)
- {
- if (!hdr)
- {
- value.r = Mathf.Clamp01(value.r);
- value.g = Mathf.Clamp01(value.g);
- value.b = Mathf.Clamp01(value.b);
- value.a = Mathf.Clamp01(value.a);
- }
- return value;
- }
- }
- /// <summary>
- /// Vector2 field.
- /// </summary>
- public class Vector2Field : Field<Vector2>
- {
- // Runtime-only
- /// <summary>
- /// Step increment.
- /// </summary>
- public float incStep = 0.025f;
- /// <summary>
- /// Step increment multiplier.
- /// </summary>
- public float incStepMult = 10f;
- /// <summary>
- /// Number of decimals.
- /// </summary>
- public int decimals = 3;
- }
- /// <summary>
- /// Vector3 field.
- /// </summary>
- public class Vector3Field : Field<Vector3>
- {
- // Runtime-only
- /// <summary>
- /// Step increment.
- /// </summary>
- public float incStep = 0.025f;
- /// <summary>
- /// Step increment multiplier.
- /// </summary>
- public float incStepMult = 10f;
- /// <summary>
- /// Number of decimals.
- /// </summary>
- public int decimals = 3;
- }
- /// <summary>
- /// Vector4 field.
- /// </summary>
- public class Vector4Field : Field<Vector4>
- {
- // Runtime-only
- /// <summary>
- /// Step increment.
- /// </summary>
- public float incStep = 0.025f;
- /// <summary>
- /// Step increment multiplier.
- /// </summary>
- public float incStepMult = 10f;
- /// <summary>
- /// Number of decimals.
- /// </summary>
- public int decimals = 3;
- }
- }
- }
|