public void Test_CallFunction_InputString_ReturnInput() { // Test a function that returns the String passed to it LuaUtilities.LoadScriptFromFile(testCode1Path); MoonSharp.Interpreter.DynValue value = LuaUtilities.CallFunction("test_func2", "inputted value"); Assert.AreEqual("inputted value", value.CastToString()); }
/// <summary> /// Merges data into your object. (no deep copy) /// </summary> /// <param name="incoming"></param> /// <param name="onlyCopyPersistedData"></param> public void MergeDataFrom(LuaCoroutine incoming, bool onlyCopyPersistedData = false) { if (incoming == null) { UnityEngine.Debug.LogError("Trying to merge from null! Type: LuaCoroutine"); return; } // base.MergeDataFrom(incoming, onlyCopyPersistedData); if (!onlyCopyPersistedData) { this.co = incoming.co; } if (!onlyCopyPersistedData) { this.waitForType = incoming.waitForType; } if (!onlyCopyPersistedData) { this.value1 = incoming.value1; } if (!onlyCopyPersistedData) { this.value2 = incoming.value2; } if (!onlyCopyPersistedData) { this.context = incoming.context; } }
public void Test_CallFunction() { // Test a function that dosent return anything (void c# , nil/nan Lua) LuaUtilities.LoadScriptFromFile(testCode1Path); MoonSharp.Interpreter.DynValue value = LuaUtilities.CallFunction("test_func0"); Assert.AreEqual(true, value.IsNilOrNan()); }
public void Test_CallFunction_ReturnString() { // Test a function that returns a string LuaUtilities.LoadScriptFromFile(testCode1Path); MoonSharp.Interpreter.DynValue value = LuaUtilities.CallFunction("test_func1"); Assert.AreEqual("test_func1_returns", value.CastToString()); }
public void Test_CallFunction_InputInts_ReturnSum() { // Test passing more than one input LuaUtilities.LoadScriptFromFile(testCode1Path); MoonSharp.Interpreter.DynValue value = LuaUtilities.CallFunction("test_func3", 4, 7); Assert.AreEqual(11, (int)value.CastToNumber()); }
/// <summary> /// Loads and executes a string containing a Lua/MoonSharp script. /// </summary> /// <param name="code">The code.</param> /// <param name="globalContext">The global context.</param> /// <returns> /// A DynValue containing the result of the processing of the loaded chunk. /// </returns> public DynValue DoString(string code, Table globalContext = null) { DynValue func = LoadString(code, globalContext); return(Call(func)); }
public static void Set(int i, ref DynValue value) { _heapAllocatedDynValue[i] = value; }
/// <summary> /// Creates a new dynamic expression which is actually quite static, returning always the same constant value. /// </summary> /// <param name="code">The code of the not-so-dynamic expression.</param> /// <param name="constant">The constant to return.</param> /// <returns></returns> public DynamicExpression CreateConstantDynamicExpression(string code, DynValue constant) { this.CheckScriptOwnership(constant); return(new DynamicExpression(this, code, constant)); }
/// <summary> /// Calls the specified function. /// </summary> /// <param name="function">The Lua/MoonSharp function to be called </param> /// <param name="args">The arguments to pass to the function.</param> /// <returns></returns> /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> public DynValue Call(object function, params object[] args) { return(Call(DynValue.FromObject(this, function), args)); }
/// <summary> /// Calls the specified function. /// </summary> /// <param name="function">The Lua/MoonSharp function to be called</param> /// <returns> /// The return value(s) of the function call. /// </returns> /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> public DynValue Call(DynValue function) { return(Call(function, new DynValue[0])); }
/// <summary> /// Loads and executes a stream containing a Lua/MoonSharp script. /// </summary> /// <param name="stream">The stream.</param> /// <param name="globalContext">The global context.</param> /// <param name="codeFriendlyName">Name of the code - used to report errors, etc. Also used by debuggers to locate the original source file.</param> /// <returns> /// A DynValue containing the result of the processing of the loaded chunk. /// </returns> public DynValue DoStream(Stream stream, Table globalContext = null, string codeFriendlyName = null) { DynValue func = LoadStream(stream, globalContext, codeFriendlyName); return(Call(func)); }
/// <summary> /// Initializes a new instance of the <see cref="TablePair"/> struct. /// </summary> /// <param name="key">The key.</param> /// <param name="val">The value.</param> public TablePair(DynValue key, DynValue val) { this.key = key; this.value = val; }
/// <summary> /// Gets the value associated with the specified key. /// </summary> /// <param name="key">The key.</param> public DynValue Get(DynValue key) { //Contract.Ensures(Contract.Result<DynValue>() != null); return(RawGet(key)); }
/// <summary> /// Sets the value associated to the specified key. /// </summary> /// <param name="key">The key.</param> /// <param name="value">The value.</param> public void Set(int key, DynValue value) { this.CheckScriptOwnership(value); PerformTableSet(m_ArrayMap, key, DynValue.NewNumber(key), value, true, -1); }
private void PerformTableSet <T>(LinkedListIndex <T, TablePair> listIndex, T key, DynValue keyDynValue, DynValue value, bool isNumber, int appendKey) { TablePair prev = listIndex.Set(key, new TablePair(keyDynValue, value)); // If this is an insert, we can invalidate all iterators and collect dead keys if (m_ContainsNilEntries && value.IsNotNil() && prev.Value.IsNil()) { CollectDeadKeys(); } // If this value is nil (and we didn't collect), set that there are nil entries, and invalidate array len cache else if (value.IsNil()) { m_ContainsNilEntries = true; if (isNumber) { m_CachedLength = -1; } } else if (isNumber) { // If this is an array insert, we might have to invalidate the array length if (prev.Value.IsNilOrNan()) { // If this is an array append, let's check the next element before blindly invalidating if (appendKey >= 0) { LinkedListNode <TablePair> next = m_ArrayMap.Find(appendKey + 1); if (next == null || next.Value.Value.IsNil()) { m_CachedLength += 1; } else { m_CachedLength = -1; } } else { m_CachedLength = -1; } } } }
public static void CheckScriptOwnership(this IScriptPrivateResource containingResource, DynValue value) { if (value != null) { var otherResource = value.GetAsPrivateResource(); if (otherResource != null) { CheckScriptOwnership(containingResource, otherResource); } } }
/// <summary> /// Loads and executes a file containing a Lua/MoonSharp script. /// </summary> /// <param name="filename">The filename.</param> /// <param name="globalContext">The global context.</param> /// <returns> /// A DynValue containing the result of the processing of the loaded chunk. /// </returns> public DynValue DoFile(string filename, Table globalContext = null) { DynValue func = LoadFile(filename, globalContext); return(Call(func)); }
/// <summary> /// Loads and executes a stream containing a Lua/MoonSharp script. /// </summary> /// <param name="stream">The stream.</param> /// <param name="globalContext">The global context.</param> /// <returns> /// A DynValue containing the result of the processing of the loaded chunk. /// </returns> public DynValue DoStream(Stream stream, Table globalContext = null) { DynValue func = LoadStream(stream, globalContext); return(Call(func)); }
/// <summary> /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. /// </summary> /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> /// <returns> /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. /// </returns> public override bool Equals(object obj) { DynValue other = obj as DynValue; if (other == null) { return(false); } if ((other.Type == DataType.Nil && this.Type == DataType.Void) || (other.Type == DataType.Void && this.Type == DataType.Nil)) { return(true); } if (other.Type != this.Type) { return(false); } switch (Type) { case DataType.Void: case DataType.Nil: return(true); case DataType.Boolean: return(Boolean == other.Boolean); case DataType.Number: return(Number == other.Number); case DataType.String: return(String == other.String); case DataType.Function: return(Function == other.Function); case DataType.ClrFunction: return(Callback == other.Callback); case DataType.Table: return(Table == other.Table); case DataType.Tuple: case DataType.TailCallRequest: return(Tuple == other.Tuple); case DataType.Thread: return(Coroutine == other.Coroutine); case DataType.UserData: { UserData ud1 = this.UserData; UserData ud2 = other.UserData; if (ud1 == null || ud2 == null) { return(false); } if (ud1.Descriptor != ud2.Descriptor) { return(false); } if (ud1.Object == null && ud2.Object == null) { return(true); } if (ud1.Object != null && ud2.Object != null) { return(ud1.Object.Equals(ud2.Object)); } return(false); } default: return(object.ReferenceEquals(this, other)); } }
public void Call(DynValue luaFunc, params object[] args) { script.Call(luaFunc, args); }
/// <summary> /// Loads and executes a file containing a Lua/MoonSharp script. /// </summary> /// <param name="filename">The filename.</param> /// <param name="globalContext">The global context.</param> /// <param name="codeFriendlyName">Name of the code - used to report errors, etc. Also used by debuggers to locate the original source file.</param> /// <returns> /// A DynValue containing the result of the processing of the loaded chunk. /// </returns> public DynValue DoFile(string filename, Table globalContext = null, string codeFriendlyName = null) { DynValue func = LoadFile(filename, globalContext, codeFriendlyName); return(Call(func)); }
/// <summary> /// Gets the metamethod to be used for a binary operation using op1 and op2. /// </summary> public DynValue GetBinaryMetamethod(DynValue op1, DynValue op2, string eventName) { return(m_Processor.GetBinaryMetamethod(op1, op2, eventName)); }
/// <summary> /// Calls the specified function. /// </summary> /// <param name="function">The Lua/MoonSharp function to be called</param> /// <returns></returns> /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> public DynValue Call(object function) { return(Call(DynValue.FromObject(this, function))); }
/// <summary> /// Gets the metatable associated with the given value. /// </summary> /// <param name="value">The value.</param> /// <returns></returns> public Table GetMetatable(DynValue value) { return(m_Processor.GetMetatable(value)); }
/// <summary> /// Creates a coroutine pointing at the specified function. /// </summary> /// <param name="function">The function.</param> /// <returns> /// The coroutine handle. /// </returns> /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function or DataType.ClrFunction</exception> public DynValue CreateCoroutine(object function) { return(CreateCoroutine(DynValue.FromObject(this, function))); }
/// <summary> /// Gets the specified metamethod associated with the given value. /// </summary> /// <param name="value">The value.</param> /// <param name="metamethod">The metamethod name.</param> /// <returns></returns> public DynValue GetMetamethod(DynValue value, string metamethod) { return(m_Processor.GetMetamethod(value, metamethod)); }
public static HashSet <int> FindCircularReferences() { //Array.Clear(_refCount, 0, _refCount.Length); var result = new HashSet <int>(); var visited = new HashSet <object>(); var queue = new Queue <DynValue>(); for (var i = 0; i < _size; i++) { if (_refCount[i] <= 0) { continue; } queue.Enqueue(_heapAllocatedDynValue[i]); } while (queue.Count > 0) { DynValue v = queue.Dequeue(); var o = v.Object; if (o == null) { continue; } if (!visited.Add(o)) { continue; } var f = v.Function; if (f != null) { var count = f.ClosureContext.Count; for (var j = 0; j < count; j++) { var index = f.ClosureContext[j].Index; //if (_refCount[index] > 0) result.Add(index); } } var table = v.Table; if (table != null) { foreach (var key in table.Keys) { queue.Enqueue(key); } foreach (var value in table.Values) { queue.Enqueue(value); } } var tuple = v.Tuple; if (tuple != null) { //foreach (var o in tuple.) } } return(result); }
/// <summary> /// Creates a ScriptRuntimeException with a predefined error message specifying that /// a len operator was applied on an invalid operand /// </summary> /// <param name="r">The operand.</param> /// <returns>The exception to be raised.</returns> public static ScriptRuntimeException LenOnInvalidType(DynValue r) { return(new ScriptRuntimeException("attempt to get length of a {0} value", r.Type.ToLuaTypeString())); }
/// <summary> /// Register some commonly used Unity classes and objects for Lua interop. /// 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 InitFungusModule() { if (fungusModule == FungusModuleOptions.NoFungusModule) { return; } MoonSharp.Interpreter.Script interpreter = luaEnvironment.Interpreter; // 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["playerprefs"] = UserData.CreateStatic(typeof(PlayerPrefs)); fungusTable["prefs"] = UserData.CreateStatic(typeof(FungusPrefs)); fungusTable["factory"] = UserData.CreateStatic(typeof(PODTypeFactory)); // Lua Environment and Lua Utils components fungusTable["luaenvironment"] = luaEnvironment; fungusTable["luautils"] = this; // Provide access to the Unity Test Tools (if available). Type testType = Type.GetType("IntegrationTest"); if (testType != null) { UserData.RegisterType(testType); fungusTable["test"] = UserData.CreateStatic(testType); } // Populate the string table by parsing the string table JSON files stringTable = new Table(interpreter); fungusTable["stringtable"] = stringTable; foreach (TextAsset stringFile in stringTables) { if (stringFile.text == "") { continue; } JSONObject stringsJSON = new JSONObject(stringFile.text); if (stringsJSON == null || stringsJSON.type != JSONObject.Type.OBJECT) { UnityEngine.Debug.LogError("String table JSON format is not correct " + stringFile.name); continue; } foreach (string stringKey in stringsJSON.keys) { if (stringKey == "") { UnityEngine.Debug.LogError("String table JSON format is not correct " + stringFile.name); continue; } Table entriesTable = new Table(interpreter); stringTable[stringKey] = entriesTable; JSONObject entries = stringsJSON.GetField(stringKey); if (entries.type != JSONObject.Type.OBJECT) { UnityEngine.Debug.LogError("String table JSON format is not correct " + stringFile.name); continue; } foreach (string language in entries.keys) { string translation = entries.GetField(language).str; entriesTable[language] = translation; } } } stringSubstituter = new StringSubstituter(); if (fungusModule == FungusModuleOptions.UseGlobalVariables) { // Copy all items from the Fungus table to global variables foreach (TablePair p in fungusTable.Pairs) { if (interpreter.Globals.Keys.Contains(p.Key)) { UnityEngine.Debug.LogError("Lua globals already contains a variable " + p.Key); } else { interpreter.Globals[p.Key] = p.Value; } } interpreter.Globals["fungus"] = DynValue.Nil; // Note: We can't remove the fungus table itself because of dependencies between functions } }
/// <summary> /// Creates a ScriptRuntimeException with a predefined error message specifying that /// an invalid attempt to index the specified object was made /// </summary> /// <param name="obj">The object.</param> /// <returns> /// The exception to be raised. /// </returns> public static ScriptRuntimeException IndexType(DynValue obj) { return(new ScriptRuntimeException("attempt to index a {0} value", obj.Type.ToLuaTypeString())); }