A game about forced loneliness, made by TACStudios
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}