Browse Source
ExecuteHandler is now a separate component. Will call any OnExecute method in the game object when executing.master
11 changed files with 897 additions and 549 deletions
@ -0,0 +1,106 @@ |
|||||||
|
// Adapted from the Unity Test Tools project (MIT license) |
||||||
|
// https://bitbucket.org/Unity-Technologies/unitytesttools/src/a30d562427e9/Assets/UnityTestTools/ |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Linq; |
||||||
|
using System.Reflection; |
||||||
|
using UnityEditor; |
||||||
|
using UnityEngine; |
||||||
|
|
||||||
|
namespace Fungus |
||||||
|
{ |
||||||
|
|
||||||
|
[CustomEditor(typeof(ExecuteHandler))] |
||||||
|
public class ExecuteHandlerEditor : Editor |
||||||
|
{ |
||||||
|
private readonly DropDownControl<Type> m_ComparerDropDown = new DropDownControl<Type>(); |
||||||
|
|
||||||
|
#region GUI Contents |
||||||
|
private readonly GUIContent m_GUIExecuteAfterTimeGuiContent = new GUIContent("Execute after (seconds)", "After how many seconds the script should be executed"); |
||||||
|
private readonly GUIContent m_GUIRepeatExecuteTimeGuiContent = new GUIContent("Repeat execute", "Should the execution be repeated."); |
||||||
|
private readonly GUIContent m_GUIRepeatEveryTimeGuiContent = new GUIContent("Frequency of repetitions", "How often should the execution be done"); |
||||||
|
private readonly GUIContent m_GUIExecuteAfterFramesGuiContent = new GUIContent("Execute after (frames)", "After how many frames the script should be executed"); |
||||||
|
private readonly GUIContent m_GUIRepeatExecuteFrameGuiContent = new GUIContent("Repeat execution", "Should the execution be repeated."); |
||||||
|
#endregion |
||||||
|
|
||||||
|
public ExecuteHandlerEditor() |
||||||
|
{ |
||||||
|
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 executeHandler = (ExecuteHandler)target; |
||||||
|
EditorGUILayout.BeginHorizontal(); |
||||||
|
EditorGUILayout.PrefixLabel(new GUIContent("On Event")); |
||||||
|
executeHandler.executeMethods = (ExecuteHandler.ExecuteMethod)EditorGUILayout.EnumMaskField(executeHandler.executeMethods, |
||||||
|
EditorStyles.popup, |
||||||
|
GUILayout.ExpandWidth(false)); |
||||||
|
EditorGUILayout.EndHorizontal(); |
||||||
|
|
||||||
|
if (executeHandler.IsExecuteMethodSelected(ExecuteHandler.ExecuteMethod.AfterPeriodOfTime)) |
||||||
|
{ |
||||||
|
DrawOptionsForAfterPeriodOfTime(executeHandler); |
||||||
|
} |
||||||
|
|
||||||
|
if (executeHandler.IsExecuteMethodSelected(ExecuteHandler.ExecuteMethod.Update)) |
||||||
|
{ |
||||||
|
DrawOptionsForOnUpdate(executeHandler); |
||||||
|
} |
||||||
|
|
||||||
|
if (Application.isPlaying) |
||||||
|
{ |
||||||
|
EditorGUILayout.BeginHorizontal(); |
||||||
|
GUILayout.FlexibleSpace(); |
||||||
|
|
||||||
|
if (GUILayout.Button(new GUIContent("Execute Now", "Execute the script immediately."))) |
||||||
|
{ |
||||||
|
executeHandler.Execute(); |
||||||
|
} |
||||||
|
|
||||||
|
GUILayout.FlexibleSpace(); |
||||||
|
EditorGUILayout.EndHorizontal(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void DrawOptionsForAfterPeriodOfTime(ExecuteHandler executeHandler) |
||||||
|
{ |
||||||
|
EditorGUILayout.Space(); |
||||||
|
executeHandler.executeAfterTime = EditorGUILayout.FloatField(m_GUIExecuteAfterTimeGuiContent, |
||||||
|
executeHandler.executeAfterTime); |
||||||
|
if (executeHandler.executeAfterTime < 0) |
||||||
|
executeHandler.executeAfterTime = 0; |
||||||
|
executeHandler.repeatExecuteTime = EditorGUILayout.Toggle(m_GUIRepeatExecuteTimeGuiContent, |
||||||
|
executeHandler.repeatExecuteTime); |
||||||
|
if (executeHandler.repeatExecuteTime) |
||||||
|
{ |
||||||
|
executeHandler.repeatEveryTime = EditorGUILayout.FloatField(m_GUIRepeatEveryTimeGuiContent, |
||||||
|
executeHandler.repeatEveryTime); |
||||||
|
if (executeHandler.repeatEveryTime < 0) |
||||||
|
executeHandler.repeatEveryTime = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void DrawOptionsForOnUpdate(ExecuteHandler executeHandler) |
||||||
|
{ |
||||||
|
EditorGUILayout.Space(); |
||||||
|
executeHandler.executeAfterFrames = EditorGUILayout.IntField(m_GUIExecuteAfterFramesGuiContent, |
||||||
|
executeHandler.executeAfterFrames); |
||||||
|
if (executeHandler.executeAfterFrames < 1) |
||||||
|
executeHandler.executeAfterFrames = 1; |
||||||
|
executeHandler.repeatExecuteFrame = EditorGUILayout.Toggle(m_GUIRepeatExecuteFrameGuiContent, |
||||||
|
executeHandler.repeatExecuteFrame); |
||||||
|
if (executeHandler.repeatExecuteFrame) |
||||||
|
{ |
||||||
|
executeHandler.repeatEveryFrame = EditorGUILayout.IntField(m_GUIRepeatEveryTimeGuiContent, |
||||||
|
executeHandler.repeatEveryFrame); |
||||||
|
if (executeHandler.repeatEveryFrame < 1) |
||||||
|
executeHandler.repeatEveryFrame = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 433a5aec1adda4a86a0022cde6487aa9 |
||||||
|
timeCreated: 1460475473 |
||||||
|
licenseType: Free |
||||||
|
MonoImporter: |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
@ -0,0 +1,293 @@ |
|||||||
|
// Adapted from the Unity Test Tools project (MIT license) |
||||||
|
// https://bitbucket.org/Unity-Technologies/unitytesttools/src/a30d562427e9/Assets/UnityTestTools/ |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Diagnostics; |
||||||
|
using System.Linq; |
||||||
|
using UnityEngine; |
||||||
|
using MoonSharp.Interpreter; |
||||||
|
using Debug = UnityEngine.Debug; |
||||||
|
using Object = UnityEngine.Object; |
||||||
|
|
||||||
|
namespace Fungus |
||||||
|
{ |
||||||
|
|
||||||
|
[Serializable] |
||||||
|
public class ExecuteHandler : MonoBehaviour, IExecuteHandlerConfigurator |
||||||
|
{ |
||||||
|
[Flags] |
||||||
|
public enum ExecuteMethod |
||||||
|
{ |
||||||
|
AfterPeriodOfTime = 1 << 0, |
||||||
|
Start = 1 << 1, |
||||||
|
Update = 1 << 2, |
||||||
|
FixedUpdate = 1 << 3, |
||||||
|
LateUpdate = 1 << 4, |
||||||
|
OnDestroy = 1 << 5, |
||||||
|
OnEnable = 1 << 6, |
||||||
|
OnDisable = 1 << 7, |
||||||
|
OnControllerColliderHit = 1 << 8, |
||||||
|
OnParticleCollision = 1 << 9, |
||||||
|
OnJointBreak = 1 << 10, |
||||||
|
OnBecameInvisible = 1 << 11, |
||||||
|
OnBecameVisible = 1 << 12, |
||||||
|
OnTriggerEnter = 1 << 13, |
||||||
|
OnTriggerExit = 1 << 14, |
||||||
|
OnTriggerStay = 1 << 15, |
||||||
|
OnCollisionEnter = 1 << 16, |
||||||
|
OnCollisionExit = 1 << 17, |
||||||
|
OnCollisionStay = 1 << 18, |
||||||
|
OnTriggerEnter2D = 1 << 19, |
||||||
|
OnTriggerExit2D = 1 << 20, |
||||||
|
OnTriggerStay2D = 1 << 21, |
||||||
|
OnCollisionEnter2D = 1 << 22, |
||||||
|
OnCollisionExit2D = 1 << 23, |
||||||
|
OnCollisionStay2D = 1 << 24, |
||||||
|
} |
||||||
|
|
||||||
|
[SerializeField] public float executeAfterTime = 1f; |
||||||
|
[SerializeField] public bool repeatExecuteTime = true; |
||||||
|
[SerializeField] public float repeatEveryTime = 1f; |
||||||
|
[SerializeField] public int executeAfterFrames = 1; |
||||||
|
[SerializeField] public bool repeatExecuteFrame = true; |
||||||
|
[SerializeField] public int repeatEveryFrame = 1; |
||||||
|
[SerializeField] public bool hasFailed; |
||||||
|
|
||||||
|
[SerializeField] public ExecuteMethod executeMethods = ExecuteMethod.Start; |
||||||
|
|
||||||
|
private int m_ExecuteOnFrame; |
||||||
|
|
||||||
|
// Recursively build the full hierarchy path to this game object |
||||||
|
private static string GetPath(Transform current) |
||||||
|
{ |
||||||
|
if (current.parent == null) |
||||||
|
{ |
||||||
|
return current.name; |
||||||
|
} |
||||||
|
return GetPath(current.parent) + "." + current.name; |
||||||
|
} |
||||||
|
|
||||||
|
public void Start() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.Start); |
||||||
|
|
||||||
|
if (IsExecuteMethodSelected(ExecuteMethod.AfterPeriodOfTime)) |
||||||
|
{ |
||||||
|
StartCoroutine(ExecutePeriodically()); |
||||||
|
} |
||||||
|
if (IsExecuteMethodSelected(ExecuteMethod.Update)) |
||||||
|
{ |
||||||
|
m_ExecuteOnFrame = Time.frameCount + executeAfterFrames; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public IEnumerator ExecutePeriodically() |
||||||
|
{ |
||||||
|
yield return new WaitForSeconds(executeAfterTime); |
||||||
|
Execute(ExecuteMethod.AfterPeriodOfTime); |
||||||
|
while (repeatExecuteTime) |
||||||
|
{ |
||||||
|
yield return new WaitForSeconds(repeatEveryTime); |
||||||
|
Execute(ExecuteMethod.AfterPeriodOfTime); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public bool ShouldExecuteOnFrame() |
||||||
|
{ |
||||||
|
if (Time.frameCount > m_ExecuteOnFrame) |
||||||
|
{ |
||||||
|
if (repeatExecuteFrame) |
||||||
|
m_ExecuteOnFrame += repeatEveryFrame; |
||||||
|
else |
||||||
|
m_ExecuteOnFrame = Int32.MaxValue; |
||||||
|
return true; |
||||||
|
} |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public void OnDisable() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnDisable); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnEnable() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnEnable); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnDestroy() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnDestroy); |
||||||
|
} |
||||||
|
|
||||||
|
public void Update() |
||||||
|
{ |
||||||
|
if (IsExecuteMethodSelected(ExecuteMethod.Update) && ShouldExecuteOnFrame()) |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.Update); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void FixedUpdate() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.FixedUpdate); |
||||||
|
} |
||||||
|
|
||||||
|
public void LateUpdate() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.LateUpdate); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnControllerColliderHit() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnControllerColliderHit); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnParticleCollision() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnParticleCollision); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnJointBreak() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnJointBreak); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnBecameInvisible() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnBecameInvisible); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnBecameVisible() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnBecameVisible); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnTriggerEnter() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnTriggerEnter); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnTriggerExit() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnTriggerExit); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnTriggerStay() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnTriggerStay); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnCollisionEnter() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnCollisionEnter); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnCollisionExit() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnCollisionExit); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnCollisionStay() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnCollisionStay); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnTriggerEnter2D() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnTriggerEnter2D); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnTriggerExit2D() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnTriggerExit2D); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnTriggerStay2D() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnTriggerStay2D); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnCollisionEnter2D() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnCollisionEnter2D); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnCollisionExit2D() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnCollisionExit2D); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnCollisionStay2D() |
||||||
|
{ |
||||||
|
Execute(ExecuteMethod.OnCollisionStay2D); |
||||||
|
} |
||||||
|
|
||||||
|
private void Execute(ExecuteMethod executeMethod) |
||||||
|
{ |
||||||
|
if (IsExecuteMethodSelected(executeMethod)) |
||||||
|
{ |
||||||
|
Execute(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public bool IsExecuteMethodSelected(ExecuteMethod method) |
||||||
|
{ |
||||||
|
return method == (executeMethods & method); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Execute the Lua script immediately. |
||||||
|
/// This is the function to call if you want to trigger execution from an external script. |
||||||
|
/// </summary> |
||||||
|
public virtual void Execute() |
||||||
|
{ |
||||||
|
// Call any OnExecute methods in components on this gameobject |
||||||
|
SendMessage("OnExecute", SendMessageOptions.DontRequireReceiver); |
||||||
|
} |
||||||
|
|
||||||
|
#region AssertionComponentConfigurator |
||||||
|
public int UpdateExecuteStartOnFrame { set { executeAfterFrames = value; } } |
||||||
|
public int UpdateExecuteRepeatFrequency { set { repeatEveryFrame = value; } } |
||||||
|
public bool UpdateExecuteRepeat { set { repeatExecuteFrame = value; } } |
||||||
|
public float TimeExecuteStartAfter { set { executeAfterTime = value; } } |
||||||
|
public float TimeExecuteRepeatFrequency { set { repeatEveryTime = value; } } |
||||||
|
public bool TimeExecuteRepeat { set { repeatExecuteTime = value; } } |
||||||
|
public ExecuteHandler Component { get { return this; } } |
||||||
|
#endregion |
||||||
|
} |
||||||
|
|
||||||
|
public interface IExecuteHandlerConfigurator |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// If the assertion is evaluated in Update, after how many frame should the evaluation start. Defult is 1 (first frame) |
||||||
|
/// </summary> |
||||||
|
int UpdateExecuteStartOnFrame { set; } |
||||||
|
/// <summary> |
||||||
|
/// If the assertion is evaluated in Update and UpdateExecuteRepeat is true, how many frame should pass between evaluations |
||||||
|
/// </summary> |
||||||
|
int UpdateExecuteRepeatFrequency { set; } |
||||||
|
/// <summary> |
||||||
|
/// If the assertion is evaluated in Update, should the evaluation be repeated after UpdateExecuteRepeatFrequency frames |
||||||
|
/// </summary> |
||||||
|
bool UpdateExecuteRepeat { set; } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// If the assertion is evaluated after a period of time, after how many seconds the first evaluation should be done |
||||||
|
/// </summary> |
||||||
|
float TimeExecuteStartAfter { set; } |
||||||
|
/// <summary> |
||||||
|
/// If the assertion is evaluated after a period of time and TimeExecuteRepeat is true, after how many seconds should the next evaluation happen |
||||||
|
/// </summary> |
||||||
|
float TimeExecuteRepeatFrequency { set; } |
||||||
|
/// <summary> |
||||||
|
/// If the assertion is evaluated after a period, should the evaluation happen again after TimeExecuteRepeatFrequency seconds |
||||||
|
/// </summary> |
||||||
|
bool TimeExecuteRepeat { set; } |
||||||
|
|
||||||
|
ExecuteHandler Component { get; } |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
fileFormatVersion: 2 |
||||||
|
guid: 6ee79785811ba49399c1b56d7309e3df |
||||||
|
timeCreated: 1460474888 |
||||||
|
licenseType: Free |
||||||
|
MonoImporter: |
||||||
|
serializedVersion: 2 |
||||||
|
defaultReferences: [] |
||||||
|
executionOrder: 0 |
||||||
|
icon: {instanceID: 0} |
||||||
|
userData: |
||||||
|
assetBundleName: |
||||||
|
assetBundleVariant: |
Loading…
Reference in new issue