module Language.Javascript.JSaddle.Native.Internal (
wrapJSVal
, wrapJSString
, withJSVal
, withJSVals
, withObject
, withJSString
) where
import Control.Monad.Trans.Reader (ask)
import Control.Monad.IO.Class (MonadIO(..))
import Language.Javascript.JSaddle.Types
(JSContextRef(..), AsyncCommand(..), JSM(..), JSString(..),
Object(..), JSVal(..), JSValueReceived(..), JSValueForSend(..),
JSStringReceived(..), JSStringForSend(..), JSObjectForSend(..))
import System.Mem.Weak (addFinalizer)
import Control.Monad.Primitive (touch)
import Control.Monad (when)
wrapJSVal :: JSValueReceived -> JSM JSVal
wrapJSVal (JSValueReceived ref) = do
let result = JSVal ref
when (ref >= 5) $ do
ctx <- JSM ask
liftIO . addFinalizer result $ doSendAsyncCommand ctx $ FreeRef $ JSValueForSend ref
return result
wrapJSString :: MonadIO m => JSStringReceived -> m JSString
wrapJSString (JSStringReceived ref) = return $ JSString ref
withJSVal :: MonadIO m => JSVal -> (JSValueForSend -> m a) -> m a
withJSVal v@(JSVal ref) f =
do result <- f (JSValueForSend ref)
liftIO $ touch v
return result
withJSVals :: MonadIO m => [JSVal] -> ([JSValueForSend] -> m a) -> m a
withJSVals v f =
do result <- f (map (\(JSVal ref) -> JSValueForSend ref) v)
liftIO $ mapM_ touch v
return result
withObject :: MonadIO m => Object -> (JSObjectForSend -> m a) -> m a
withObject (Object o) f = withJSVal o (f . JSObjectForSend)
withJSString :: MonadIO m => JSString -> (JSStringForSend -> m a) -> m a
withJSString v@(JSString ref) f =
do result <- f (JSStringForSend ref)
liftIO $ touch v
return result