using System; using System.Text; using System.Collections.Generic; using System.Reflection; namespace UnityEngine.Rendering.HighDefinition { static partial class StringExtention { /// Runtime alternative to UnityEditor.ObjectNames.NicifyVariableName. Only prefix 'm_' is not skipped. public static string CamelToPascalCaseWithSpace(this string text, bool preserveAcronyms = true) { if (string.IsNullOrWhiteSpace(text)) return string.Empty; StringBuilder newText = new StringBuilder(text.Length * 2); newText.Append(char.ToUpper(text[0])); for (int i = 1; i < text.Length; i++) { if (char.IsUpper(text[i])) if ((text[i - 1] != ' ' && !char.IsUpper(text[i - 1])) || (preserveAcronyms && char.IsUpper(text[i - 1]) && i < text.Length - 1 && !char.IsUpper(text[i + 1]))) newText.Append(' '); newText.Append(text[i]); } return newText.ToString(); } } /// Should only be used on enum value of field to describe aspect in DebugMenu [AttributeUsage(AttributeTargets.Field)] class FrameSettingsFieldAttribute : Attribute { public enum DisplayType { BoolAsCheckbox, BoolAsEnumPopup, Others } public readonly DisplayType type; public readonly string displayedName; public readonly string tooltip; public readonly int group; public readonly int orderInGroup; public readonly Type targetType; public readonly int indentLevel; public readonly FrameSettingsField[] dependencies; private readonly int dependencySeparator; static int autoOrder = 0; private static Dictionary s_FrameSettingsEnumNameMap = null; public static Dictionary GetEnumNameMap() { if (s_FrameSettingsEnumNameMap == null) { s_FrameSettingsEnumNameMap = new Dictionary(); Type type = typeof(FrameSettingsField); foreach (string enumName in Enum.GetNames(type)) { if (type.GetField(enumName).GetCustomAttribute() != null) continue; s_FrameSettingsEnumNameMap.Add((FrameSettingsField)Enum.Parse(type, enumName), enumName); } } return s_FrameSettingsEnumNameMap; } static FrameSettingsFieldAttribute() { GetEnumNameMap();//build the enum name map. } /// Attribute contenaing generation info for inspector and DebugMenu /// Group index contening this element. /// [Optional] Helper to name the label as the enum entry given. Alternatively, use displayedName. /// [Optional] Displayed name to use as label. If given, it override autoname. /// [Optional] tooltip to use in inspector. /// [Optional] Requested display for this entry. /// [Requested for Enum] Allow to map boolean value to named enum. /// [Optional] Dependencies that must be activated in order to appear activable in Inspector. Indentation is deduced frm this information. /// [Optional] If order is not the same than the order of value in the FrameSettingsField enum, you can ask to rewrite order from this element. /// Could be asked to use this on another element too to have correct ordering amongst everything. /// (Example if the 2nd element must be showed at position 10, add this property with value 10 to in and this parameter with value 3 to the following one (the 3rd). public FrameSettingsFieldAttribute( int group, FrameSettingsField autoName = FrameSettingsField.None, string displayedName = null, string tooltip = null, DisplayType type = DisplayType.BoolAsCheckbox, Type targetType = null, FrameSettingsField[] positiveDependencies = null, FrameSettingsField[] negativeDependencies = null, int customOrderInGroup = -1) { if (string.IsNullOrEmpty(displayedName)) { if (!s_FrameSettingsEnumNameMap.TryGetValue(autoName, out displayedName)) { displayedName = autoName.ToString(); } displayedName = displayedName.CamelToPascalCaseWithSpace(); } // Editor and Runtime debug menu this.group = group; if (customOrderInGroup != -1) autoOrder = customOrderInGroup; //start again numbering from this value this.orderInGroup = autoOrder++; this.displayedName = displayedName; this.type = type; this.targetType = targetType; dependencySeparator = positiveDependencies?.Length ?? 0; dependencies = new FrameSettingsField[dependencySeparator + (negativeDependencies?.Length ?? 0)]; positiveDependencies?.CopyTo(dependencies, 0); negativeDependencies?.CopyTo(dependencies, dependencySeparator); indentLevel = dependencies?.Length ?? 0; #if UNITY_EDITOR // Editor only this.tooltip = tooltip; #endif } public bool IsNegativeDependency(FrameSettingsField frameSettingsField) => Array.FindIndex(dependencies, fsf => fsf == frameSettingsField) >= dependencySeparator; } }