{-# LANGUAGE MonoLocalBinds #-}
{-# LANGUAGE ViewPatterns #-}
{-# OPTIONS_GHC -Wall -fno-warn-tabs #-}

module Shaderc.Include where

import Foreign.Ptr
import Foreign.Marshal
import Foreign.Storable
import Foreign.Storable.PeekPoke
import Control.Monad.Trans
import Control.Monad.Cont

import qualified Data.ByteString as BS

import qualified Shaderc.Include.Core as C

data Result ud = Result {
	forall ud. Result ud -> ByteString
resultSourceName :: BS.ByteString,
	forall ud. Result ud -> ByteString
resultContent :: BS.ByteString,
	forall ud. Result ud -> Maybe ud
resultUserData :: Maybe ud }
	deriving Int -> Result ud -> ShowS
[Result ud] -> ShowS
Result ud -> String
(Int -> Result ud -> ShowS)
-> (Result ud -> String)
-> ([Result ud] -> ShowS)
-> Show (Result ud)
forall ud. Show ud => Int -> Result ud -> ShowS
forall ud. Show ud => [Result ud] -> ShowS
forall ud. Show ud => Result ud -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall ud. Show ud => Int -> Result ud -> ShowS
showsPrec :: Int -> Result ud -> ShowS
$cshow :: forall ud. Show ud => Result ud -> String
show :: Result ud -> String
$cshowList :: forall ud. Show ud => [Result ud] -> ShowS
showList :: [Result ud] -> ShowS
Show

resultToCore :: Pokable ud => Result ud -> ContT r IO C.Result
resultToCore :: forall ud r. Pokable ud => Result ud -> ContT r IO Result
resultToCore Result {
	resultSourceName :: forall ud. Result ud -> ByteString
resultSourceName = ByteString
src,
	resultContent :: forall ud. Result ud -> ByteString
resultContent = ByteString
cnt,
	resultUserData :: forall ud. Result ud -> Maybe ud
resultUserData = Maybe ud
ud } = do
	(Ptr CChar
csrc, Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> Word64
csrcln) <- (((Ptr CChar, Int) -> IO r) -> IO r) -> ContT r IO (Ptr CChar, Int)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT ((((Ptr CChar, Int) -> IO r) -> IO r)
 -> ContT r IO (Ptr CChar, Int))
-> (((Ptr CChar, Int) -> IO r) -> IO r)
-> ContT r IO (Ptr CChar, Int)
forall a b. (a -> b) -> a -> b
$ ByteString -> ((Ptr CChar, Int) -> IO r) -> IO r
forall a. ByteString -> ((Ptr CChar, Int) -> IO a) -> IO a
BS.useAsCStringLen ByteString
src
	(Ptr CChar
ccnt, Int -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral -> Word64
ccntln) <- (((Ptr CChar, Int) -> IO r) -> IO r) -> ContT r IO (Ptr CChar, Int)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT ((((Ptr CChar, Int) -> IO r) -> IO r)
 -> ContT r IO (Ptr CChar, Int))
-> (((Ptr CChar, Int) -> IO r) -> IO r)
-> ContT r IO (Ptr CChar, Int)
forall a b. (a -> b) -> a -> b
$ ByteString -> ((Ptr CChar, Int) -> IO r) -> IO r
forall a. ByteString -> ((Ptr CChar, Int) -> IO a) -> IO a
BS.useAsCStringLen ByteString
cnt
	(Ptr ud -> Ptr ()
forall a b. Ptr a -> Ptr b
castPtr -> Ptr ()
pud) <- ((Ptr ud -> IO r) -> IO r) -> ContT r IO (Ptr ud)
forall {k} (r :: k) (m :: k -> *) a.
((a -> m r) -> m r) -> ContT r m a
ContT (((Ptr ud -> IO r) -> IO r) -> ContT r IO (Ptr ud))
-> ((Ptr ud -> IO r) -> IO r) -> ContT r IO (Ptr ud)
forall a b. (a -> b) -> a -> b
$ Maybe ud -> (Ptr ud -> IO r) -> IO r
forall a b. Pokable a => Maybe a -> (Ptr a -> IO b) -> IO b
withPokedMaybe Maybe ud
ud
	Result -> ContT r IO Result
forall a. a -> ContT r IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Result -> ContT r IO Result) -> Result -> ContT r IO Result
forall a b. (a -> b) -> a -> b
$ C.Result {
		resultSourceName :: Ptr CChar
C.resultSourceName = Ptr CChar
csrc,
		resultSourceNameLength :: Word64
C.resultSourceNameLength = Word64
csrcln,
		resultContent :: Ptr CChar
C.resultContent = Ptr CChar
ccnt,
		resultContentLength :: Word64
C.resultContentLength = Word64
ccntln,
		resultUserData :: Ptr ()
C.resultUserData = Ptr ()
pud }

type ResolveFn ud =
	Maybe ud -> BS.ByteString -> C.Type -> BS.ByteString -> Int ->
	IO (Result ud)

resolveFnToCore :: Storable ud => ResolveFn ud -> (C.ResolveFn, C.ResultReleaseFn)
resolveFnToCore :: forall ud.
Storable ud =>
ResolveFn ud -> (ResolveFn, ResultReleaseFn)
resolveFnToCore ResolveFn ud
f = (ResolveFn ud -> ResolveFn
forall ud. Storable ud => ResolveFn ud -> ResolveFn
resolveFnToResolveFnCore ResolveFn ud
f, ResultReleaseFn
resultReleaseFn)

resultReleaseFn :: C.ResultReleaseFn
resultReleaseFn :: ResultReleaseFn
resultReleaseFn Ptr ()
pud Ptr Result
prslt = Ptr () -> IO ()
forall a. Ptr a -> IO ()
free Ptr ()
pud IO () -> IO () -> IO ()
forall a b. IO a -> IO b -> IO b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Ptr Result -> IO ()
forall a. Ptr a -> IO ()
free Ptr Result
prslt

resolveFnToResolveFnCore :: Storable ud => ResolveFn ud -> C.ResolveFn
resolveFnToResolveFnCore :: forall ud. Storable ud => ResolveFn ud -> ResolveFn
resolveFnToResolveFnCore ResolveFn ud
f Ptr ()
pud Ptr CChar
crqtd Type
tp Ptr CChar
crqtng Word64
dpt = do
	Maybe ud
ud <- case Ptr ()
pud of
		Ptr ()
NullPtr -> Maybe ud -> IO (Maybe ud)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ud
forall a. Maybe a
Nothing
		Ptr ()
_ -> ud -> Maybe ud
forall a. a -> Maybe a
Just (ud -> Maybe ud) -> IO ud -> IO (Maybe ud)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr ud -> IO ud
forall a. Storable a => Ptr a -> IO a
peek (Ptr () -> Ptr ud
forall a b. Ptr a -> Ptr b
castPtr Ptr ()
pud)
	ByteString
rqtd <- Ptr CChar -> IO ByteString
BS.packCString Ptr CChar
crqtd
	ByteString
rqtng <- Ptr CChar -> IO ByteString
BS.packCString Ptr CChar
crqtng
	Ptr Result
prslt <- IO (Ptr Result)
forall a. Storable a => IO (Ptr a)
malloc
	Result ud
rslt <- ResolveFn ud
f Maybe ud
ud ByteString
rqtd Type
tp ByteString
rqtng (Int -> IO (Result ud)) -> Int -> IO (Result ud)
forall a b. (a -> b) -> a -> b
$ Word64 -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word64
dpt
	(((() -> IO ()) -> IO ()) -> (() -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure) (((() -> IO ()) -> IO ()) -> IO ())
-> (ContT () IO () -> (() -> IO ()) -> IO ())
-> ContT () IO ()
-> IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ContT () IO () -> (() -> IO ()) -> IO ()
forall {k} (r :: k) (m :: k -> *) a.
ContT r m a -> (a -> m r) -> m r
runContT
		(ContT () IO () -> IO ()) -> ContT () IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ IO () -> ContT () IO ()
forall (m :: * -> *) a. Monad m => m a -> ContT () m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IO () -> ContT () IO ())
-> (Result -> IO ()) -> Result -> ContT () IO ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr Result -> Result -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr Result
prslt (Result -> ContT () IO ()) -> ContT () IO Result -> ContT () IO ()
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Result ud -> ContT () IO Result
forall ud r. Pokable ud => Result ud -> ContT r IO Result
resultToCore Result ud
rslt
	Ptr Result -> IO (Ptr Result)
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Ptr Result
prslt