{-# LANGUAGE CPP #-}
module Foreign.Lua.Raw.Userdata
( hslua_fromuserdata
, hslua_newhsuserdata
, hslua_newudmetatable
) where
import Foreign.C (CInt (CInt), CString)
import Foreign.Lua.Raw.Auxiliary (luaL_testudata)
import Foreign.Lua.Raw.Functions (lua_newuserdata)
import Foreign.Lua.Raw.Types
( LuaBool (..)
, StackIndex (..)
, State (..)
)
import Foreign.Ptr (castPtr, nullPtr)
import Foreign.StablePtr (newStablePtr, deRefStablePtr)
import Foreign.Storable (peek, poke, sizeOf)
#ifdef ALLOW_UNSAFE_GC
#define SAFTY unsafe
#else
#define SAFTY safe
#endif
foreign import ccall SAFTY "hsludata.h hslua_newudmetatable"
hslua_newudmetatable :: State
-> CString
-> IO LuaBool
hslua_newhsuserdata :: State -> a -> IO ()
hslua_newhsuserdata l x = do
xPtr <- newStablePtr x
udPtr <- lua_newuserdata l (fromIntegral $ sizeOf xPtr)
poke (castPtr udPtr) xPtr
{-# INLINABLE hslua_newhsuserdata #-}
hslua_fromuserdata :: State
-> StackIndex
-> CString
-> IO (Maybe a)
hslua_fromuserdata l idx name = do
udPtr <- luaL_testudata l idx name
if udPtr == nullPtr
then return Nothing
else Just <$> (peek (castPtr udPtr) >>= deRefStablePtr)
{-# INLINABLE hslua_fromuserdata #-}