Browse Source

Refactored LuaEnvironment to use ILuaEnvironment interface

master
Christopher 9 years ago
parent
commit
501cb34247
  1. 2
      Assets/Fungus/Flowchart/Scripts/Flowchart.cs
  2. 13
      Assets/Fungus/Lua/Scripts/Commands/ExecuteLua.cs
  3. 8
      Assets/Fungus/Lua/Scripts/LuaExtensions.cs
  4. 44
      Assets/Fungus/Thirdparty/FungusLua/Scripts/ILuaEnvironment.cs
  5. 12
      Assets/Fungus/Thirdparty/FungusLua/Scripts/ILuaEnvironment.cs.meta
  6. 9
      Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaBindings.cs
  7. 265
      Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaEnvironment.cs
  8. 21
      Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaScript.cs
  9. 4
      Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaStore.cs
  10. 32
      Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaUtils.cs

2
Assets/Fungus/Flowchart/Scripts/Flowchart.cs

@ -172,7 +172,7 @@ namespace Fungus
/// </summary>
[Tooltip("Lua Environment to be used by default for all Execute Lua commands in this Flowchart")]
[SerializeField] protected LuaEnvironment luaEnvironment;
public virtual LuaEnvironment _LuaEnvironment { get { return luaEnvironment; } }
public virtual ILuaEnvironment LuaEnv { get { return luaEnvironment; } }
/// <summary>
/// The ExecuteLua command adds a global Lua variable with this name bound to the flowchart prior to executing.

13
Assets/Fungus/Lua/Scripts/Commands/ExecuteLua.cs

@ -17,6 +17,7 @@ namespace Fungus
{
[Tooltip("Lua Environment to use to execute this Lua script")]
[SerializeField] protected LuaEnvironment luaEnvironment;
public ILuaEnvironment LuaEnv { set; get; }
[Tooltip("A text file containing Lua script to execute.")]
[SerializeField] protected TextAsset luaFile;
@ -65,22 +66,22 @@ namespace Fungus
// See if a Lua Environment has been assigned to this Flowchart
if (luaEnvironment == null)
{
luaEnvironment = flowchart._LuaEnvironment;
LuaEnv = flowchart.LuaEnv;
}
// No Lua Environment specified so just use any available or create one.
if (luaEnvironment == null)
if (LuaEnv == null)
{
luaEnvironment = LuaEnvironment.GetLua();
LuaEnv = LuaEnvironment.GetLua();
}
string s = GetLuaString();
luaFunction = luaEnvironment.LoadLuaString(s, friendlyName);
luaFunction = LuaEnv.LoadLuaFunction(s, friendlyName);
// Add a binding to the parent flowchart
if (flowchart.LuaBindingName != "")
{
Table globals = luaEnvironment.Interpreter.Globals;
Table globals = LuaEnv.Interpreter.Globals;
if (globals != null)
{
globals[flowchart.LuaBindingName] = flowchart;
@ -115,7 +116,7 @@ namespace Fungus
Continue();
}
luaEnvironment.RunLuaFunction(luaFunction, runAsCoroutine, (returnValue) => {
LuaEnv.RunLuaFunction(luaFunction, runAsCoroutine, (returnValue) => {
StoreReturnVariable(returnValue);
if (waitUntilFinished)
{

8
Assets/Fungus/Lua/Scripts/LuaExtensions.cs

@ -16,7 +16,7 @@ namespace Fungus
/// <summary>
/// Extension for MenuDialog that allows AddOption to call a Lua function when an option is selected.
/// </summary>
public static bool AddOption(this MenuDialog menuDialog, string text, bool interactable, LuaEnvironment luaEnvironment, Closure callBack)
public static bool AddOption(this MenuDialog menuDialog, string text, bool interactable, ILuaEnvironment luaEnv, Closure callBack)
{
if (!menuDialog.gameObject.activeSelf)
{
@ -46,7 +46,7 @@ namespace Fungus
if (callBack != null)
{
luaEnvironment.RunLuaFunction(callBack, true);
luaEnv.RunLuaFunction(callBack, true);
}
});
@ -61,7 +61,7 @@ namespace Fungus
/// <summary>
/// Extension for MenuDialog that allows ShowTimer to call a Lua function when the timer expires.
/// </summary>
public static IEnumerator ShowTimer(this MenuDialog menuDialog, float duration, LuaEnvironment luaEnvironment, Closure callBack)
public static IEnumerator ShowTimer(this MenuDialog menuDialog, float duration, ILuaEnvironment luaEnv, Closure callBack)
{
if (menuDialog.CachedSlider == null ||
duration <= 0f)
@ -94,7 +94,7 @@ namespace Fungus
if (callBack != null)
{
luaEnvironment.RunLuaFunction(callBack, true);
luaEnv.RunLuaFunction(callBack, true);
}
}
}

44
Assets/Fungus/Thirdparty/FungusLua/Scripts/ILuaEnvironment.cs vendored

@ -0,0 +1,44 @@
using MoonSharp.Interpreter;
namespace Fungus
{
/// <summary>
/// Wrapper for a MoonSharp Lua Script instance.
/// </summary>
public interface ILuaEnvironment
{
/// <summary>
/// Initialise the Lua interpreter so we can start running Lua code.
/// </summary>
void InitEnvironment();
/// <summary>
/// The MoonSharp interpreter instance used to run Lua code.
/// </summary>
Script Interpreter { get; }
/// <summary>
/// Loads and compiles a string containing Lua script, returning a closure (Lua function) which can be executed later.
/// <param name="luaString">The Lua code to be run.</param>
/// <param name="friendlyName">A descriptive name to be used in error reports.</param>
/// </summary>
Closure LoadLuaFunction(string luaString, string friendlyName);
/// <summary>
/// Load and run a previously compiled Lua script. May be run as a coroutine.
/// <param name="fn">A previously compiled Lua function.</param>
/// <param name="runAsCoroutine">Run the Lua code as a coroutine to support asynchronous operations.</param>
/// <param name="onComplete">Method to callback when the Lua code finishes exection. Supports return parameters.</param>
/// </summary>
void RunLuaFunction(Closure fn, bool runAsCoroutine, System.Action<DynValue> onComplete = null);
/// <summary>
/// Load and run a string containing Lua script. May be run as a coroutine.
/// <param name="luaString">The Lua code to be run.</param>
/// <param name="friendlyName">A descriptive name to be used in error reports.</param>
/// <param name="runAsCoroutine">Run the Lua code as a coroutine to support asynchronous operations.</param>
/// <param name="onComplete">Method to callback when the Lua code finishes exection. Supports return parameters.</param>
/// </summary>
void DoLuaString(string luaString, string friendlyName, bool runAsCoroutine, System.Action<DynValue> onComplete = null);
}
}

12
Assets/Fungus/Thirdparty/FungusLua/Scripts/ILuaEnvironment.cs.meta vendored

@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: 73324073029d844479927d75293a9c38
timeCreated: 1473436184
licenseType: Free
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaBindings.cs vendored

@ -18,7 +18,7 @@ namespace Fungus
/// <summary>
/// Add all declared bindings to the globals table.
/// </summary>
public abstract void AddBindings(LuaEnvironment luaEnvironment);
public abstract void AddBindings(ILuaEnvironment luaEnv);
}
/// <summary>
@ -43,6 +43,7 @@ namespace Fungus
[Tooltip("The specific LuaEnvironment to register the bindings in.")]
[SerializeField] protected LuaEnvironment luaEnvironment;
public ILuaEnvironment LuaEnv { get; set; }
/// <summary>
/// Name of global table variable to store bindings in. If left blank then each binding will be added as a global variable.
@ -81,16 +82,16 @@ namespace Fungus
/// <summary>
/// Add all declared bindings to the globals table.
/// </summary>
public override void AddBindings(LuaEnvironment _luaEnvironment)
public override void AddBindings(ILuaEnvironment luaEnv)
{
if (!allEnvironments &&
luaEnvironment != _luaEnvironment)
!luaEnvironment.Equals(luaEnv))
{
// Don't add bindings to this environment
return;
}
MoonSharp.Interpreter.Script interpreter = _luaEnvironment.Interpreter;
MoonSharp.Interpreter.Script interpreter = luaEnv.Interpreter;
Table globals = interpreter.Globals;
Table bindingsTable = null;

265
Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaEnvironment.cs vendored

@ -6,7 +6,6 @@ using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
using System.Diagnostics;
using MoonSharp.Interpreter;
using MoonSharp.Interpreter.Loaders;
using MoonSharp.RemoteDebugger;
@ -16,7 +15,7 @@ namespace Fungus
/// <summary>
/// Wrapper for a MoonSharp Lua Script instance.
/// </summary>
public class LuaEnvironment : MonoBehaviour
public class LuaEnvironment : MonoBehaviour, ILuaEnvironment
{
/// <summary>
/// Helper class used to extend the initialization behavior of LuaEnvironment.
@ -86,29 +85,24 @@ namespace Fungus
/// Returns the first Lua Environment found in the scene, or creates one if none exists.
/// This is a slow operation, call it once at startup and cache the returned value.
/// </summary>
public static LuaEnvironment GetLua()
public static ILuaEnvironment GetLua()
{
LuaEnvironment luaEnvironment = GameObject.FindObjectOfType<LuaEnvironment>();
if (luaEnvironment == null)
ILuaEnvironment luaEnv = GameObject.FindObjectOfType<LuaEnvironment>();
if (luaEnv == null)
{
GameObject prefab = Resources.Load<GameObject>("Prefabs/LuaEnvironment");
if (prefab != null)
{
GameObject go = Instantiate(prefab) as GameObject;
go.name = "LuaEnvironment";
luaEnvironment = go.GetComponent<LuaEnvironment>();
luaEnv = go.GetComponent<ILuaEnvironment>();
}
}
return luaEnvironment;
return luaEnv;
}
protected Script interpreter;
/// <summary>
/// The MoonSharp interpreter instance used to run Lua code.
/// </summary>
public virtual Script Interpreter { get { return interpreter; } }
/// <summary>
/// Launches the remote Lua debugger in your browser and breaks execution at the first executed Lua command.
/// </summary>
@ -130,40 +124,6 @@ namespace Fungus
InitEnvironment();
}
/// <summary>
/// Initialise the Lua interpreter so we can start running Lua code.
/// </summary>
public virtual void InitEnvironment()
{
if (initialised)
{
return;
}
Script.DefaultOptions.DebugPrint = (s) => { UnityEngine.Debug.Log(s); };
// In some use cases (e.g. downloadable Lua files) some Lua modules can pose a potential security risk.
// You can restrict which core lua modules are available here if needed. See the MoonSharp documentation for details.
interpreter = new Script(CoreModules.Preset_Complete);
// Load all Lua scripts in the project
InitLuaScriptFiles();
// Initialize any attached initializer components (e.g. LuaUtils)
Initializer[] initializers = GetComponents<Initializer>();
foreach (Initializer initializer in initializers)
{
initializer.Initialize();
}
if (remoteDebugger)
{
ActivateRemoteDebugger(interpreter);
}
initialised = true;
}
/// <summary>
/// Register all Lua files in the project so they can be accessed at runtime.
/// </summary>
@ -211,102 +171,6 @@ namespace Fungus
}
}
/// <summary>
/// Loads and compiles a string containing Lua script, returning a closure (Lua function) which can be executed later.
/// <param name="luaString">The Lua code to be run.</param>
/// <param name="friendlyName">A descriptive name to be used in error reports.</param>
/// </summary>
public virtual Closure LoadLuaString(string luaString, string friendlyName)
{
InitEnvironment();
string processedString;
Initializer initializer = GetComponent<Initializer>();
if (initializer != null)
{
processedString = initializer.PreprocessScript(luaString);
}
else
{
processedString = luaString;
}
// Load the Lua script
DynValue res = null;
try
{
res = interpreter.LoadString(processedString, null, friendlyName);
}
catch (InterpreterException ex)
{
LogException(ex.DecoratedMessage, luaString);
}
if (res == null ||
res.Type != DataType.Function)
{
UnityEngine.Debug.LogError("Failed to create Lua function from Lua string");
return null;
}
return res.Function;
}
/// <summary>
/// Load and run a previously compiled Lua script. May be run as a coroutine.
/// <param name="fn">A previously compiled Lua function.</param>
/// <param name="runAsCoroutine">Run the Lua code as a coroutine to support asynchronous operations.</param>
/// <param name="onComplete">Method to callback when the Lua code finishes exection. Supports return parameters.</param>
/// </summary>
public virtual void RunLuaFunction(Closure fn, bool runAsCoroutine, Action<DynValue> onComplete = null)
{
if (fn == null)
{
if (onComplete != null)
{
onComplete(null);
}
return;
}
// Execute the Lua script
if (runAsCoroutine)
{
StartCoroutine(RunLuaCoroutine(fn, onComplete));
}
else
{
DynValue returnValue = null;
try
{
returnValue = fn.Call();
}
catch (InterpreterException ex)
{
LogException(ex.DecoratedMessage, GetSourceCode());
}
if (onComplete != null)
{
onComplete(returnValue);
}
}
}
/// <summary>
/// Load and run a string containing Lua script. May be run as a coroutine.
/// <param name="luaString">The Lua code to be run.</param>
/// <param name="friendlyName">A descriptive name to be used in error reports.</param>
/// <param name="runAsCoroutine">Run the Lua code as a coroutine to support asynchronous operations.</param>
/// <param name="onComplete">Method to callback when the Lua code finishes exection. Supports return parameters.</param>
/// </summary>
public virtual void DoLuaString(string luaString, string friendlyName, bool runAsCoroutine, Action<DynValue> onComplete = null)
{
Closure fn = LoadLuaString(luaString, friendlyName);
RunLuaFunction(fn, runAsCoroutine, onComplete);
}
/// <summary>
/// A Unity coroutine method which updates a Lua coroutine each frame.
/// <param name="closure">A MoonSharp closure object representing a function.</param>
@ -406,7 +270,7 @@ namespace Fungus
/// </summary>
/// <param name="decoratedMessage">Decorated message from a MoonSharp exception</param>
/// <param name="debugInfo">Debug info, usually the Lua script that was running.</param>
public static void LogException(string decoratedMessage, string debugInfo)
protected static void LogException(string decoratedMessage, string debugInfo)
{
string output = decoratedMessage + "\n";
@ -423,5 +287,120 @@ namespace Fungus
UnityEngine.Debug.LogError(output);
}
#region ILuaEnvironment implementation
public virtual void InitEnvironment()
{
if (initialised)
{
return;
}
Script.DefaultOptions.DebugPrint = (s) => { UnityEngine.Debug.Log(s); };
// In some use cases (e.g. downloadable Lua files) some Lua modules can pose a potential security risk.
// You can restrict which core lua modules are available here if needed. See the MoonSharp documentation for details.
interpreter = new Script(CoreModules.Preset_Complete);
// Load all Lua scripts in the project
InitLuaScriptFiles();
// Initialize any attached initializer components (e.g. LuaUtils)
Initializer[] initializers = GetComponents<Initializer>();
foreach (Initializer initializer in initializers)
{
initializer.Initialize();
}
if (remoteDebugger)
{
ActivateRemoteDebugger(interpreter);
}
initialised = true;
}
public virtual Script Interpreter { get { return interpreter; } }
public virtual Closure LoadLuaFunction(string luaString, string friendlyName)
{
InitEnvironment();
string processedString;
Initializer initializer = GetComponent<Initializer>();
if (initializer != null)
{
processedString = initializer.PreprocessScript(luaString);
}
else
{
processedString = luaString;
}
// Load the Lua script
DynValue res = null;
try
{
res = interpreter.LoadString(processedString, null, friendlyName);
}
catch (InterpreterException ex)
{
LogException(ex.DecoratedMessage, luaString);
}
if (res == null ||
res.Type != DataType.Function)
{
UnityEngine.Debug.LogError("Failed to create Lua function from Lua string");
return null;
}
return res.Function;
}
public virtual void RunLuaFunction(Closure fn, bool runAsCoroutine, Action<DynValue> onComplete = null)
{
if (fn == null)
{
if (onComplete != null)
{
onComplete(null);
}
return;
}
// Execute the Lua script
if (runAsCoroutine)
{
StartCoroutine(RunLuaCoroutine(fn, onComplete));
}
else
{
DynValue returnValue = null;
try
{
returnValue = fn.Call();
}
catch (InterpreterException ex)
{
LogException(ex.DecoratedMessage, GetSourceCode());
}
if (onComplete != null)
{
onComplete(returnValue);
}
}
}
public virtual void DoLuaString(string luaString, string friendlyName, bool runAsCoroutine, Action<DynValue> onComplete = null)
{
Closure fn = LoadLuaFunction(luaString, friendlyName);
RunLuaFunction(fn, runAsCoroutine, onComplete);
}
#endregion
}
}

21
Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaScript.cs vendored

@ -21,6 +21,7 @@ namespace Fungus
/// </summary>
[Tooltip("The Lua Environment to use when executing Lua script.")]
[SerializeField] protected LuaEnvironment luaEnvironment;
protected ILuaEnvironment LuaEnv { get; set; }
/// <summary>
/// Text file containing Lua script to be executed.
@ -76,26 +77,32 @@ namespace Fungus
return;
}
if (luaEnvironment == null)
if (LuaEnv == null &&
luaEnvironment != null)
{
LuaEnv = luaEnvironment as ILuaEnvironment;
}
if (LuaEnv == null)
{
// Create a Lua Environment if none exists yet
luaEnvironment = LuaEnvironment.GetLua();
LuaEnv = LuaEnvironment.GetLua();
}
if (luaEnvironment == null)
if (LuaEnv == null)
{
Debug.LogError("No Lua Environment found");
return;
}
// Ensure the LuaEnvironment is initialized before trying to execute code
luaEnvironment.InitEnvironment();
LuaEnv.InitEnvironment();
// Cache a descriptive name to use in Lua error messages
friendlyName = GetPath(transform) + ".LuaScript";
string s = GetLuaString();
luaFunction = luaEnvironment.LoadLuaString(s, friendlyName);
luaFunction = LuaEnv.LoadLuaFunction(s, friendlyName);
initialised = true;
}
@ -130,13 +137,13 @@ namespace Fungus
// Make sure the script and Lua environment are initialised before executing
InitLuaScript();
if (luaEnvironment == null)
if (LuaEnv == null)
{
Debug.LogWarning("No Lua Environment found");
}
else
{
luaEnvironment.RunLuaFunction(luaFunction, runAsCoroutine);
LuaEnv.RunLuaFunction(luaFunction, runAsCoroutine);
}
}
}

4
Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaStore.cs vendored

@ -70,14 +70,14 @@ namespace Fungus
/// <summary>
/// Callback to bind this LuaStore component with the "unity" table in a LuaEnvironment component.
/// </summary>
public override void AddBindings(LuaEnvironment luaEnvironment)
public override void AddBindings(ILuaEnvironment luaEnv)
{
if (!Init())
{
return;
}
MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter;
MoonSharp.Interpreter.Script interpreter = luaEnv.Interpreter;
Table globals = interpreter.Globals;
if (globals == null)

32
Assets/Fungus/Thirdparty/FungusLua/Scripts/LuaUtils.cs vendored

@ -65,7 +65,7 @@ namespace Fungus
/// <summary>
/// Cached reference to the Lua Environment component.
/// </summary>
protected LuaEnvironment luaEnvironment;
protected ILuaEnvironment LuaEnv { get; set; }
protected StringSubstituter stringSubstituter;
@ -76,16 +76,16 @@ namespace Fungus
/// </summary>
public override void Initialize()
{
luaEnvironment = GetComponent<LuaEnvironment>();
if (luaEnvironment == null)
LuaEnv = GetComponent<ILuaEnvironment>();
if (LuaEnv == null)
{
UnityEngine.Debug.LogError("No Lua Environment found");
Debug.LogError("No Lua Environment found");
return;
}
if (luaEnvironment.Interpreter == null)
if (LuaEnv.Interpreter == null)
{
UnityEngine.Debug.LogError("No Lua interpreter found");
Debug.LogError("No Lua interpreter found");
return;
}
@ -185,7 +185,7 @@ namespace Fungus
LuaBindingsBase[] bindings = GameObject.FindObjectsOfType<LuaBindingsBase>();
foreach (LuaBindingsBase binding in bindings)
{
binding.AddBindings(luaEnvironment);
binding.AddBindings(LuaEnv);
}
}
@ -201,7 +201,7 @@ namespace Fungus
return;
}
MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter;
MoonSharp.Interpreter.Script interpreter = LuaEnv.Interpreter;
// Require the Fungus module and assign it to the global 'fungus'
Table fungusTable = null;
@ -225,7 +225,7 @@ namespace Fungus
fungusTable["factory"] = UserData.CreateStatic(typeof(PODTypeFactory));
// Lua Environment and Lua Utils components
fungusTable["luaenvironment"] = luaEnvironment;
fungusTable["luaenvironment"] = LuaEnv;
fungusTable["luautils"] = this;
// Provide access to the Unity Test Tools (if available).
@ -339,28 +339,28 @@ namespace Fungus
{
// This method could be called from the Start of another component, so
// we need to ensure that the LuaEnvironment has been initialized.
if (luaEnvironment == null)
if (LuaEnv == null)
{
luaEnvironment = GetComponent<LuaEnvironment>();
if (luaEnvironment != null)
LuaEnv = GetComponent<ILuaEnvironment>();
if (LuaEnv != null)
{
luaEnvironment.InitEnvironment();
LuaEnv.InitEnvironment();
}
}
if (luaEnvironment == null)
if (LuaEnv == null)
{
UnityEngine.Debug.LogError("No Lua Environment found");
return false;
}
if (luaEnvironment.Interpreter == null)
if (LuaEnv.Interpreter == null)
{
UnityEngine.Debug.LogError("No Lua interpreter found");
return false;
}
MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter;
MoonSharp.Interpreter.Script interpreter = LuaEnv.Interpreter;
// Instantiate the regular expression object.
Regex r = new Regex("\\{\\$.*?\\}");

Loading…
Cancel
Save