UI 자동화를 위해 바인딩 기능 구현
- 유니티 에셋 인증 오류로 meta 재생성
This commit is contained in:
@@ -0,0 +1,298 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEngine.InputSystem.Editor
|
||||
{
|
||||
internal interface IViewStateSelector<out TViewState>
|
||||
{
|
||||
bool HasStateChanged(InputActionsEditorState state);
|
||||
TViewState GetViewState(InputActionsEditorState state);
|
||||
}
|
||||
|
||||
internal interface IView
|
||||
{
|
||||
void UpdateView(InputActionsEditorState state);
|
||||
void DestroyView();
|
||||
}
|
||||
|
||||
internal abstract class ViewBase<TViewState> : IView
|
||||
{
|
||||
protected ViewBase(VisualElement root, StateContainer stateContainer)
|
||||
{
|
||||
this.rootElement = root;
|
||||
this.stateContainer = stateContainer;
|
||||
m_ChildViews = new List<IView>();
|
||||
}
|
||||
|
||||
protected void OnStateChanged(InputActionsEditorState state, UIRebuildMode editorRebuildMode)
|
||||
{
|
||||
// Return early if rebuilding the editor UI isn't required (ISXB-1171)
|
||||
if (editorRebuildMode == UIRebuildMode.None)
|
||||
return;
|
||||
|
||||
UpdateView(state);
|
||||
}
|
||||
|
||||
public void UpdateView(InputActionsEditorState state)
|
||||
{
|
||||
if (m_ViewStateSelector == null)
|
||||
{
|
||||
Debug.LogWarning(
|
||||
$"View '{GetType().Name}' has no selector and will not render. Create a selector for the " +
|
||||
$"view using the CreateSelector method.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_ViewStateSelector.HasStateChanged(state) || m_IsFirstUpdate)
|
||||
RedrawUI(m_ViewStateSelector.GetViewState(state));
|
||||
|
||||
m_IsFirstUpdate = false;
|
||||
foreach (var view in m_ChildViews)
|
||||
{
|
||||
view.UpdateView(state);
|
||||
}
|
||||
|
||||
// We can execute UI Commands now that the UI is fully updated
|
||||
// NOTE: This isn't used with Input Commands
|
||||
allowUICommandExecution = true;
|
||||
}
|
||||
|
||||
public TView CreateChildView<TView>(TView view) where TView : IView
|
||||
{
|
||||
m_ChildViews.Add(view);
|
||||
return view;
|
||||
}
|
||||
|
||||
public void DestroyChildView<TView>(TView view) where TView : IView
|
||||
{
|
||||
if (view == null)
|
||||
return;
|
||||
|
||||
m_ChildViews.Remove(view);
|
||||
view.DestroyView();
|
||||
}
|
||||
|
||||
public void Dispatch(Command command, UIRebuildMode editorRebuildMode = UIRebuildMode.Rebuild)
|
||||
{
|
||||
stateContainer.Dispatch(command, editorRebuildMode);
|
||||
}
|
||||
|
||||
public abstract void RedrawUI(TViewState viewState);
|
||||
|
||||
/// <summary>
|
||||
/// Called when a parent view is destroying this view to give it an opportunity to clean up any
|
||||
/// resources or event handlers.
|
||||
/// </summary>
|
||||
public virtual void DestroyView()
|
||||
{
|
||||
}
|
||||
|
||||
protected void CreateSelector(Func<InputActionsEditorState, TViewState> selector)
|
||||
{
|
||||
m_ViewStateSelector = new ViewStateSelector<TViewState>(selector);
|
||||
}
|
||||
|
||||
protected void CreateSelector<T1>(
|
||||
Func<InputActionsEditorState, T1> func1,
|
||||
Func<T1, InputActionsEditorState, TViewState> selector)
|
||||
{
|
||||
m_ViewStateSelector = new ViewStateSelector<T1, TViewState>(func1, selector);
|
||||
}
|
||||
|
||||
protected void CreateSelector<T1, T2>(
|
||||
Func<InputActionsEditorState, T1> func1,
|
||||
Func<InputActionsEditorState, T2> func2,
|
||||
Func<T1, T2, InputActionsEditorState, TViewState> selector)
|
||||
{
|
||||
m_ViewStateSelector = new ViewStateSelector<T1, T2, TViewState>(func1, func2, selector);
|
||||
}
|
||||
|
||||
protected void CreateSelector<T1, T2, T3>(
|
||||
Func<InputActionsEditorState, T1> func1,
|
||||
Func<InputActionsEditorState, T2> func2,
|
||||
Func<InputActionsEditorState, T3> func3,
|
||||
Func<T1, T2, T3, InputActionsEditorState, TViewState> selector)
|
||||
{
|
||||
m_ViewStateSelector = new ViewStateSelector<T1, T2, T3, TViewState>(func1, func2, func3, selector);
|
||||
}
|
||||
|
||||
protected readonly VisualElement rootElement;
|
||||
protected readonly StateContainer stateContainer;
|
||||
protected bool allowUICommandExecution { get; set; } = true;
|
||||
|
||||
protected IViewStateSelector<TViewState> ViewStateSelector => m_ViewStateSelector;
|
||||
private IViewStateSelector<TViewState> m_ViewStateSelector;
|
||||
private IList<IView> m_ChildViews;
|
||||
private bool m_IsFirstUpdate = true;
|
||||
}
|
||||
|
||||
internal class ViewStateSelector<TReturn> : IViewStateSelector<TReturn>
|
||||
{
|
||||
private readonly Func<InputActionsEditorState, TReturn> m_Selector;
|
||||
|
||||
public ViewStateSelector(Func<InputActionsEditorState, TReturn> selector)
|
||||
{
|
||||
m_Selector = selector;
|
||||
}
|
||||
|
||||
public bool HasStateChanged(InputActionsEditorState state)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public TReturn GetViewState(InputActionsEditorState state)
|
||||
{
|
||||
return m_Selector(state);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Make all args to view state selectors IEquatable<T>?
|
||||
internal class ViewStateSelector<T1, TReturn> : IViewStateSelector<TReturn>
|
||||
{
|
||||
private readonly Func<InputActionsEditorState, T1> m_Func1;
|
||||
private readonly Func<T1, InputActionsEditorState, TReturn> m_Selector;
|
||||
|
||||
private T1 m_PreviousT1;
|
||||
|
||||
public ViewStateSelector(Func<InputActionsEditorState, T1> func1,
|
||||
Func<T1, InputActionsEditorState, TReturn> selector)
|
||||
{
|
||||
m_Func1 = func1;
|
||||
m_Selector = selector;
|
||||
}
|
||||
|
||||
public bool HasStateChanged(InputActionsEditorState state)
|
||||
{
|
||||
var valueOne = m_Func1(state);
|
||||
|
||||
if (valueOne is IViewStateCollection collection)
|
||||
{
|
||||
if (collection.SequenceEqual((IViewStateCollection)m_PreviousT1))
|
||||
return false;
|
||||
}
|
||||
else if (valueOne.Equals(m_PreviousT1))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_PreviousT1 = valueOne;
|
||||
return true;
|
||||
}
|
||||
|
||||
public TReturn GetViewState(InputActionsEditorState state)
|
||||
{
|
||||
return m_Selector(m_PreviousT1, state);
|
||||
}
|
||||
}
|
||||
|
||||
internal class ViewStateSelector<T1, T2, TReturn> : IViewStateSelector<TReturn>
|
||||
{
|
||||
private readonly Func<InputActionsEditorState, T1> m_Func1;
|
||||
private readonly Func<InputActionsEditorState, T2> m_Func2;
|
||||
private readonly Func<T1, T2, InputActionsEditorState, TReturn> m_Selector;
|
||||
|
||||
private T1 m_PreviousT1;
|
||||
private T2 m_PreviousT2;
|
||||
|
||||
public ViewStateSelector(Func<InputActionsEditorState, T1> func1,
|
||||
Func<InputActionsEditorState, T2> func2,
|
||||
Func<T1, T2, InputActionsEditorState, TReturn> selector)
|
||||
{
|
||||
m_Func1 = func1;
|
||||
m_Func2 = func2;
|
||||
m_Selector = selector;
|
||||
}
|
||||
|
||||
public bool HasStateChanged(InputActionsEditorState state)
|
||||
{
|
||||
var valueOne = m_Func1(state);
|
||||
var valueTwo = m_Func2(state);
|
||||
|
||||
var valueOneHasChanged = false;
|
||||
var valueTwoHasChanged = false;
|
||||
|
||||
if (valueOne is IViewStateCollection collection && !collection.SequenceEqual((IViewStateCollection)m_PreviousT1) ||
|
||||
!valueOne.Equals(m_PreviousT1))
|
||||
valueOneHasChanged = true;
|
||||
|
||||
if (valueTwo is IViewStateCollection collection2 && !collection2.SequenceEqual((IViewStateCollection)m_PreviousT2) ||
|
||||
!valueTwo.Equals(m_PreviousT2))
|
||||
valueTwoHasChanged = true;
|
||||
|
||||
if (!valueOneHasChanged && !valueTwoHasChanged)
|
||||
return false;
|
||||
|
||||
m_PreviousT1 = valueOne;
|
||||
m_PreviousT2 = valueTwo;
|
||||
return true;
|
||||
}
|
||||
|
||||
public TReturn GetViewState(InputActionsEditorState state)
|
||||
{
|
||||
return m_Selector(m_PreviousT1, m_PreviousT2, state);
|
||||
}
|
||||
}
|
||||
|
||||
internal class ViewStateSelector<T1, T2, T3, TReturn> : IViewStateSelector<TReturn>
|
||||
{
|
||||
private readonly Func<InputActionsEditorState, T1> m_Func1;
|
||||
private readonly Func<InputActionsEditorState, T2> m_Func2;
|
||||
private readonly Func<InputActionsEditorState, T3> m_Func3;
|
||||
private readonly Func<T1, T2, T3, InputActionsEditorState, TReturn> m_Selector;
|
||||
|
||||
private T1 m_PreviousT1;
|
||||
private T2 m_PreviousT2;
|
||||
private T3 m_PreviousT3;
|
||||
|
||||
public ViewStateSelector(Func<InputActionsEditorState, T1> func1,
|
||||
Func<InputActionsEditorState, T2> func2,
|
||||
Func<InputActionsEditorState, T3> func3,
|
||||
Func<T1, T2, T3, InputActionsEditorState, TReturn> selector)
|
||||
{
|
||||
m_Func1 = func1;
|
||||
m_Func2 = func2;
|
||||
m_Func3 = func3;
|
||||
m_Selector = selector;
|
||||
}
|
||||
|
||||
public bool HasStateChanged(InputActionsEditorState state)
|
||||
{
|
||||
var valueOne = m_Func1(state);
|
||||
var valueTwo = m_Func2(state);
|
||||
var valueThree = m_Func3(state);
|
||||
|
||||
var valueOneHasChanged = false;
|
||||
var valueTwoHasChanged = false;
|
||||
var valueThreeHasChanged = false;
|
||||
|
||||
if (valueOne is IViewStateCollection collection && !collection.SequenceEqual((IViewStateCollection)m_PreviousT1) ||
|
||||
!valueOne.Equals(m_PreviousT1))
|
||||
valueOneHasChanged = true;
|
||||
|
||||
if (valueTwo is IViewStateCollection collection2 && !collection2.SequenceEqual((IViewStateCollection)m_PreviousT2) ||
|
||||
!valueTwo.Equals(m_PreviousT2))
|
||||
valueTwoHasChanged = true;
|
||||
|
||||
if (valueThree is IViewStateCollection collection3 && !collection3.SequenceEqual((IViewStateCollection)m_PreviousT3) ||
|
||||
!valueThree.Equals(m_PreviousT3))
|
||||
valueThreeHasChanged = true;
|
||||
|
||||
if (!valueOneHasChanged && !valueTwoHasChanged && !valueThreeHasChanged)
|
||||
return false;
|
||||
|
||||
m_PreviousT1 = valueOne;
|
||||
m_PreviousT2 = valueTwo;
|
||||
m_PreviousT3 = valueThree;
|
||||
return true;
|
||||
}
|
||||
|
||||
public TReturn GetViewState(InputActionsEditorState state)
|
||||
{
|
||||
return m_Selector(m_PreviousT1, m_PreviousT2, m_PreviousT3, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user