basics.md 4.3 KB

Integration

Luwra does not provide a standalone version of Lua nor does it isolate its features. This means that all functions and classes operate on lua_State (or the alias State). Doing this allows you to integrate Luwra however you like.

Stack Interaction

Although Luwra provides a variety of features, its main concern is efficient and safe interaction with the Lua stack.

A fundamental aspect of this is the abstract template Value. Every type which can be pushed onto or read from the stack has a specialization of it. Useful implementations are provided out of the box:

C++ type Pushable Readable Lua type
bool yes yes boolean
signed char yes yes number (integer since 5.3)
signed short yes yes number (integer since 5.3)
signed int yes yes number (integer since 5.3)
signed long int yes yes number (integer since 5.3)
signed long long int yes yes number (integer since 5.3)
unsigned char yes yes number (integer since 5.3)
unsigned short yes yes number (integer since 5.3)
unsigned int yes yes number (integer since 5.3)
unsigned long int yes yes number (integer since 5.3)
unsigned long long int yes yes number (integer since 5.3)
float yes yes number
double yes yes number
long double yes yes number
const char* yes yes string
std::string yes yes string
std::nullptr_t yes yes nil
std::tuple<T> yes no depends on the tuple contents
lua_CFunction yes no function
NativeFunction<R(A...)> no yes function
FieldVector yes no table

Note: Some numeric types have a different size than their matching Lua type - they will be truncated during push or read operations.

Pushing C++ values

When pushing values onto the stack you can either use Value<T>::push or the more convenient push.

// Push an integer
luwra::push(lua, 1338);

// Push a number
luwra::push(lua, 13.37);

// Push a boolean
luwra::push(lua, false);

// Push a string
luwra::push(lua, "Hello World");

This produces the following stack layout:

Absolute Position Relative Position Value
1 -4 1338
2 -3 13.37
3 -2 false
4 -1 "Hello World"

It is possible to provide a template parameter to push to enforce pushing a specific type. In most cases you are probably better off by letting the compiler infer the template parameter.

Reading Lua values

Simple retrieval of Lua values is done using read<T>. Consider the stack layout from the previous example. This is how you would retrieve a value from the stack.

// Retrieve the integer at position 1
int value = luwra::read<int>(lua, 1);

// Similiar with a relative index
int value = luwra::read<int>(lua, -4);

Read and type errors

What happens when a value which you are trying to read mismatches the expected type or cannot be converted to it? Most Value<T> specializations use Lua's luaL_check* functions to retrieve the values from the stack. This means that no exceptions will be thrown - instead the error handling is delegated to the Lua VM. Have a look at the error handling documentation for more information.