public void LuaNestedErrors() { using (var runtime = new LuaRuntime()) { Action errorer = () => { DoError(runtime); }; using (var func = runtime.CreateFunctionFromDelegate(errorer)) { runtime.Globals ["test"] = func; } Action errorer2 = () => { runtime.DoString("test()").Dispose(); }; using (var func = runtime.CreateFunctionFromDelegate(errorer2)) { runtime.Globals ["test2"] = func; } try { runtime.DoString(@" function test3() test2() end test3()"); } catch (LuaException e) { Assert.AreEqual(e.Message, "[LuaTable]"); Assert.IsInstanceOf <LuaTable>(e.Value); var tab = (LuaTable)e.Value; Assert.AreEqual(tab ["a"].ToBoolean(), true); Assert.IsNull(e.InnerException); } } }
/// <summary> /// Processes a Lua chunk. /// </summary> /// <param name="chunk">Chunk to process.</param> /// <param name="chunkName">Name of the chunk.</param> /// <returns>The result of the lua state's DoString method.</returns> public IList <object> SafeDoString(string chunk, string chunkName = "") { lock (_luaState) { try { return(Dewrap(_luaState.DoString(chunk, chunkName))); } catch (Exception e) { return(HandleException(e, null) as IList <object>); } } }
public void TransparentBinding() { using (var runtime = new LuaRuntime()) { var script = @" function fn(o) local r = { two = o.two(), three = o.three, four = o.Four(), five = o.add_two(3), GetType = o.GetType } return r end "; runtime.DoString(script).Dispose(); using (var fn = (LuaFunction)runtime.Globals["fn"]) { var results = (LuaTable)fn.Call(new LuaTransparentClrObject(new TransparentBindingObject()))[0]; Assert.AreEqual(new LuaNumber(2), results["two"], "two"); Assert.AreEqual(new LuaNumber(3), results["three"], "three"); Assert.AreEqual(new LuaNumber(4), results["four"], "four"); Assert.AreEqual(new LuaNumber(5), results["five"], "five"); Assert.AreEqual(LuaNil.Instance, results["GetType"], "GetType"); } } }
public void InstantiatingClasses() { using (var runtime = new LuaRuntime()) { runtime.InitializeClrPackage(); var results = runtime.DoString(@" local ass = clr.assembly('Eluant.Tests') local Something = clr.type(ass, 'Eluant.Tests.Functions/Something') local a = Something(100, 200, 300) local b = Something(10) return a, b "); using (results) { Assert.AreEqual(2, results.Count); Assert.IsInstanceOf(typeof(Something), results [0].CLRMappedObject); Assert.IsInstanceOf(typeof(Something), results [1].CLRMappedObject); var a = results [0].CLRMappedObject as Something; var b = results [1].CLRMappedObject as Something; Assert.AreEqual(100, a.A); Assert.AreEqual(200, a.B); Assert.AreEqual(300, a.C); Assert.AreEqual(10, b.A); Assert.AreEqual(10, b.B); Assert.AreEqual(10, b.C); } } }
public void Basic() { var obj = new BasicTestObject(); obj.a = 42; using (var runtime = new LuaRuntime()) { runtime.Globals["obj"] = new LuaTransparentClrObject(obj); var script = @" local old_a = obj.a obj.a = 50 obj.b = 51 obj.c = 'foo' obj.e = 'bar' return { a=old_a, n=obj.square(obj, 4), o=obj.sqr(obj, 5) } "; using (var result = runtime.DoString(script)) { var t = (LuaTable)result[0]; Assert.AreEqual(50, obj.a, "obj.a"); Assert.AreEqual(51, obj.b, "obj.b"); Assert.AreEqual("foo", obj.C, "obj.C"); Assert.AreEqual("bar", obj.E, "obj.E"); Assert.AreEqual(42, ((LuaNumber)t["a"]).Value, "t.a"); Assert.AreEqual(4 * 4, ((LuaNumber)t["n"]).Value, "t.n"); Assert.AreEqual(5 * 5, ((LuaNumber)t["o"]).Value, "t.o"); } } }
public void Basic() { var obj = new BasicTestObject(); obj.a = 42; using (var runtime = new LuaRuntime()) { runtime.Globals["obj"] = new LuaTransparentClrObject(obj); var script = @" local old_a = obj.a obj.a = 50 obj.b = 51 obj.c = 'foo' obj.e = 'bar' return { a=old_a, n=obj.square(4), o=obj.sqr(5) } "; using (var result = runtime.DoString(script)) { var t = (LuaTable)result[0]; Assert.AreEqual(50, obj.a, "obj.a"); Assert.AreEqual(51, obj.b, "obj.b"); Assert.AreEqual("foo", obj.C, "obj.C"); Assert.AreEqual("bar", obj.E, "obj.E"); Assert.AreEqual(42, ((LuaNumber)t["a"]).Value, "t.a"); Assert.AreEqual(4 * 4, ((LuaNumber)t["n"]).Value, "t.n"); Assert.AreEqual(5 * 5, ((LuaNumber)t["o"]).Value, "t.o"); } } }
public void Metatables() { using (var runtime = new LuaRuntime()) { using (var tab = runtime.CreateTable()) { using (var mt = runtime.CreateTable()) { Func <LuaTable, string, LuaValue> index = (self, key) => { return("hey"); }; using (var func = runtime.CreateFunctionFromDelegate(index)) { mt ["__index"] = func; } tab.Metatable = mt; } runtime.Globals ["test"] = tab; using (var mt = tab.Metatable) { using (var index = mt ["__index"]) { Assert.IsInstanceOf(typeof(LuaFunction), index); } Assert.AreEqual(1, mt.Count); } } using (var ret = runtime.DoString("return test.this_key_doesnt_exist")) { Assert.AreEqual(1, ret.Count); Assert.AreEqual("hey", ret [0].ToString()); } } }
public void TypeMapping() { bool called = false; TypeMappingTestDelegate cb = (a, b, c, d, e, f, g) => { Assert.AreEqual(10, a, "a"); Assert.AreEqual(20, b, "b"); Assert.AreEqual(0.5, c, "c"); Assert.AreEqual("foobar", d, "d"); Assert.AreEqual("dingus", e["widget"].ToString(), "e"); Assert.AreEqual(true, f, "f"); Assert.IsNull(g, "g"); called = true; }; using (var runtime = new LuaRuntime()) { using (var wrapper = runtime.CreateFunctionFromDelegate(cb)) { runtime.Globals["callback"] = wrapper; } runtime.DoString("callback(10, 20, 0.5, 'foobar', { widget='dingus' }, true, nil)"); } Assert.IsTrue(called, "called"); }
public void TransparentObjectEquality() { using (var runtime = new LuaRuntime()) { var script = @" function fn(a, b) return { ['a == b'] = (a == b), ['a == 1'] = (a == 1), ['1 == b'] = (1 == b), } end "; runtime.DoString(script).Dispose(); using (var fn = (LuaFunction)runtime.Globals["fn"]) using (var results = fn.Call(new LuaTransparentClrObject(this), new LuaTransparentClrObject(this))) { var table = (LuaTable)results[0]; Assert.AreEqual(LuaBoolean.True, table["a == b"], "a == b"); Assert.AreEqual(LuaBoolean.False, table["a == 1"], "a == 1"); Assert.AreEqual(LuaBoolean.False, table["1 == b"], "1 == b"); } } }
public void ClrPackage() { using (var runtime = new LuaRuntime()) { runtime.InitializeClrPackage(); // adds a `clr` package with the following functions: // clr.assembly | obtain an assembly with the provided name // clr.namespace | obtain a table runtime.DoString(@" local ass = clr.assembly('Eluant.Tests') local EluantTests = clr.namespace(ass, 'Eluant.Tests') local s1 = EluantTests.Functions.Test() local Functions = clr.type(ass, 'Eluant.Tests.Functions') local s2 = Functions.Test() if s1 ~= s2 then error('The strings are different') end "); } }
public void LuaArrayConvertionError() { using (var runtime = new LuaRuntime()) { runtime.Globals ["string"] = new LuaClrTypeObject(typeof(string)); runtime.DoString(@" print(string.Join(',', {'Hello', ' world!', 10}, 0, 3)) "); } }
public void LuaVarargMethod() { using (var runtime = new LuaRuntime()) { runtime.Globals ["test"] = new LuaTransparentClrObject(new HasVararg(), autobind: true); using (var ret = runtime.DoString(@"return test:Stringify(1, 2, 3)")) { Assert.AreEqual(1, ret.Count); Assert.AreEqual(123, ret [0].ToNumber()); } } }
public void ClrObjectReturn() { using (var runtime = new LuaRuntime()) { var inst = new Something(); runtime.Globals ["something"] = new LuaTransparentClrObject(inst, autobind: true); using (var result = runtime.DoString(@"return something:GetMe()")) { Assert.AreEqual("[LuaClrObjectReference ClrObject:A 1 B 2 C 4]", result [0].ToString()); } } }
public void AutoboundObjects() { using (var runtime = new LuaRuntime()) { var inst = new Something(); runtime.Globals ["something"] = new LuaTransparentClrObject(inst, autobind: true); using (var result = runtime.DoString(@"return something:GetType().TheAnswer")) { Assert.AreEqual(result [0].ToNumber(), 42); } } }
public void AdditionBinding() { using (var runtime = new LuaRuntime()) { runtime.DoString("function fn(o) return (2 + o) + 3 end").Dispose(); using (var fn = (LuaFunction)runtime.Globals["fn"]) { using (var results = fn.Call(new LuaCustomClrObject(new MathBindingObject(5)))) { Console.WriteLine(results[0]); } } } }
public void ClrExceptionPropagation() { Action thrower = () => { throw new InvalidOperationException(); }; using (var runtime = new LuaRuntime()) { using (var wrapper = runtime.CreateFunctionFromDelegate(thrower)) { runtime.Globals["callback"] = wrapper; } runtime.DoString("callback()"); } }
public void BasicFunction() { using (var runtime = new LuaRuntime()) { runtime.DoString("function basic_function(x) return x * 2 + 1 end"); using (var fn = (LuaFunction)runtime.Globals["basic_function"]) { using (var result = fn.Call(5)) { Assert.AreEqual(1, result.Count, "result.Count"); Assert.AreEqual(11, result[0].ToNumber(), "result[0]"); } } } }
public void AdditionBinding() { using (var runtime = new LuaRuntime()) { runtime.DoString("function fn(o) return (2 + o) + 3 end").Dispose(); using (var fn = (LuaFunction)runtime.Globals["fn"]) { using (var results = fn.Call(new LuaCustomClrObject(new MathBindingObject(5)))) { Assert.IsInstanceOf(typeof(LuaClrObjectReference), results [0]); Assert.IsInstanceOf(typeof(MathBindingObject), results [0].GetClrObject()); } } } }
public void CallbackOnCoroutineFails() { using (var runtime = new LuaRuntime()) { using (var callback = runtime.CreateFunctionFromDelegate(new Action(() => { Assert.Fail("Function called."); }))) { runtime.Globals["callback"] = callback; } using (var r = runtime.DoString("return coroutine.resume(coroutine.create(callback))")) { Assert.IsFalse(r[0].ToBoolean(), "Call succeeded."); Assert.IsTrue(r[1].ToString().EndsWith("Cannot enter the CLR from inside of a Lua coroutine."), "Error message is accurate."); } } }
public void NoSelfInMethodsMode() { using (var runtime = new LuaRuntime()) { runtime.MethodMode = LuaRuntime.LuaMethodMode.PassJustArgs; var inst = new Something(); runtime.Globals ["something"] = new LuaTransparentClrObject(inst, autobind: true); using (var result = runtime.DoString(@"return something.GetType().TheAnswer")) { Assert.AreEqual(result [0].ToNumber(), 42); } } }
public void LuaClrStaticMethods() { using (var runtime = new LuaRuntime()) { Func <LuaClrTypeObject> testex = () => { return(new LuaClrTypeObject(typeof(string))); }; using (var func = runtime.CreateFunctionFromDelegate(testex)) { runtime.Globals ["extest"] = func; } runtime.DoString(@" local str = extest() print(str.Join(',', {'Hello', ' world!'}, 0, 2)) "); } }
public void Table() { using (var runtime = new LuaRuntime()) { using (var table = runtime.CreateTable()) { table["foo"] = "bar"; runtime.Globals["t"] = table; } using (var results = runtime.DoString("return t['foo']")) { Assert.AreEqual(1, results.Count, "results.Count"); Assert.AreEqual("bar", results[0].ToString(), "results[0]"); } } }
public void Callback() { int? cbValue = null; Action <int> callback = x => cbValue = x; using (var runtime = new LuaRuntime()) { using (var wrapper = runtime.CreateFunctionFromDelegate(callback)) { runtime.Globals["callback"] = wrapper; } runtime.DoString("callback(42)"); } Assert.AreEqual(42, cbValue, "cbValue"); }
public void Callback() { int? cbValue = null; Action<int> callback = x => cbValue = x; using (var runtime = new LuaRuntime()) { using (var wrapper = runtime.CreateFunctionFromDelegate(callback)) { runtime.Globals["callback"] = wrapper; } runtime.DoString("callback(42)"); } Assert.AreEqual(42, cbValue, "cbValue"); }
public void DifferentReferencesToSameClrObjectAreUnequal() { using (var runtime = new LuaRuntime()) { var obj = new LuaOpaqueClrObject(this); LuaFunction fn; using (var r = runtime.DoString("return function(a, b) return a == b end")) { fn = (LuaFunction)r[0].CopyReference(); } using (var r = fn.Call(obj, obj)) { Assert.AreEqual(1, r.Count, "r.Count"); Assert.IsFalse(r[0].ToBoolean(), "r[0]"); } } }
public void LuaNonStringErrorPropagation() { using (var runtime = new LuaRuntime()) { try { runtime.DoString("error({a = 1, b = 2, c = 3})"); } catch (LuaException e) { Assert.AreEqual(e.Message, "[LuaTable]"); Assert.NotNull(e.Value); Assert.IsInstanceOf(typeof(LuaTable), e.Value); var val = (LuaTable)e.Value; Assert.AreEqual(val ["a"].ToNumber(), 1); Assert.AreEqual(val ["b"].ToNumber(), 2); Assert.AreEqual(val ["c"].ToNumber(), 3); } } }
public void HugeResultList() { var range = Enumerable.Range(1, 1000); Func <LuaVararg> fn = () => new LuaVararg(range.Select(i => (LuaNumber)i), true); using (var runtime = new LuaRuntime()) { using (var f = runtime.CreateFunctionFromDelegate(fn)) { runtime.Globals["callback"] = f; } using (var results = runtime.DoString("return callback()")) { Assert.AreEqual(range.Sum(), results.Select(i => (int)i.ToNumber().Value).Sum()); } } }
public void ClrEnums() { using (var runtime = new LuaRuntime()) { using (var func = runtime.CreateFunctionFromDelegate(new Func <Type>(() => typeof(string)))) { runtime.Globals ["get_string_type"] = func; } runtime.Globals ["StringComparison"] = new LuaClrTypeObject(typeof(StringComparison)); runtime.DoString(@" local string = get_string_type() if not string.Equals('Hello!', 'Hello!', StringComparison.InvariantCulture) then error('Strings aren\'t equal?') end ").Dispose(); } }
public void OpaqueClrObjectAsArgument() { object object1 = new object(); object object2 = null; using (var runtime = new LuaRuntime()) { runtime.Globals["o"] = new LuaOpaqueClrObject(object1); using (var d = runtime.CreateFunctionFromDelegate(new Action <object>(o => object2 = o))) { runtime.Globals["fn"] = d; } runtime.DoString("fn(o)").Dispose(); } Assert.AreSame(object1, object2); }
public void WeakReferences() { using (var runtime = new LuaRuntime()) { LuaWeakReference <LuaTable> tableWeakRef; using (var table = runtime.CreateTable()) { table["foo"] = "bar"; tableWeakRef = table.CreateWeakReference(); using (var tableRef = tableWeakRef.CreateReferenceToTarget()) { Assert.IsNotNull(tableRef, "tableRef"); Assert.AreEqual("bar", tableRef["foo"].ToString(), "tableRef[\"foo\"]"); } } runtime.DoString("collectgarbage()"); Assert.IsNull(tableWeakRef.CreateReferenceToTarget(), "tableWeakRef.Target"); tableWeakRef.Dispose(); } }
public void NonAsciiStringMarshallingFromLua() { using (var runtime = new LuaRuntime()) { runtime.DoString(@"k = string.char(0xFC, 0xFF)").Dispose(); LuaString clrString; using (var k = runtime.Globals["k"]) { clrString = (LuaString)k; } Assert.AreEqual(2, clrString.AsByteArray().Length, "clrString.AsByteArray().Length"); runtime.Globals["kclr"] = clrString; runtime.DoString("assert(k == kclr, 'k == kclr')").Dispose(); } }
public void LuaErrorPropagation() { using (var runtime = new LuaRuntime()) { runtime.DoString("error('$TEST$')"); } }
public void OpaqueClrObjectAsArgument() { object object1 = new object(); object object2 = null; using (var runtime = new LuaRuntime()) { runtime.Globals["o"] = new LuaOpaqueClrObject(object1); using (var d = runtime.CreateFunctionFromDelegate(new Action<object>(o => object2 = o))) { runtime.Globals["fn"] = d; } runtime.DoString("fn(o)").Dispose(); } Assert.AreSame(object1, object2); }
public void WeakReferences() { using (var runtime = new LuaRuntime()) { LuaWeakReference<LuaTable> tableWeakRef; using (var table = runtime.CreateTable()) { table["foo"] = "bar"; tableWeakRef = table.CreateWeakReference(); using (var tableRef = tableWeakRef.CreateReferenceToTarget()) { Assert.IsNotNull(tableRef, "tableRef"); Assert.AreEqual("bar", tableRef["foo"].ToString(), "tableRef[\"foo\"]"); } } runtime.DoString("collectgarbage()"); Assert.IsNull(tableWeakRef.CreateReferenceToTarget(), "tableWeakRef.Target"); tableWeakRef.Dispose(); } }
private void DoError(LuaRuntime runtime) { runtime.DoString("error({a = true})").Dispose(); }
public void ClrErrorPropagation() { Action thrower = () => { throw new LuaException("$TEST$"); }; using (var runtime = new LuaRuntime()) { using (var wrapper = runtime.CreateFunctionFromDelegate(thrower)) { runtime.Globals["callback"] = wrapper; } runtime.DoString("callback()"); } }
internal WIGInternalImpl(LuaRuntime luaState) { LuaTable wiginternal = luaState.CreateTable(); luaState.Globals["WIGInternal"] = wiginternal; // Interface for GUI luaState.DoString("WIGInternal.LogMessage = function (a, b) end"); luaState.DoString("WIGInternal.MessageBox = function (a, b, c, d, e) end"); luaState.DoString("WIGInternal.GetInput = function (a) end"); luaState.DoString("WIGInternal.NotifyOS = function (a) end"); luaState.DoString("WIGInternal.ShowScreen = function (a, b) end"); luaState.DoString("WIGInternal.ShowStatusText = function (a) end"); // Events luaState.DoString("WIGInternal.AttributeChangedEvent = function (a, b) end"); luaState.DoString("WIGInternal.CartridgeEvent = function (a) end"); luaState.DoString("WIGInternal.CommandChangedEvent = function (a) end"); luaState.DoString("WIGInternal.InventoryEvent = function (a, b, c) end"); luaState.DoString("WIGInternal.MediaEvent = function (a, b) end"); luaState.DoString("WIGInternal.TimerEvent = function (a, b) end"); luaState.DoString("WIGInternal.ZoneStateChangedEvent = function (a) end"); // Internal functions luaState.DoString("WIGInternal.IsPointInZone = function (a, b) end"); luaState.DoString("WIGInternal.VectorToZone = function (a, b) end"); luaState.DoString("WIGInternal.VectorToSegment = function (a, b, c) end"); luaState.DoString("WIGInternal.VectorToPoint = function (a, b) end"); luaState.DoString("WIGInternal.TranslatePoint = function (a, b, c) end"); // Mark package WIGInternal as loaded //luaState.SafeSetGlobal("package.loaded.WIGInternal", wiginternal); //luaState.SafeSetGlobal("package.preload.WIGInternal", wiginternal); LuaTable package = (LuaTable)luaState.Globals["package"]; LuaTable loaded = (LuaTable)package["loaded"]; loaded["WIGInternal"] = wiginternal; loaded["io"] = null; LuaTable preload = (LuaTable)package["preload"]; preload["WIGInternal"] = wiginternal; preload["io"] = null; // Deactivate luaState.Globals["io"] = null; // Set LuaTable env = (Eluant.LuaTable)luaState.CreateTable(); luaState.Globals["Env"] = env; // Loads the Wherigo LUA engine. using (BinaryReader bw = new BinaryReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("WF.Compiler.Resources.Wherigo.luac"))) { byte[] binChunk = bw.ReadBytes ((int)bw.BaseStream.Length); luaState.DoString(binChunk, "Wherigo.lua"); } }
public void ClrCallLoopVsVarargVsTable() { // Measures three approaches to processing 4,000 items through a Lua function fn(). // // 1. Call fn() 4,000 times from C#. // 2. Call with 4,000 arguments a Lua function that passes each argument through fn(), returning all 4,000 // results. // 3. Build a table with 4,000 elements in C#, and pass that to a function that calls fn() on each element, // replacing it with the result, and returning nothing. // // The results appear to be that 1 is fastest, 3 is very slightly slower than 1, and 2 is almost 20x slower // than 1. This is good, as it means that the most straightforward and intuitive way of using Eluant in // such a scenario is the fastest, and that tricky optimization techniques are not required. const int ITEMS = 4000; var clrSw = new Stopwatch(); var varargSw = new Stopwatch(); var tableSw = new Stopwatch(); IList<double> clrResults, varargResults, tableResults; var inputs = Enumerable.Range(1, ITEMS); using (var runtime = new LuaRuntime()) { runtime.DoString(@" -- Main loop function function fn(x) return x * x end -- Function for iterating the loop in Lua and collecting the results function loop(...) local function iter(x, ...) if x then return fn(x), iter(...) end end return iter(...) end -- Same, but using tables function loop_table(t) for k,v in ipairs(t) do t[k] = fn(v) end end "); using (var fn = (LuaFunction)runtime.Globals["fn"]) using (var loop = (LuaFunction)runtime.Globals["loop"]) using (var loop_table = (LuaFunction)runtime.Globals["loop_table"]) { // CLR loop. clrResults = new List<double>(ITEMS); clrSw.Start(); foreach (var i in inputs) { using (var r = fn.Call(i)) { clrResults.Add(r[0].ToNumber().Value); } } clrSw.Stop(); // Lua vararg. varargSw.Start(); using (var r = loop.Call(inputs.Select(i => (LuaValue)i).ToList())) { varargResults = r.Select(i => i.ToNumber().Value).ToList(); } varargSw.Stop(); // Lua loop over table. tableResults = new double[ITEMS]; tableSw.Start(); using (var table = runtime.CreateTable(inputs.Select(i => (LuaValue)i))) { loop_table.Call(table).Dispose(); for (int i = 0; i < ITEMS; ++i) { tableResults[i] = table[i + 1].ToNumber().Value; } } tableSw.Stop(); } } Assert.IsTrue(clrResults.SequenceEqual(varargResults), "Results equal (CLR/vararg)"); Assert.IsTrue(clrResults.SequenceEqual(tableResults), "Results equal (CLR/table)"); Assert.Inconclusive("CLR time: {0}, Vararg time: {1}, Table time: {2}", clrSw.Elapsed, varargSw.Elapsed, tableSw.Elapsed); }
public void HugeResultList() { var range = Enumerable.Range(1, 1000); Func<LuaVararg> fn = () => new LuaVararg(range.Select(i => (LuaNumber)i), true); using (var runtime = new LuaRuntime()) { using (var f = runtime.CreateFunctionFromDelegate(fn)) { runtime.Globals["callback"] = f; } using (var results = runtime.DoString("return callback()")) { Assert.AreEqual(range.Sum(), results.Select(i => (int)i.ToNumber().Value).Sum()); } } }