Browse Source

Merge pull request #443 from FungusGames/init-fungus-module

Improved how fungus lua module is initialized
master
Chris Gregan 9 years ago
parent
commit
02d07521c3
  1. 9
      Assets/Fungus/Lua/Resources/Lua/fungus.txt
  2. 1
      Assets/Fungus/Lua/Resources/Types/RegisterTypes.txt
  3. 14
      Assets/Fungus/Lua/Scripts/Commands/ExecuteLua.cs
  4. 3
      Assets/Fungus/Lua/Scripts/Editor/LuaScriptEditor.cs
  5. 6
      Assets/Fungus/Lua/Scripts/LuaEnvironment.cs
  6. 22
      Assets/Fungus/Lua/Scripts/LuaScript.cs
  7. 4
      Assets/Fungus/Lua/Scripts/LuaStore.cs
  8. 50
      Assets/Fungus/Lua/Scripts/LuaUtils.cs
  9. 36
      Assets/Tests/Lua/FungusTests.unity
  10. 19
      Assets/Tests/Lua/LuaEnvironmentTests.unity

9
Assets/Fungus/Lua/Resources/Lua/fungus.txt

@ -3,15 +3,6 @@ local inspect = require('inspect')
-- Utility functions for working with Lua in Fungus
local M = {}
-- Merge everything in the temp _fungus table into this module
local function mergefungustable()
for k,v in pairs(_fungus) do
M[k] = v
end
_fungus = nil
end
mergefungustable()
------------
-- Debugging
------------

1
Assets/Fungus/Lua/Resources/Types/RegisterTypes.txt

@ -26,6 +26,7 @@ Fungus.Label
Fungus.MaterialVariable
Fungus.MenuDialog
Fungus.ObjectVariable
Fungus.PODTypeFactory
Fungus.PortraitState
Fungus.SayDialog
Fungus.SpriteVariable

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

@ -18,12 +18,6 @@ namespace Fungus
[Tooltip("Lua script to execute. Use {$VarName} to insert a Flowchart variable in the Lua script.")]
public string luaScript;
/// <summary>
/// Require the fungus Lua module at the start of the script. Equivalent to 'local fungus = require('fungus')
/// </summary>
[Tooltip("Require the fungus Lua module at the start of the script. Equivalent to 'local fungus = require('fungus')")]
public bool useFungusModule = true;
[Tooltip("Execute this Lua script as a Lua coroutine")]
public bool runAsCoroutine = true;
@ -63,13 +57,7 @@ namespace Fungus
return;
}
string s = "";
if (useFungusModule)
{
s = "fungus = require('fungus')\n";
}
string subbed = s + GetFlowchart().SubstituteVariables(luaScript);
string subbed = GetFlowchart().SubstituteVariables(luaScript);
luaEnvironment.DoLuaString(subbed, friendlyName, runAsCoroutine, (returnValue) => {
StoreReturnVariable(returnValue);

3
Assets/Fungus/Lua/Scripts/Editor/LuaScriptEditor.cs

@ -28,7 +28,6 @@ namespace Fungus
protected SerializedProperty runAsCoroutineProp;
protected SerializedProperty luaFileProp;
protected SerializedProperty luaScriptProp;
protected SerializedProperty useFungusModuleProp;
protected List<TextAsset> luaFiles = new List<TextAsset>();
@ -46,7 +45,6 @@ namespace Fungus
runAsCoroutineProp = serializedObject.FindProperty("runAsCoroutine");
luaFileProp = serializedObject.FindProperty("luaFile");
luaScriptProp = serializedObject.FindProperty("luaScript");
useFungusModuleProp = serializedObject.FindProperty("useFungusModule");
// Make a note of all Lua files in the project resources
object[] result = Resources.LoadAll("Lua", typeof(TextAsset));
@ -105,7 +103,6 @@ namespace Fungus
EditorGUILayout.PropertyField(luaEnvironmentProp);
EditorGUILayout.PropertyField(runAsCoroutineProp);
EditorGUILayout.PropertyField(useFungusModuleProp);
int selected = 0;
List<GUIContent> options = new List<GUIContent>();

6
Assets/Fungus/Lua/Scripts/LuaEnvironment.cs

@ -118,13 +118,13 @@ namespace Fungus
protected virtual void Start()
{
InitInterpreter();
InitEnvironment();
}
/// <summary>
/// Initialise the Lua interpreter so we can start running Lua code.
/// </summary>
public virtual void InitInterpreter()
public virtual void InitEnvironment()
{
if (initialised)
{
@ -212,7 +212,7 @@ namespace Fungus
/// </summary>
public void DoLuaString(string luaString, string friendlyName, bool runAsCoroutine, Action<DynValue> onComplete = null)
{
InitInterpreter();
InitEnvironment();
// Load the Lua script
DynValue res = null;

22
Assets/Fungus/Lua/Scripts/LuaScript.cs

@ -7,6 +7,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using UnityEngine;
using MoonSharp.Interpreter;
using Debug = UnityEngine.Debug;
using Object = UnityEngine.Object;
@ -81,12 +82,6 @@ namespace Fungus
[Tooltip("Run the script as a Lua coroutine so execution can be yielded for asynchronous operations.")]
public bool runAsCoroutine = true;
/// <summary>
/// Require the fungus Lua module at the start of the script. Equivalent to 'local fungus = require('fungus')
/// </summary>
[Tooltip("Require the fungus Lua module at the start of the script. Equivalent to 'local fungus = require('fungus')")]
public bool useFungusModule = true;
private int m_ExecuteOnFrame;
protected string friendlyName = "";
@ -115,6 +110,9 @@ namespace Fungus
return;
}
// Ensure the LuaEnvironment is initialized before trying to execute code
luaEnvironment.InitEnvironment();
// Cache a descriptive name to use in Lua error messages
friendlyName = GetPath(transform) + ".LuaScript";
@ -297,19 +295,17 @@ namespace Fungus
}
else
{
string s = "";
if (useFungusModule)
{
s = "fungus = require('fungus')\n";
}
// Ensure the Lua Environment is initialised first.
luaEnvironment.InitEnvironment();
string s = "";
if (luaFile != null)
{
s += luaFile.text;
s = luaFile.text;
}
else if (luaScript.Length > 0)
{
s += luaScript;
s = luaScript;
}
luaEnvironment.DoLuaString(s, friendlyName, runAsCoroutine);

4
Assets/Fungus/Lua/Scripts/LuaStore.cs

@ -82,10 +82,10 @@ namespace Fungus
return;
}
Table fungusTable = globals.Get("_fungus").Table;
Table fungusTable = globals.Get("fungus").Table;
if (fungusTable == null)
{
Debug.LogError("_fungus table not found");
Debug.LogError("fungus table not found");
return;
}

50
Assets/Fungus/Lua/Scripts/LuaUtils.cs

@ -15,6 +15,13 @@ namespace Fungus
public class LuaUtils : LuaEnvironment.Initializer, StringSubstituter.ISubstitutionHandler
{
/// <summary>
/// Create an instance of the 'fungus' utility Lua module.
/// This module provides useful utilities that can be accessed via the 'fungus' global table.
/// </summary>
[Tooltip("Create an instance of the 'fungus' utility Lua module.")]
public bool useFungusModule = true;
/// <summary>
/// Lua script file which defines the global string table used for localisation.
/// </summary>
@ -78,7 +85,7 @@ namespace Fungus
}
InitTypes();
InitCustomObjects();
InitFungusModule();
InitBindings();
InitStringTable();
}
@ -130,21 +137,33 @@ namespace Fungus
/// To register more class objects externally to this class, register them in the Awake method of any
/// monobehavior in your scene.
/// </summary>
protected virtual void InitCustomObjects()
protected virtual void InitFungusModule()
{
MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter;
if (!useFungusModule)
{
return;
}
// Add the CLR class objects to a temp unity table called _fungus.
// When the fungus module is required, all the entries from _fungus are copied over.
MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter;
Table fungusTable = new Table(interpreter);
interpreter.Globals["_fungus"] = fungusTable;
// Require the Fungus module and assign it to the global 'fungus'
Table fungusTable = null;
MoonSharp.Interpreter.DynValue value = interpreter.RequireModule("fungus");
if (value != null &&
value.Type == DataType.Function)
{
fungusTable = value.Function.Call().Table;
}
if (fungusTable == null)
{
UnityEngine.Debug.LogError("Failed to create Fungus table");
return;
}
interpreter.Globals["fungus"] = fungusTable;
// Static classes
fungusTable["time"] = UserData.CreateStatic(typeof(Time));
fungusTable["prefs"] = UserData.CreateStatic(typeof(FungusPrefs));
UserData.RegisterType(typeof(PODTypeFactory));
fungusTable["factory"] = UserData.CreateStatic(typeof(PODTypeFactory));
// Lua Environment and Lua Utils components
@ -179,7 +198,7 @@ namespace Fungus
if (stringTableRes.Type == DataType.Table)
{
stringTableCached = stringTableRes.Table;
Table fungusTable = interpreter.Globals.Get("_fungus").Table;
Table fungusTable = interpreter.Globals.Get("fungus").Table;
if (fungusTable != null)
{
fungusTable["stringtable"] = stringTableCached;
@ -230,8 +249,19 @@ namespace Fungus
[MoonSharpHidden]
public virtual string SubstituteStrings(string input)
{
// 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)
{
luaEnvironment = GetComponent<LuaEnvironment>();
if (luaEnvironment != null)
{
luaEnvironment.InitEnvironment();
}
}
if (luaEnvironment == null)
{
UnityEngine.Debug.LogError("No Lua Environment found");
return input;
}

36
Assets/Tests/Lua/FungusTests.unity

@ -822,7 +822,6 @@ MonoBehaviour:
fungus.pass()'
useFungusModule: 1
runAsCoroutine: 1
waitUntilFinished: 1
returnVariable: {fileID: 0}
@ -880,7 +879,7 @@ MonoBehaviour:
variablesScrollPos: {x: 0, y: 0}
variablesExpanded: 1
blockViewHeight: 400
zoom: 0.8889934
zoom: 0.9199953
scrollViewRect:
serializedVersion: 2
x: -343
@ -1229,7 +1228,6 @@ MonoBehaviour:
fungus.pass()'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1001 &130678264
Prefab:
m_ObjectHideFlags: 0
@ -2275,6 +2273,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c10f0b861365b42b0928858f7b086ff3, type: 3}
m_Name:
m_EditorClassIdentifier:
useFungusModule: 1
stringTable: {fileID: 0}
activeLanguage: en
timeScale: -1
@ -2751,7 +2750,6 @@ MonoBehaviour:
fungus.pass()'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &465829169
GameObject:
m_ObjectHideFlags: 0
@ -3070,7 +3068,6 @@ MonoBehaviour:
1\", option1)\n\nfungus.assert(optionbutton0.activeSelf)\nfungus.clearmenu()\nfungus.assert(not
optionbutton0.activeSelf)\n\nfungus.pass()"
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &511430244
GameObject:
m_ObjectHideFlags: 0
@ -3127,7 +3124,6 @@ MonoBehaviour:
menu option with a timer\nfungus.menu(\"Option 1\", option1)\nfungus.menutimer(1,
timeout)\n"
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &560555132
GameObject:
m_ObjectHideFlags: 0
@ -3290,7 +3286,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 25fb867d2049d41f597aefdd6b19f598, type: 3}
m_Name:
m_EditorClassIdentifier:
nameText: John [$score]
nameText: John {$score}
nameColor: {r: 0.034482718, g: 1, b: 0, a: 1}
soundEffect: {fileID: 0}
profileSprite: {fileID: 21300000, guid: ea8f56c43254d41728f5ac4e8299b6c9, type: 3}
@ -4409,7 +4405,6 @@ MonoBehaviour:
go = fungus.luautils.find(\"OptionButton0\")\nfungus.assert(go != nil)\n\nlocal
button = go.GetComponent(\"Button\")\nfungus.assert(button != nil)\n\nbutton.onClick.Invoke()"
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &851680338
GameObject:
m_ObjectHideFlags: 0
@ -4554,7 +4549,6 @@ MonoBehaviour:
fungus.pass()'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &863130402
GameObject:
m_ObjectHideFlags: 0
@ -5343,7 +5337,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return true
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227029}
@ -5460,7 +5453,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return 1.0
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227035}
@ -5480,7 +5472,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return 2
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227034}
@ -5500,7 +5491,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return "a string"
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227033}
@ -5579,7 +5569,6 @@ MonoBehaviour:
return c'
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227037}
@ -5599,7 +5588,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return testgameobject
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227040}
@ -5647,7 +5635,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return testmaterial
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227042}
@ -5681,7 +5668,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return testgameobject
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227044}
@ -5715,7 +5701,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return mushroom
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227046}
@ -5752,7 +5737,6 @@ MonoBehaviour:
return v'
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227050}
@ -5786,7 +5770,6 @@ MonoBehaviour:
indentLevel: 0
luaEnvironment: {fileID: 0}
luaScript: return mousepointer
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227048}
@ -5822,7 +5805,6 @@ MonoBehaviour:
luaScript: 'local v = fungus.factory.vector3(1,1,1)
return v'
useFungusModule: 1
runAsCoroutine: 0
waitUntilFinished: 1
returnVariable: {fileID: 942227052}
@ -6449,7 +6431,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 0
m_IsActive: 1
--- !u!114 &1109996700
MonoBehaviour:
m_ObjectHideFlags: 0
@ -7630,7 +7612,7 @@ GameObject:
m_Icon: {fileID: 0}
m_NavMeshLayer: 0
m_StaticEditorFlags: 0
m_IsActive: 1
m_IsActive: 0
--- !u!114 &1641285457
MonoBehaviour:
m_ObjectHideFlags: 0
@ -7819,7 +7801,6 @@ MonoBehaviour:
\ fungus.pass()\nend\n\n-- Display a menu option with a timer\nfungus.menu(\"Option
1\", option1)\n\noptionbutton0.onClick.Invoke()\n"
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &1667495163
GameObject:
m_ObjectHideFlags: 0
@ -8827,7 +8808,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 61dddfdc5e0e44ca298d8f46f7f5a915, type: 3}
m_Name:
m_EditorClassIdentifier:
selectedFlowchart: {fileID: 942227028}
selectedFlowchart: {fileID: 56584893}
--- !u!4 &1791050794
Transform:
m_ObjectHideFlags: 1
@ -8912,7 +8893,7 @@ MonoBehaviour:
-- Test say command with a tag and global variable substitution
fungus.say "Alrighty{w=1} how do [$score]?"
fungus.say "Alrighty{w=1} how do {$score}?"
fungus.assert(nametext.text == "John 10")
@ -8924,7 +8905,6 @@ MonoBehaviour:
'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &1880266302
GameObject:
m_ObjectHideFlags: 0
@ -9583,7 +9563,6 @@ MonoBehaviour:
fungus.pass()'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &2087053783
GameObject:
m_ObjectHideFlags: 0
@ -9903,7 +9882,6 @@ MonoBehaviour:
luaFile: {fileID: 0}
luaScript:
runAsCoroutine: 1
useFungusModule: 1
--- !u!1001 &2092185197
Prefab:
m_ObjectHideFlags: 0

19
Assets/Tests/Lua/LuaEnvironmentTests.unity

@ -242,7 +242,6 @@ MonoBehaviour:
'
runAsCoroutine: 1
useFungusModule: 1
--- !u!4 &236999594 stripped
Transform:
m_PrefabParentObject: {fileID: 495584, guid: 49031c561e16d4fcf91c12153f8e0b25, type: 2}
@ -415,7 +414,6 @@ MonoBehaviour:
returns true\n-- If this doesn't work the test will timeout and fail\nvalue =
true\nfungus.waitfor(fn, 1)\n\nfungus.pass()"
runAsCoroutine: 1
useFungusModule: 1
--- !u!1001 &364012152
Prefab:
m_ObjectHideFlags: 0
@ -556,6 +554,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c10f0b861365b42b0928858f7b086ff3, type: 3}
m_Name:
m_EditorClassIdentifier:
useFungusModule: 1
stringTable: {fileID: 0}
activeLanguage: en
timeScale: -1
@ -736,7 +735,6 @@ MonoBehaviour:
'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &715881501
GameObject:
m_ObjectHideFlags: 0
@ -1001,7 +999,6 @@ MonoBehaviour:
fungus.pass()'
runAsCoroutine: 1
useFungusModule: 1
--- !u!4 &1167396341 stripped
Transform:
m_PrefabParentObject: {fileID: 495584, guid: 49031c561e16d4fcf91c12153f8e0b25, type: 2}
@ -1158,7 +1155,6 @@ MonoBehaviour:
f.pass()'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &1394431693
GameObject:
m_ObjectHideFlags: 0
@ -1286,6 +1282,7 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: c10f0b861365b42b0928858f7b086ff3, type: 3}
m_Name:
m_EditorClassIdentifier:
useFungusModule: 1
stringTable: {fileID: 0}
activeLanguage: en
timeScale: -1
@ -1622,8 +1619,6 @@ MonoBehaviour:
luaFile: {fileID: 0}
luaScript: '-- Test string table localisation system
print (fungus.stringtable)
fungus.assert(fungus.stringtable != nil)
@ -1645,14 +1640,14 @@ MonoBehaviour:
t = 3
local s = fungus.sub("should be [$t]")
local s = fungus.sub("should be {$t}")
fungus.assert(s == "should be 3")
-- Test substituting a string table value (en)
s = fungus.sub("say [$hello]")
s = fungus.sub("say {$hello}")
fungus.assert(s == "say Hi there")
@ -1661,14 +1656,13 @@ MonoBehaviour:
fungus.setlanguage("fr")
s = fungus.sub("say [$hello]")
s = fungus.sub("say {$hello}")
fungus.assert(s == "say Bonjour")
fungus.pass()'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &1818482578
GameObject:
m_ObjectHideFlags: 0
@ -1726,7 +1720,6 @@ MonoBehaviour:
'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &1828947831
GameObject:
m_ObjectHideFlags: 0
@ -1805,7 +1798,6 @@ MonoBehaviour:
fungus.pass()'
useFungusModule: 1
runAsCoroutine: 1
waitUntilFinished: 1
returnVariable: {fileID: 0}
@ -2047,7 +2039,6 @@ MonoBehaviour:
fungus.pass()'
runAsCoroutine: 1
useFungusModule: 1
--- !u!1 &1960220030
GameObject:
m_ObjectHideFlags: 0

Loading…
Cancel
Save