// This code is part of the Fungus library (https://github.com/snozbot/fungus)
// It is released for free under the MIT open source license (https://github.com/snozbot/fungus/blob/master/LICENSE)
using UnityEngine;
using MoonSharp.Interpreter;
namespace Fungus
{
///
/// Executes a Lua code chunk using a Lua Environment.
///
[CommandInfo("Scripting",
"Execute Lua",
"Executes a Lua code chunk using a Lua Environment.")]
public class ExecuteLua : Command
{
[Tooltip("Lua Environment to use to execute this Lua script")]
[SerializeField] protected LuaEnvironment luaEnvironment;
[Tooltip("A text file containing Lua script to execute.")]
[SerializeField] protected TextAsset luaFile;
[TextArea(10,100)]
[Tooltip("Lua script to execute. This text is appended to the contents of Lua file (if one is specified).")]
[SerializeField] protected string luaScript;
[Tooltip("Execute this Lua script as a Lua coroutine")]
[SerializeField] protected bool runAsCoroutine = true;
[Tooltip("Pause command execution until the Lua script has finished execution")]
[SerializeField] protected bool waitUntilFinished = true;
[Tooltip("A Flowchart variable to store the returned value in.")]
[VariableProperty()]
[SerializeField] protected Variable returnVariable;
protected string friendlyName = "";
protected bool initialised;
// Stores the compiled Lua code for fast execution later.
protected Closure luaFunction;
protected virtual void Start()
{
InitExecuteLua();
}
///
/// Initialises the Lua environment and compiles the Lua string for execution later on.
///
protected virtual void InitExecuteLua()
{
if (initialised)
{
return;
}
// Cache a descriptive name to use in Lua error messages
friendlyName = gameObject.name + "." + ParentBlock.BlockName + "." + "ExecuteLua #" + CommandIndex.ToString();
var flowchart = GetFlowchart();
// See if a Lua Environment has been assigned to this Flowchart
if (luaEnvironment == null)
{
luaEnvironment = flowchart.LuaEnv;
}
if (luaEnvironment == null)
{
// No Lua Environment specified so just use any available or create one.
luaEnvironment = LuaEnvironment.GetLua();
}
string s = GetLuaString();
luaFunction = luaEnvironment.LoadLuaFunction(s, friendlyName);
// Add a binding to the parent flowchart
if (flowchart.LuaBindingName != "")
{
Table globals = luaEnvironment.Interpreter.Globals;
if (globals != null)
{
globals[flowchart.LuaBindingName] = flowchart;
}
}
// Always initialise when playing in the editor.
// Allows the user to edit the Lua script while the game is playing.
if ( !(Application.isPlaying && Application.isEditor) )
{
initialised = true;
}
}
protected virtual string GetLuaString()
{
if (luaFile == null)
{
return luaScript;
}
return luaFile.text + "\n" + luaScript;
}
protected virtual void StoreReturnVariable(DynValue returnValue)
{
if (returnVariable == null || returnValue == null)
{
return;
}
// Store the return value in a Fungus Variable
System.Type variableType = returnVariable.GetType();
if (variableType == typeof(BooleanVariable) && returnValue.Type == DataType.Boolean)
{
(returnVariable as BooleanVariable).Value = returnValue.Boolean;
}
else if (variableType == typeof(IntegerVariable) && returnValue.Type == DataType.Number)
{
(returnVariable as IntegerVariable).Value = (int)returnValue.Number;
}
else if (variableType == typeof(FloatVariable) && returnValue.Type == DataType.Number)
{
(returnVariable as FloatVariable).Value = (float)returnValue.Number;
}
else if (variableType == typeof(StringVariable) && returnValue.Type == DataType.String)
{
(returnVariable as StringVariable).Value = returnValue.String;
}
else if (variableType == typeof(ColorVariable) && returnValue.Type == DataType.UserData)
{
(returnVariable as ColorVariable).Value = returnValue.CheckUserDataType("ExecuteLua.StoreReturnVariable");
}
else if (variableType == typeof(GameObjectVariable) && returnValue.Type == DataType.UserData)
{
(returnVariable as GameObjectVariable).Value = returnValue.CheckUserDataType("ExecuteLua.StoreReturnVariable");
}
else if (variableType == typeof(MaterialVariable) && returnValue.Type == DataType.UserData)
{
(returnVariable as MaterialVariable).Value = returnValue.CheckUserDataType("ExecuteLua.StoreReturnVariable");
}
else if (variableType == typeof(ObjectVariable) && returnValue.Type == DataType.UserData)
{
(returnVariable as ObjectVariable).Value = returnValue.CheckUserDataType