A game about forced loneliness, made by TACStudios
at master 140 lines 6.7 kB view raw
1using System; 2 3namespace UnityEditor.Rendering 4{ 5 /// <summary>Used in editor drawer part to store the state of expandable areas.</summary> 6 /// <typeparam name="TState">An enum to use to describe the state.</typeparam> 7 public abstract class ExpandedStateBase<TState> 8 where TState : struct, IConvertible 9 { 10 /// <summary>Accessor to the expended state of this specific mask.</summary> 11 /// <param name="mask">The filtering mask</param> 12 /// <returns>True: All flagged area are expended</returns> 13 public abstract bool GetExpandedAreas(TState mask); 14 /// <summary>Setter to the expended state.</summary> 15 /// <param name="mask">The filtering mask</param> 16 /// <param name="value">The expended state to set</param> 17 public abstract void SetExpandedAreas(TState mask, bool value); 18 /// <summary> Utility to set all states to true </summary> 19 public abstract void ExpandAll(); 20 /// <summary> Utility to set all states to false </summary> 21 public abstract void CollapseAll(); 22 23 /// <summary>Get or set the state given the mask.</summary> 24 /// <param name="mask">The filtering mask</param> 25 /// <value>True: All flagged area are expended</value> 26 public bool this[TState mask] 27 { 28 get => GetExpandedAreas(mask); 29 set => SetExpandedAreas(mask, value); 30 } 31 } 32 33 34 /// <summary>Used in editor drawer part to store the state of expandable areas using EditorPrefBoolFlags.</summary> 35 /// <typeparam name="TState">An enum to use to describe the state.</typeparam> 36 /// <typeparam name="TTarget">A type given to automatically compute the key.</typeparam> 37 public class ExpandedState<TState, TTarget> : ExpandedStateBase<TState> 38 where TState : struct, IConvertible 39 { 40 /// <summary> 41 /// The variable which stores the state of expandable areas. 42 /// </summary> 43 protected internal EditorPrefBoolFlags<TState> m_State; 44 45 /// <summary> 46 /// Constructor will create the key to store in the EditorPref the state given generic type passed. 47 /// The key will be formated as such prefix:TTarget:TState:UI_State. 48 /// </summary> 49 /// <param name="defaultValue">If key did not exist, it will be created with this value for initialization.</param> 50 /// <param name="prefix">[Optional] Prefix scope of the key (Default is CoreRP)</param> 51 /// <param name="stateId">[Optional] Postfix used to differentiate between different keys (Default is UI_State)</param> 52 public ExpandedState(TState defaultValue, string prefix = "CoreRP", string stateId = "UI_State") 53 { 54 string key = $"{prefix}:{typeof(TTarget).Name}:{typeof(TState).Name}:{stateId}"; 55 m_State = new EditorPrefBoolFlags<TState>(key); 56 57 //register key if not already there 58 if (!EditorPrefs.HasKey(key)) 59 { 60 EditorPrefs.SetInt(key, (int)(object)defaultValue); 61 } 62 } 63 64 /// <inheritdoc/> 65 public override bool GetExpandedAreas(TState mask) 66 { 67 return m_State.HasFlag(mask); 68 } 69 70 /// <inheritdoc/> 71 public override void SetExpandedAreas(TState mask, bool value) 72 { 73 m_State.SetFlag(mask, value); 74 } 75 76 /// <inheritdoc/> 77 public override void ExpandAll() 78 { 79 m_State.rawValue = uint.MaxValue; 80 } 81 82 /// <inheritdoc/> 83 public override void CollapseAll() 84 { 85 m_State.rawValue = 0u; 86 } 87 } 88 89 /// <summary>Used in editor drawer part to store the state of expandable areas using EditorPrefBoolFlags for a list of elements.</summary> 90 /// <typeparam name="TTarget">A type given to automatically compute the key.</typeparam> 91 public class ExpandedStateList<TTarget> : ExpandedState<int, TTarget> 92 { 93 /// <summary> 94 /// Constructor will create the key to store in the EditorPref the state given generic type passed. 95 /// The key will be formated as such prefix:TTarget:TState:UI_State. 96 /// </summary> 97 /// <param name="prefix">[Optional] Prefix scope of the key (Default is CoreRP)</param> 98 public ExpandedStateList(string prefix = "CoreRP") 99 : base(default(int), prefix, "UI_State_List") { } 100 101 /// <summary> 102 /// Swap flag between src index and dst index. 103 /// </summary> 104 /// <param name="srcIndex">src index to swap.</param> 105 /// <param name="dstIndex">dst index to swap.</param> 106 public void SwapFlags(int srcIndex, int dstIndex) 107 { 108 int srcFlag = 1 << srcIndex; 109 int dstFlag = 1 << dstIndex; 110 111 bool srcVal = GetExpandedAreas(srcFlag); 112 SetExpandedAreas(srcFlag, GetExpandedAreas(dstFlag)); 113 SetExpandedAreas(dstFlag, srcVal); 114 } 115 116 /// <summary> Removes a flag at a given index which causes the following flags' index to decrease by one.</summary> 117 /// <param name="index">The index of the flag to be removed.</param> 118 public void RemoveFlagAtIndex(int index) 119 { 120 m_State.rawValue = RightShiftOnceFromIndexToMSB(index, m_State.rawValue); 121 } 122 123 /// <summary> Utility to logical right shift every bit from the index flag to MSB resulting in the index flag being shifted out.<\summary> 124 /// <param name="index">Right shift every bit greater or equal to the index.</param> 125 /// <param name="value">Value to make the operations on.</param> 126 /// <returns>The right shift value after the given index.</returns> 127 internal static uint RightShiftOnceFromIndexToMSB(int index, uint value) 128 { // Example of each operation: 129 // 1011 1001 - Value 130 uint indexBit = 1u << index; // 0000 1000 - Index bit 131 uint remainArea = indexBit - 1u; // 0000 0111 132 uint remainBits = remainArea & value; // 0000 0001 133 uint movedBits = (~remainArea - indexBit & value) >> 1; // 1111 1000 134 // 1111 0000 135 // 1011 0000 136 // 0101 1000 137 return movedBits | remainBits; // 0101 1001 - Result 138 } 139 } 140}