Files
lunch-games/source/luad/conversions/arrays.d
2025-04-29 01:59:15 +02:00

99 lines
2.0 KiB
D

/**
Internal module for pushing and getting _arrays.
All _arrays with LuaD compatible element types are supported.
*/
module luad.conversions.arrays;
import std.traits;
import std.range : ElementType;
import luad.c.all;
import luad.stack;
void pushArray(T)(lua_State* L, ref T arr) if (isArray!T)
{
assert(arr.length <= int.max, "lua_createtable only supports int.max many elements");
lua_createtable(L, cast(int) arr.length, 0);
foreach(i, v; arr)
{
pushValue(L, i + 1); //Lua tables start at 1, not 0
pushValue(L, v);
lua_rawset(L, -3);
}
}
// TODO: do the immutable/const initialization *properly*
T getArray(T)(lua_State* L, int idx) if (isArray!T)
{
alias ElemType = ElementType!T;
auto len = lua_objlen(L, idx);
static if(isStaticArray!T)
{
if(len != T.length)
luaL_error(L, "Incorrect number of array elements: %d, expected: %d", len, T.length);
Unqual!ElemType[T.length] arr;
}
else
auto arr = new Unqual!ElemType[len];
foreach(i; 0 .. len)
{
lua_pushinteger(L, i + 1);
lua_gettable(L, idx < 0? idx - 1 : idx);
arr[i] = popValue!ElemType(L);
}
return cast(T)arr;
}
void fillStaticArray(T)(lua_State* L, ref T arr) if(isStaticArray!T)
{
foreach(i, ref elem; arr)
{
elem = getValue!(typeof(elem))(L, cast(int)(-arr.length + i));
}
}
void pushStaticArray(T)(lua_State* L, ref T arr) if(isStaticArray!T)
{
foreach(elem; arr)
pushValue(L, elem);
}
version(unittest) import luad.testing;
unittest
{
lua_State* L = luaL_newstate();
scope(success) lua_close(L);
luaL_openlibs(L);
{
int[] arr = [1, 2, 3];
pushValue(L, arr);
assert(lua_istable(L, -1));
lua_setglobal(L, "array");
unittest_lua(L, `
for i, expected in pairs{1, 2, 3} do
local value = array[i]
assert(value == expected,
("bad array index: '%s' = '%s' (expected '%s')"):format(i, value, expected)
)
end
`);
}
{
unittest_lua(L, `array = {"hello", "from", "lua"}`);
lua_getglobal(L, "array");
string[] arr = popValue!(string[])(L);
assert(arr[0] == "hello");
assert(arr[1] == "from");
assert(arr[2] == "lua");
}
}