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 Clear() { using (var runtime = new LuaRuntime()) { using (var t = runtime.CreateTable(Enumerable.Range(1, 100).Select(i => (LuaValue)i))) { Assert.AreEqual(100, t.Count); t.Clear(); Assert.AreEqual(0, t.Count); } } }
public void DisallowCrossRuntimeReferences() { using (var runtime1 = new LuaRuntime()) using (var runtime2 = new LuaRuntime()) { using (var table = runtime1.CreateTable()) { Assert.Throws<InvalidOperationException>(() => runtime2.Globals["foo"] = table); using (var table2 = runtime2.CreateTable()) { Assert.Throws<InvalidOperationException>(() => table["foo"] = table2); } } } }
public void Count() { using (var runtime = new LuaRuntime()) { using (var t = runtime.CreateTable()) { Assert.AreEqual(0, t.Count); t[1] = 1; t[3] = "foo"; t["x"] = "bar"; t[6] = null; Assert.AreEqual(3, t.Count); } } }
public void KeysAndValues() { using (var runtime = new LuaRuntime()) { using (var t = runtime.CreateTable()) { t[1] = 2; t[3] = 4; t["foo"] = "bar"; var keys = new HashSet<LuaValue>(new LuaValue[] { 1, 3, "foo" }); var values = new HashSet<LuaValue>(new LuaValue[] { 2, 4, "bar" }); Assert.IsTrue(keys.SetEquals(t.Keys), "Keys"); Assert.IsTrue(values.SetEquals(t.Values), "Values"); } } }
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 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 ReferenceTableRewriteDoesNotConfuseReferences() { // Make sure that after a reference table rewrite everything still points where it should. using (var runtime = new LuaRuntime()) { using (var t1 = runtime.CreateTable()) using (var t2 = runtime.CreateTable()) { t1["foo"] = "bar"; t2[5] = 6; t2["fixture"] = new LuaOpaqueClrObject(this); // 1000 cycles should trigger a rewrite. foreach (var t in Enumerable.Range(1, 1000).Select(j => runtime.CreateTable()).ToList()) { t.Dispose(); } Assert.AreEqual("bar", t1["foo"].ToString()); Assert.AreEqual(6, t2[5].ToNumber()); using (var clrRef = (LuaOpaqueClrObjectReference)t2["fixture"]) { Assert.AreSame(this, clrRef.ClrObject); } } } }
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 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); }