A game about forced loneliness, made by TACStudios
1#if UNITY_EDITOR && UNITY_INPUT_SYSTEM_PROJECT_WIDE_ACTIONS 2using System; 3using System.Collections.Generic; 4using UnityEngine.UIElements; 5 6namespace UnityEngine.InputSystem.Editor 7{ 8 internal interface IViewStateSelector<out TViewState> 9 { 10 bool HasStateChanged(InputActionsEditorState state); 11 TViewState GetViewState(InputActionsEditorState state); 12 } 13 14 internal interface IView 15 { 16 void UpdateView(InputActionsEditorState state); 17 void DestroyView(); 18 } 19 20 internal abstract class ViewBase<TViewState> : IView 21 { 22 protected ViewBase(VisualElement root, StateContainer stateContainer) 23 { 24 this.rootElement = root; 25 this.stateContainer = stateContainer; 26 m_ChildViews = new List<IView>(); 27 } 28 29 protected void OnStateChanged(InputActionsEditorState state) 30 { 31 UpdateView(state); 32 } 33 34 public void UpdateView(InputActionsEditorState state) 35 { 36 if (m_ViewStateSelector == null) 37 { 38 Debug.LogWarning( 39 $"View '{GetType().Name}' has no selector and will not render. Create a selector for the " + 40 $"view using the CreateSelector method."); 41 return; 42 } 43 44 if (m_ViewStateSelector.HasStateChanged(state) || m_IsFirstUpdate) 45 RedrawUI(m_ViewStateSelector.GetViewState(state)); 46 47 m_IsFirstUpdate = false; 48 foreach (var view in m_ChildViews) 49 { 50 view.UpdateView(state); 51 } 52 53 // We can execute UI Commands now that the UI is fully updated 54 // NOTE: This isn't used with Input Commands 55 allowUICommandExecution = true; 56 } 57 58 public TView CreateChildView<TView>(TView view) where TView : IView 59 { 60 m_ChildViews.Add(view); 61 return view; 62 } 63 64 public void DestroyChildView<TView>(TView view) where TView : IView 65 { 66 if (view == null) 67 return; 68 69 m_ChildViews.Remove(view); 70 view.DestroyView(); 71 } 72 73 public void Dispatch(Command command) 74 { 75 stateContainer.Dispatch(command); 76 } 77 78 public abstract void RedrawUI(TViewState viewState); 79 80 /// <summary> 81 /// Called when a parent view is destroying this view to give it an opportunity to clean up any 82 /// resources or event handlers. 83 /// </summary> 84 public virtual void DestroyView() 85 { 86 } 87 88 protected void CreateSelector(Func<InputActionsEditorState, TViewState> selector) 89 { 90 m_ViewStateSelector = new ViewStateSelector<TViewState>(selector); 91 } 92 93 protected void CreateSelector<T1>( 94 Func<InputActionsEditorState, T1> func1, 95 Func<T1, InputActionsEditorState, TViewState> selector) 96 { 97 m_ViewStateSelector = new ViewStateSelector<T1, TViewState>(func1, selector); 98 } 99 100 protected void CreateSelector<T1, T2>( 101 Func<InputActionsEditorState, T1> func1, 102 Func<InputActionsEditorState, T2> func2, 103 Func<T1, T2, InputActionsEditorState, TViewState> selector) 104 { 105 m_ViewStateSelector = new ViewStateSelector<T1, T2, TViewState>(func1, func2, selector); 106 } 107 108 protected void CreateSelector<T1, T2, T3>( 109 Func<InputActionsEditorState, T1> func1, 110 Func<InputActionsEditorState, T2> func2, 111 Func<InputActionsEditorState, T3> func3, 112 Func<T1, T2, T3, InputActionsEditorState, TViewState> selector) 113 { 114 m_ViewStateSelector = new ViewStateSelector<T1, T2, T3, TViewState>(func1, func2, func3, selector); 115 } 116 117 protected readonly VisualElement rootElement; 118 protected readonly StateContainer stateContainer; 119 protected bool allowUICommandExecution { get; set; } = true; 120 121 protected IViewStateSelector<TViewState> ViewStateSelector => m_ViewStateSelector; 122 private IViewStateSelector<TViewState> m_ViewStateSelector; 123 private IList<IView> m_ChildViews; 124 private bool m_IsFirstUpdate = true; 125 } 126 127 internal class ViewStateSelector<TReturn> : IViewStateSelector<TReturn> 128 { 129 private readonly Func<InputActionsEditorState, TReturn> m_Selector; 130 131 public ViewStateSelector(Func<InputActionsEditorState, TReturn> selector) 132 { 133 m_Selector = selector; 134 } 135 136 public bool HasStateChanged(InputActionsEditorState state) 137 { 138 return true; 139 } 140 141 public TReturn GetViewState(InputActionsEditorState state) 142 { 143 return m_Selector(state); 144 } 145 } 146 147 // TODO: Make all args to view state selectors IEquatable<T>? 148 internal class ViewStateSelector<T1, TReturn> : IViewStateSelector<TReturn> 149 { 150 private readonly Func<InputActionsEditorState, T1> m_Func1; 151 private readonly Func<T1, InputActionsEditorState, TReturn> m_Selector; 152 153 private T1 m_PreviousT1; 154 155 public ViewStateSelector(Func<InputActionsEditorState, T1> func1, 156 Func<T1, InputActionsEditorState, TReturn> selector) 157 { 158 m_Func1 = func1; 159 m_Selector = selector; 160 } 161 162 public bool HasStateChanged(InputActionsEditorState state) 163 { 164 var valueOne = m_Func1(state); 165 166 if (valueOne is IViewStateCollection collection) 167 { 168 if (collection.SequenceEqual((IViewStateCollection)m_PreviousT1)) 169 return false; 170 } 171 else if (valueOne.Equals(m_PreviousT1)) 172 { 173 return false; 174 } 175 176 m_PreviousT1 = valueOne; 177 return true; 178 } 179 180 public TReturn GetViewState(InputActionsEditorState state) 181 { 182 return m_Selector(m_PreviousT1, state); 183 } 184 } 185 186 internal class ViewStateSelector<T1, T2, TReturn> : IViewStateSelector<TReturn> 187 { 188 private readonly Func<InputActionsEditorState, T1> m_Func1; 189 private readonly Func<InputActionsEditorState, T2> m_Func2; 190 private readonly Func<T1, T2, InputActionsEditorState, TReturn> m_Selector; 191 192 private T1 m_PreviousT1; 193 private T2 m_PreviousT2; 194 195 public ViewStateSelector(Func<InputActionsEditorState, T1> func1, 196 Func<InputActionsEditorState, T2> func2, 197 Func<T1, T2, InputActionsEditorState, TReturn> selector) 198 { 199 m_Func1 = func1; 200 m_Func2 = func2; 201 m_Selector = selector; 202 } 203 204 public bool HasStateChanged(InputActionsEditorState state) 205 { 206 var valueOne = m_Func1(state); 207 var valueTwo = m_Func2(state); 208 209 var valueOneHasChanged = false; 210 var valueTwoHasChanged = false; 211 212 if (valueOne is IViewStateCollection collection && !collection.SequenceEqual((IViewStateCollection)m_PreviousT1) || 213 !valueOne.Equals(m_PreviousT1)) 214 valueOneHasChanged = true; 215 216 if (valueTwo is IViewStateCollection collection2 && !collection2.SequenceEqual((IViewStateCollection)m_PreviousT2) || 217 !valueTwo.Equals(m_PreviousT2)) 218 valueTwoHasChanged = true; 219 220 if (!valueOneHasChanged && !valueTwoHasChanged) 221 return false; 222 223 m_PreviousT1 = valueOne; 224 m_PreviousT2 = valueTwo; 225 return true; 226 } 227 228 public TReturn GetViewState(InputActionsEditorState state) 229 { 230 return m_Selector(m_PreviousT1, m_PreviousT2, state); 231 } 232 } 233 234 internal class ViewStateSelector<T1, T2, T3, TReturn> : IViewStateSelector<TReturn> 235 { 236 private readonly Func<InputActionsEditorState, T1> m_Func1; 237 private readonly Func<InputActionsEditorState, T2> m_Func2; 238 private readonly Func<InputActionsEditorState, T3> m_Func3; 239 private readonly Func<T1, T2, T3, InputActionsEditorState, TReturn> m_Selector; 240 241 private T1 m_PreviousT1; 242 private T2 m_PreviousT2; 243 private T3 m_PreviousT3; 244 245 public ViewStateSelector(Func<InputActionsEditorState, T1> func1, 246 Func<InputActionsEditorState, T2> func2, 247 Func<InputActionsEditorState, T3> func3, 248 Func<T1, T2, T3, InputActionsEditorState, TReturn> selector) 249 { 250 m_Func1 = func1; 251 m_Func2 = func2; 252 m_Func3 = func3; 253 m_Selector = selector; 254 } 255 256 public bool HasStateChanged(InputActionsEditorState state) 257 { 258 var valueOne = m_Func1(state); 259 var valueTwo = m_Func2(state); 260 var valueThree = m_Func3(state); 261 262 var valueOneHasChanged = false; 263 var valueTwoHasChanged = false; 264 var valueThreeHasChanged = false; 265 266 if (valueOne is IViewStateCollection collection && !collection.SequenceEqual((IViewStateCollection)m_PreviousT1) || 267 !valueOne.Equals(m_PreviousT1)) 268 valueOneHasChanged = true; 269 270 if (valueTwo is IViewStateCollection collection2 && !collection2.SequenceEqual((IViewStateCollection)m_PreviousT2) || 271 !valueTwo.Equals(m_PreviousT2)) 272 valueTwoHasChanged = true; 273 274 if (valueThree is IViewStateCollection collection3 && !collection3.SequenceEqual((IViewStateCollection)m_PreviousT3) || 275 !valueThree.Equals(m_PreviousT3)) 276 valueThreeHasChanged = true; 277 278 if (!valueOneHasChanged && !valueTwoHasChanged && !valueThreeHasChanged) 279 return false; 280 281 m_PreviousT1 = valueOne; 282 m_PreviousT2 = valueTwo; 283 m_PreviousT3 = valueThree; 284 return true; 285 } 286 287 public TReturn GetViewState(InputActionsEditorState state) 288 { 289 return m_Selector(m_PreviousT1, m_PreviousT2, m_PreviousT3, state); 290 } 291 } 292} 293 294#endif