-
-
Notifications
You must be signed in to change notification settings - Fork 28
Expand file tree
/
Copy pathUserdata.hs
More file actions
63 lines (58 loc) · 2.09 KB
/
Userdata.hs
File metadata and controls
63 lines (58 loc) · 2.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-|
Module : HsLua.Marshalling.Userdata
Copyright : © 2007–2012 Gracjan Polak;
© 2012–2016 Ömer Sinan Ağacan;
© 2017-2021 Albert Krewinkel
License : MIT
Maintainer : Albert Krewinkel <tarleb+hslua@zeitkraut.de>
Stability : beta
Portability : non-portable (depends on GHC)
Convenience functions to use Haskell values as Lua userdata.
-}
module HsLua.Marshalling.Userdata
( pushIterator
) where
import Control.Monad (void)
import HsLua.Core as Lua
-- | Pushes three values to the stack that can be used in a generic for
-- loop to lazily iterate over all values in the list. Keeps the
-- remaining list in a userdata state.
--
-- If the values pusher function returns @'NumResults' 0@ for a list
-- item, then this item will be skipped and the values for the next item
-- will be pushed.
pushIterator :: forall a e. LuaError e
=> (a -> LuaE e NumResults) -- ^ pusher for the values
-> [a] -- ^ list to iterate over lazily
-> LuaE e NumResults
pushIterator pushValues xs = do
-- push initial state
pushHaskellFunction nextItem
pushInitialState
pushnil
return (NumResults 3)
where
nextItem :: LuaE e NumResults
nextItem = do
props <- fromuserdata @[a] (nthBottom 1) statename
case props of
Nothing -> failLua
"Error in iterator: could not retrieve iterator state."
Just [] -> 2 <$ (pushnil *> pushnil) -- end loop
Just (y:ys) -> do
success <- putuserdata @[a] (nthBottom 1) statename ys
if not success
then failLua "Error in iterator: could not update iterator state."
else pushValues y >>= \case
0 -> nextItem -- keep going if nothing was pushed
n -> return n
statename :: Name
statename = "HsLua iterator state"
pushInitialState :: LuaE e ()
pushInitialState = do
newhsuserdata @[a] xs
void (newudmetatable statename)
setmetatable (nth 2)