@@ -711,6 +711,7 @@ pub const Lua = struct {
711711 }
712712
713713 /// This function allocates a new userdata of the given type
714+ /// Returns a pointer to the Lua-owned data
714715 /// See https://www.lua.org/manual/5.2/manual.html#lua_newuserdata
715716 pub fn newUserdata (lua : * Lua , comptime T : type ) * T {
716717 // safe to .? because this function throws a Lua error on out of memory
@@ -719,6 +720,15 @@ pub const Lua = struct {
719720 return opaqueCast (T , ptr );
720721 }
721722
723+ /// This function creates and pushes a slice of full userdata onto the stack.
724+ /// Returns a slice to the Lua-owned data.
725+ /// See https://www.lua.org/manual/5.2/manual.html#lua_newuserdata
726+ pub fn newUserdataSlice (lua : * Lua , comptime T : type , size : usize ) []T {
727+ // safe to .? because this function throws a Lua error on out of memory
728+ const ptr = c .lua_newuserdata (lua .state , @sizeOf (T ) * size ).? ;
729+ return @ptrCast ([* ]T , @alignCast (@alignOf ([* ]T ), ptr ))[0.. size ];
730+ }
731+
722732 /// Pops a key from the stack, and pushes a key-value pair from the table at the given index
723733 /// See https://www.lua.org/manual/5.2/manual.html#lua_next
724734 pub fn next (lua : * Lua , index : i32 ) bool {
@@ -1084,14 +1094,26 @@ pub const Lua = struct {
10841094 return result ;
10851095 }
10861096
1087- /// Returns a pointer of the given type to the userdata at the given index.
1088- /// Works for both full and light userdata. Otherwise returns an error.
1097+ /// Returns a Lua-owned userdata pointer of the given type at the given index.
1098+ /// Works for both light and full userdata.
1099+ /// Returns an error if the value is not a userdata.
10891100 /// See https://www.lua.org/manual/5.2/manual.html#lua_touserdata
10901101 pub fn toUserdata (lua : * Lua , comptime T : type , index : i32 ) ! * T {
10911102 if (c .lua_touserdata (lua .state , index )) | ptr | return opaqueCast (T , ptr );
10921103 return error .Fail ;
10931104 }
10941105
1106+ /// Returns a Lua-owned userdata slice of the given type at the given index.
1107+ /// Returns an error if the value is not a userdata.
1108+ /// See https://www.lua.org/manual/5.2/manual.html#lua_touserdata
1109+ pub fn toUserdataSlice (lua : * Lua , comptime T : type , index : i32 ) ! []T {
1110+ if (c .lua_touserdata (lua .state , index )) | ptr | {
1111+ const size = lua .rawLen (index ) / @sizeOf (T );
1112+ return @ptrCast ([* ]T , @alignCast (@alignOf ([* ]T ), ptr ))[0.. size ];
1113+ }
1114+ return error .Fail ;
1115+ }
1116+
10951117 /// Returns the `LuaType` of the value at the given index
10961118 /// Note that this is equivalent to lua_type but because type is a Zig primitive it is renamed to `typeOf`
10971119 /// See https://www.lua.org/manual/5.2/manual.html#lua_type
@@ -1389,12 +1411,22 @@ pub const Lua = struct {
13891411 c .luaL_checktype (lua .state , arg , @enumToInt (t ));
13901412 }
13911413
1392- /// Checks whether the function argument `arg` is a userdata of the type `type_name `
1414+ /// Checks whether the function argument `arg` is a userdata of the type `name `
13931415 /// Returns the userdata's memory-block address
13941416 /// See https://www.lua.org/manual/5.2/manual.html#luaL_checkudata
1395- pub fn checkUserdata (lua : * Lua , comptime T : type , arg : i32 ) * T {
1417+ pub fn checkUserdata (lua : * Lua , comptime T : type , arg : i32 , name : [: 0 ] const u8 ) * T {
13961418 // the returned pointer will not be null
1397- return opaqueCast (T , c .luaL_checkudata (lua .state , arg , @typeName (T )).? );
1419+ return opaqueCast (T , c .luaL_checkudata (lua .state , arg , name .ptr ).? );
1420+ }
1421+
1422+ /// Checks whether the function argument `arg` is a userdata of the type `name`
1423+ /// Returns a Lua-owned userdata slice
1424+ /// See https://www.lua.org/manual/5.2/manual.html#luaL_checkudata
1425+ pub fn checkUserdataSlice (lua : * Lua , comptime T : type , arg : i32 , name : [:0 ]const u8 ) []T {
1426+ // the returned pointer will not be null
1427+ const ptr = c .luaL_checkudata (lua .state , arg , name .ptr ).? ;
1428+ const size = lua .rawLen (arg ) / @sizeOf (T );
1429+ return @ptrCast ([* ]T , @alignCast (@alignOf ([* ]T ), ptr ))[0.. size ];
13981430 }
13991431
14001432 /// Checks whether the function argument arg is a number and returns this number cast to an unsigned
@@ -1652,12 +1684,21 @@ pub const Lua = struct {
16521684
16531685 /// This function works like `Lua.checkUserdata()` except it returns a Zig error instead of raising a Lua error on fail
16541686 /// See https://www.lua.org/manual/5.2/manual.html#luaL_testudata
1655- pub fn testUserdata (lua : * Lua , comptime T : type , arg : i32 ) ! * T {
1656- if (c .luaL_testudata (lua .state , arg , @typeName ( T ) )) | ptr | {
1687+ pub fn testUserdata (lua : * Lua , comptime T : type , arg : i32 , name : [: 0 ] const u8 ) ! * T {
1688+ if (c .luaL_testudata (lua .state , arg , name . ptr )) | ptr | {
16571689 return opaqueCast (T , ptr );
16581690 } else return error .Fail ;
16591691 }
16601692
1693+ /// This function works like `Lua.checkUserdataSlice()` except it returns a Zig error instead of raising a Lua error on fail
1694+ /// See https://www.lua.org/manual/5.2/manual.html#luaL_checkudata
1695+ pub fn testUserdataSlice (lua : * Lua , comptime T : type , arg : i32 , name : [:0 ]const u8 ) ! []T {
1696+ if (c .luaL_testudata (lua .state , arg , name .ptr )) | ptr | {
1697+ const size = lua .rawLen (arg ) / @sizeOf (T );
1698+ return @ptrCast ([* ]T , @alignCast (@alignOf ([* ]T ), ptr ))[0.. size ];
1699+ } else return error .Fail ;
1700+ }
1701+
16611702 /// Converts any Lua value at the given index into a string in a reasonable format
16621703 /// See https://www.lua.org/manual/5.2/manual.html#luaL_tolstring
16631704 pub fn toBytesFmt (lua : * Lua , index : i32 ) [:0 ]const u8 {
0 commit comments