{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
module HsLua.Marshalling.Userdata
( pushIterator
) where
import Control.Monad (void)
import HsLua.Core as Lua
pushIterator :: forall a e. LuaError e
=> (a -> LuaE e NumResults)
-> [a]
-> LuaE e NumResults
pushIterator :: forall a e.
LuaError e =>
(a -> LuaE e NumResults) -> [a] -> LuaE e NumResults
pushIterator a -> LuaE e NumResults
pushValues [a]
xs = do
forall e. LuaError e => HaskellFunction e -> LuaE e ()
pushHaskellFunction LuaE e NumResults
nextItem
LuaE e ()
pushInitialState
forall e. LuaE e ()
pushnil
forall (m :: * -> *) a. Monad m => a -> m a
return (CInt -> NumResults
NumResults CInt
3)
where
nextItem :: LuaE e NumResults
nextItem :: LuaE e NumResults
nextItem = do
Maybe [a]
props <- forall a e. StackIndex -> Name -> LuaE e (Maybe a)
fromuserdata @[a] (CInt -> StackIndex
nthBottom CInt
1) Name
statename
case Maybe [a]
props of
Maybe [a]
Nothing -> forall e a. LuaError e => String -> LuaE e a
failLua
String
"Error in iterator: could not retrieve iterator state."
Just [] -> NumResults
2 forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ (forall e. LuaE e ()
pushnil forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> forall e. LuaE e ()
pushnil)
Just (a
y:[a]
ys) -> do
Bool
success <- forall a e. StackIndex -> Name -> a -> LuaE e Bool
putuserdata @[a] (CInt -> StackIndex
nthBottom CInt
1) Name
statename [a]
ys
if Bool -> Bool
not Bool
success
then forall e a. LuaError e => String -> LuaE e a
failLua String
"Error in iterator: could not update iterator state."
else a -> LuaE e NumResults
pushValues a
y forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
NumResults
0 -> LuaE e NumResults
nextItem
NumResults
n -> forall (m :: * -> *) a. Monad m => a -> m a
return NumResults
n
statename :: Name
statename :: Name
statename = Name
"HsLua iterator state"
pushInitialState :: LuaE e ()
pushInitialState :: LuaE e ()
pushInitialState = do
forall a e. a -> Int -> LuaE e ()
newhsuserdatauv @[a] [a]
xs Int
0
forall (f :: * -> *) a. Functor f => f a -> f ()
void (forall e. Name -> LuaE e Bool
newudmetatable Name
statename)
forall e. StackIndex -> LuaE e ()
setmetatable (CInt -> StackIndex
nth CInt
2)