Skip to content

Lua State

Quahu edited this page May 19, 2023 · 5 revisions

Creating a Lua state

To create a Lua state, you can use any of the constructor overloads of the Lua type.
They allow you to specify the culture, allocator, and even allow you to customize the way values are marshaled to and from Lua.

using (var lua = new Lua())
{
    // code
}

Lua is disposable; disposing a Lua instance closes the relevant Lua state and frees any allocated memory.

In future examples, the wiki might omit the instantiation of Lua and simply use a lua variable which you're meant to replace with your instance.

Running Lua Code

There are a bunch of Lua instance methods that allow running Lua code:

  • Execute() - executes the specified code without returning any values Lua returned
  • Evaluate() - executes the specified code and returns any values Lua returned (Evaluate<T>() can be used for a single value)
  • Compile() - compiles the specified code and returns it as a LuaFunction, allowing for efficient execution at a later point

Examples:

using (var lua = new Lua())
{
    // Set global variable x to 2
    lua.Execute("x = 2");

    // Get the result of x + 2
    var result = lua.Evaluate<int>("return x + 2");
    Console.WriteLine(result); // 4
}
Compile() is more complex as it returns a LuaFunction which we have to work with manually.
// Compiles a LuaFunction that increments x by 1 and returns it
using (var function = lua.Compile("x = x + 1 return x"))
{
    // Call it a few times
    for (var i = 0; i < 3; i++)
    {
        // A Lua function can return multiple values which are all pushed onto the Lua stack
        using (var results = function.Call())
        {
            result = results.First.GetValue<int>();

            // Prints the value of x after each call, i.e. 3, 4, 5
            Console.WriteLine(result);
        }
    }
}

Globals

Lua exposes multiple ways to get and set global variables within Lua:

  • TryGetGlobal<T>() and SetGlobal<T>
  • Globals - returns a LuaTable for global variables

Examples:

lua.SetGlobal("x", 42);

var x = lua.GetGlobal<int>("x");

Console.WriteLine(x); // 42

Lua.Globals allows for more operations on the global variables:

var hasX = lua.Globals.ContainsKey("x");
Console.WriteLine(hasX); // True

var globalCount = lua.Globals.Count();
Console.WriteLine(globalCount); // 1

Libraries

Lua offers a wide range of useful standard libraries. See Lua manual.

Laylua exposes these standard libraries through the LuaLibraries.Standard nested static type.
For example, the mathematical functions library can be accessed via LuaLibraries.Standard.Math.

Laylua utilizes the ILuaLibrary interface to handle both standard libraries and custom libraries. This interface enables the opening and closing functionalities for the specified Lua instance, allowing you to manage the accessibility of libraries dynamically.

Examples:

Opening all standard libraries:

lua.OpenStandardLibraries();

Getting the value of $\pi$ from Lua:

lua.OpenLibrary(LuaLibraries.Standard.Math);

var pi = lua.Evaluate<double>("return math.pi");

Console.WriteLine(pi); // 3.141592653589793

Exceptions

When it comes to Lua and its related entities, they follow the standard usage of exceptions such as ArgumentException or InvalidOperationException. However, there are specific exception types designed for handling failures in Lua interactions.

  • LuaException serves as the base exception type that is thrown when an error occurs during Lua interaction.

  • LuaPanicException is the exception type used when an error happens in an unprotected environment and Lua triggers the panic handler. This type of exception is commonly associated with user code issues, although not always, and by default, it causes Lua to terminate the application. Laylua uses a customized panic handler that prevents the application from terminating and instead raises the exception. This behavior applies to both Windows and Unix systems.

Examples:

lua.Execute("return x.y"); // LuaException: [string "?"]:1: attempt to index a nil value (global 'x')

Clone this wiki locally