An easy to use Unity 3D library for creating illustrated Interactive Fiction games and more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

235 lines
10 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using UnityEditor;
using UnityEngine;
#if UNITY_5_3_OR_NEWER
using UnityEditor.SceneManagement;
#endif
namespace UnityTest
{
[CustomEditor(typeof(AssertionComponent))]
public class AssertionComponentEditor : Editor
{
private readonly DropDownControl<Type> m_ComparerDropDown = new DropDownControl<Type>();
private readonly PropertyPathSelector m_ThisPathSelector = new PropertyPathSelector("Compare");
private readonly PropertyPathSelector m_OtherPathSelector = new PropertyPathSelector("Compare to");
#region GUI Contents
private readonly GUIContent m_GUICheckAfterTimeGuiContent = new GUIContent("Check after (seconds)", "After how many seconds the assertion should be checked");
private readonly GUIContent m_GUIRepeatCheckTimeGuiContent = new GUIContent("Repeat check", "Should the check be repeated.");
private readonly GUIContent m_GUIRepeatEveryTimeGuiContent = new GUIContent("Frequency of repetitions", "How often should the check be done");
private readonly GUIContent m_GUICheckAfterFramesGuiContent = new GUIContent("Check after (frames)", "After how many frames the assertion should be checked");
private readonly GUIContent m_GUIRepeatCheckFrameGuiContent = new GUIContent("Repeat check", "Should the check be repeated.");
#endregion
private static List<Type> allComparersList = null;
public AssertionComponentEditor()
{
m_ComparerDropDown.convertForButtonLabel = type => type.Name;
m_ComparerDropDown.convertForGUIContent = type => type.Name;
m_ComparerDropDown.ignoreConvertForGUIContent = types => false;
m_ComparerDropDown.tooltip = "Comparer that will be used to compare values and determine the result of assertion.";
}
public override void OnInspectorGUI()
{
var script = (AssertionComponent)target;
EditorGUILayout.BeginHorizontal();
var obj = DrawComparerSelection(script);
script.checkMethods = (CheckMethod)EditorGUILayout.EnumMaskField(script.checkMethods,
EditorStyles.popup,
GUILayout.ExpandWidth(false));
EditorGUILayout.EndHorizontal();
if (script.IsCheckMethodSelected(CheckMethod.AfterPeriodOfTime))
{
DrawOptionsForAfterPeriodOfTime(script);
}
if (script.IsCheckMethodSelected(CheckMethod.Update))
{
DrawOptionsForOnUpdate(script);
}
if (obj)
{
EditorGUILayout.Space();
m_ThisPathSelector.Draw(script.Action.go, script.Action,
script.Action.thisPropertyPath, script.Action.GetAccepatbleTypesForA(),
go =>
{
script.Action.go = go;
AssertionExplorerWindow.Reload();
},
s =>
{
script.Action.thisPropertyPath = s;
AssertionExplorerWindow.Reload();
});
EditorGUILayout.Space();
DrawCustomFields(script);
EditorGUILayout.Space();
if (script.Action is ComparerBase)
{
DrawCompareToType(script.Action as ComparerBase);
}
}
if(GUI.changed)
{
#if UNITY_5_3_OR_NEWER
EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
#else
EditorApplication.MarkSceneDirty();
#endif
}
}
private void DrawOptionsForAfterPeriodOfTime(AssertionComponent script)
{
EditorGUILayout.Space();
script.checkAfterTime = EditorGUILayout.FloatField(m_GUICheckAfterTimeGuiContent,
script.checkAfterTime);
if (script.checkAfterTime < 0)
script.checkAfterTime = 0;
script.repeatCheckTime = EditorGUILayout.Toggle(m_GUIRepeatCheckTimeGuiContent,
script.repeatCheckTime);
if (script.repeatCheckTime)
{
script.repeatEveryTime = EditorGUILayout.FloatField(m_GUIRepeatEveryTimeGuiContent,
script.repeatEveryTime);
if (script.repeatEveryTime < 0)
script.repeatEveryTime = 0;
}
}
private void DrawOptionsForOnUpdate(AssertionComponent script)
{
EditorGUILayout.Space();
script.checkAfterFrames = EditorGUILayout.IntField(m_GUICheckAfterFramesGuiContent,
script.checkAfterFrames);
if (script.checkAfterFrames < 1)
script.checkAfterFrames = 1;
script.repeatCheckFrame = EditorGUILayout.Toggle(m_GUIRepeatCheckFrameGuiContent,
script.repeatCheckFrame);
if (script.repeatCheckFrame)
{
script.repeatEveryFrame = EditorGUILayout.IntField(m_GUIRepeatEveryTimeGuiContent,
script.repeatEveryFrame);
if (script.repeatEveryFrame < 1)
script.repeatEveryFrame = 1;
}
}
private void DrawCompareToType(ComparerBase comparer)
{
comparer.compareToType = (ComparerBase.CompareToType)EditorGUILayout.EnumPopup("Compare to type",
comparer.compareToType,
EditorStyles.popup);
if (comparer.compareToType == ComparerBase.CompareToType.CompareToConstantValue)
{
try
{
DrawConstCompareField(comparer);
}
catch (NotImplementedException)
{
Debug.LogWarning("This comparer can't compare to static value");
comparer.compareToType = ComparerBase.CompareToType.CompareToObject;
}
}
else if (comparer.compareToType == ComparerBase.CompareToType.CompareToObject)
{
DrawObjectCompareField(comparer);
}
}
private void DrawObjectCompareField(ComparerBase comparer)
{
m_OtherPathSelector.Draw(comparer.other, comparer,
comparer.otherPropertyPath, comparer.GetAccepatbleTypesForB(),
go =>
{
comparer.other = go;
AssertionExplorerWindow.Reload();
},
s =>
{
comparer.otherPropertyPath = s;
AssertionExplorerWindow.Reload();
}
);
}
private void DrawConstCompareField(ComparerBase comparer)
{
if (comparer.ConstValue == null)
{
comparer.ConstValue = comparer.GetDefaultConstValue();
}
var so = new SerializedObject(comparer);
var sp = so.FindProperty("constantValueGeneric");
if (sp != null)
{
EditorGUILayout.PropertyField(sp, new GUIContent("Constant"), true);
so.ApplyModifiedProperties();
}
}
private bool DrawComparerSelection(AssertionComponent script)
{
if(allComparersList == null)
{
allComparersList = new List<Type>();
var allAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (var assembly in allAssemblies)
{
var types = assembly.GetTypes();
allComparersList.AddRange(types.Where(type => type.IsSubclassOf(typeof(ActionBase)) && !type.IsAbstract));
}
}
var allComparers = allComparersList.ToArray();
if (script.Action == null)
script.Action = (ActionBase)CreateInstance(allComparers.First());
m_ComparerDropDown.Draw(script.Action.GetType(), allComparers,
type =>
{
if (script.Action == null || script.Action.GetType().Name != type.Name)
{
script.Action = (ActionBase)CreateInstance(type);
AssertionExplorerWindow.Reload();
}
});
return script.Action != null;
}
private void DrawCustomFields(AssertionComponent script)
{
foreach (var prop in script.Action.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
{
var so = new SerializedObject(script.Action);
var sp = so.FindProperty(prop.Name);
if (sp != null)
{
EditorGUILayout.PropertyField(sp, true);
so.ApplyModifiedProperties();
}
}
}
}
}