Initial commit
This commit is contained in:
98
source/luad/conversions/arrays.d
Normal file
98
source/luad/conversions/arrays.d
Normal file
@ -0,0 +1,98 @@
|
||||
/**
|
||||
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");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user