{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module WGPU.Internal.Instance
(
Instance (..),
withInstance,
LogCallback,
LogLevel (..),
setLogLevel,
logLevelToText,
logStdout,
Version (..),
getVersion,
versionToText,
)
where
import Data.Bits (shiftR, (.&.))
import Data.Text (Text)
import qualified Data.Text as Text
import qualified Data.Text.IO as TextIO
import Data.Word (Word32, Word8)
import Foreign (Ptr, freeHaskellFunPtr, nullFunPtr)
import Foreign.C (CChar, peekCString)
import WGPU.Internal.Memory (ToRaw, raw)
import WGPU.Raw.Dynamic (withWGPU)
import WGPU.Raw.Generated.Enum.WGPULogLevel (WGPULogLevel (WGPULogLevel))
import qualified WGPU.Raw.Generated.Enum.WGPULogLevel as WGPULogLevel
import WGPU.Raw.Generated.Fun (WGPUHsInstance)
import qualified WGPU.Raw.Generated.Fun as RawFun
import WGPU.Raw.Types (WGPULogCallback)
newtype Instance = Instance {Instance -> WGPUHsInstance
wgpuHsInstance :: WGPUHsInstance}
instance Show Instance where show :: Instance -> String
show Instance
_ = String
"<Instance>"
instance ToRaw Instance WGPUHsInstance where
raw :: Instance -> ContT c IO WGPUHsInstance
raw = WGPUHsInstance -> ContT c IO WGPUHsInstance
forall (f :: * -> *) a. Applicative f => a -> f a
pure (WGPUHsInstance -> ContT c IO WGPUHsInstance)
-> (Instance -> WGPUHsInstance)
-> Instance
-> ContT c IO WGPUHsInstance
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Instance -> WGPUHsInstance
wgpuHsInstance
data LogLevel
= Trace
| Debug
| Info
| Warn
| Error
deriving (LogLevel -> LogLevel -> Bool
(LogLevel -> LogLevel -> Bool)
-> (LogLevel -> LogLevel -> Bool) -> Eq LogLevel
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: LogLevel -> LogLevel -> Bool
$c/= :: LogLevel -> LogLevel -> Bool
== :: LogLevel -> LogLevel -> Bool
$c== :: LogLevel -> LogLevel -> Bool
Eq, Int -> LogLevel -> ShowS
[LogLevel] -> ShowS
LogLevel -> String
(Int -> LogLevel -> ShowS)
-> (LogLevel -> String) -> ([LogLevel] -> ShowS) -> Show LogLevel
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [LogLevel] -> ShowS
$cshowList :: [LogLevel] -> ShowS
show :: LogLevel -> String
$cshow :: LogLevel -> String
showsPrec :: Int -> LogLevel -> ShowS
$cshowsPrec :: Int -> LogLevel -> ShowS
Show)
type LogCallback = LogLevel -> Text -> IO ()
withInstance ::
FilePath ->
Maybe LogCallback ->
(Instance -> IO a) ->
IO a
withInstance :: String -> Maybe LogCallback -> (Instance -> IO a) -> IO a
withInstance String
dylibPath Maybe LogCallback
mLog Instance -> IO a
program =
String -> (WGPUHsInstance -> IO a) -> IO a
forall a. String -> (WGPUHsInstance -> IO a) -> IO a
withWGPU String
dylibPath ((WGPUHsInstance -> IO a) -> IO a)
-> (WGPUHsInstance -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$
\WGPUHsInstance
winst -> do
FunPtr (WGPULogLevel -> Ptr CChar -> IO ())
logCallback_c <- case Maybe LogCallback
mLog of
Maybe LogCallback
Nothing -> FunPtr (WGPULogLevel -> Ptr CChar -> IO ())
-> IO (FunPtr (WGPULogLevel -> Ptr CChar -> IO ()))
forall (f :: * -> *) a. Applicative f => a -> f a
pure FunPtr (WGPULogLevel -> Ptr CChar -> IO ())
forall a. FunPtr a
nullFunPtr
Just LogCallback
logFn -> (WGPULogLevel -> Ptr CChar -> IO ())
-> IO (FunPtr (WGPULogLevel -> Ptr CChar -> IO ()))
mkLogCallback ((WGPULogLevel -> Ptr CChar -> IO ())
-> IO (FunPtr (WGPULogLevel -> Ptr CChar -> IO ())))
-> (LogCallback -> WGPULogLevel -> Ptr CChar -> IO ())
-> LogCallback
-> IO (FunPtr (WGPULogLevel -> Ptr CChar -> IO ()))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LogCallback -> WGPULogLevel -> Ptr CChar -> IO ()
toRawLogCallback (LogCallback -> IO (FunPtr (WGPULogLevel -> Ptr CChar -> IO ())))
-> LogCallback -> IO (FunPtr (WGPULogLevel -> Ptr CChar -> IO ()))
forall a b. (a -> b) -> a -> b
$ LogCallback
logFn
WGPUHsInstance
-> FunPtr (WGPULogLevel -> Ptr CChar -> IO ()) -> IO ()
RawFun.wgpuSetLogCallback WGPUHsInstance
winst FunPtr (WGPULogLevel -> Ptr CChar -> IO ())
logCallback_c
a
result <- Instance -> IO a
program (WGPUHsInstance -> Instance
Instance WGPUHsInstance
winst)
case Maybe LogCallback
mLog of
Maybe LogCallback
Nothing -> () -> IO ()
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
Just LogCallback
_ -> do
WGPUHsInstance
-> FunPtr (WGPULogLevel -> Ptr CChar -> IO ()) -> IO ()
RawFun.wgpuSetLogCallback WGPUHsInstance
winst FunPtr (WGPULogLevel -> Ptr CChar -> IO ())
forall a. FunPtr a
nullFunPtr
FunPtr (WGPULogLevel -> Ptr CChar -> IO ()) -> IO ()
forall a. FunPtr a -> IO ()
freeHaskellFunPtr FunPtr (WGPULogLevel -> Ptr CChar -> IO ())
logCallback_c
a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure a
result
setLogLevel :: Instance -> LogLevel -> IO ()
setLogLevel :: Instance -> LogLevel -> IO ()
setLogLevel Instance
inst LogLevel
lvl =
WGPUHsInstance -> WGPULogLevel -> IO ()
RawFun.wgpuSetLogLevel (Instance -> WGPUHsInstance
wgpuHsInstance Instance
inst) (LogLevel -> WGPULogLevel
logLevelToWLogLevel LogLevel
lvl)
foreign import ccall "wrapper"
mkLogCallback ::
(WGPULogLevel -> Ptr CChar -> IO ()) ->
IO WGPULogCallback
toRawLogCallback :: LogCallback -> (WGPULogLevel -> Ptr CChar -> IO ())
toRawLogCallback :: LogCallback -> WGPULogLevel -> Ptr CChar -> IO ()
toRawLogCallback LogCallback
logFn WGPULogLevel
wLogLevel Ptr CChar
cMsg = do
Text
msg <- String -> Text
Text.pack (String -> Text) -> IO String -> IO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CChar -> IO String
peekCString Ptr CChar
cMsg
LogCallback
logFn (WGPULogLevel -> LogLevel
wLogLevelToLogLevel WGPULogLevel
wLogLevel) Text
msg
wLogLevelToLogLevel :: WGPULogLevel -> LogLevel
wLogLevelToLogLevel :: WGPULogLevel -> LogLevel
wLogLevelToLogLevel WGPULogLevel
wLvl =
case WGPULogLevel
wLvl of
WGPULogLevel
WGPULogLevel.Trace -> LogLevel
Trace
WGPULogLevel
WGPULogLevel.Debug -> LogLevel
Debug
WGPULogLevel
WGPULogLevel.Info -> LogLevel
Info
WGPULogLevel
WGPULogLevel.Warn -> LogLevel
Warn
WGPULogLevel
WGPULogLevel.Error -> LogLevel
Error
WGPULogLevel
_ -> LogLevel
Error
logLevelToWLogLevel :: LogLevel -> WGPULogLevel
logLevelToWLogLevel :: LogLevel -> WGPULogLevel
logLevelToWLogLevel LogLevel
lvl =
case LogLevel
lvl of
LogLevel
Trace -> WGPULogLevel
forall a. (Eq a, Num a) => a
WGPULogLevel.Trace
LogLevel
Debug -> WGPULogLevel
forall a. (Eq a, Num a) => a
WGPULogLevel.Debug
LogLevel
Info -> WGPULogLevel
forall a. (Eq a, Num a) => a
WGPULogLevel.Info
LogLevel
Warn -> WGPULogLevel
forall a. (Eq a, Num a) => a
WGPULogLevel.Warn
LogLevel
Error -> WGPULogLevel
forall a. (Eq a, Num a) => a
WGPULogLevel.Error
logLevelToText :: LogLevel -> Text
logLevelToText :: LogLevel -> Text
logLevelToText LogLevel
lvl =
case LogLevel
lvl of
LogLevel
Trace -> Text
"Trace"
LogLevel
Debug -> Text
"Debug"
LogLevel
Info -> Text
"Info"
LogLevel
Warn -> Text
"Warn"
LogLevel
Error -> Text
"Error"
logStdout :: LogLevel -> Text -> IO ()
logStdout :: LogCallback
logStdout LogLevel
lvl Text
msg = Text -> IO ()
TextIO.putStrLn (Text -> IO ()) -> Text -> IO ()
forall a b. (a -> b) -> a -> b
$ Text
"[" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> LogLevel -> Text
logLevelToText LogLevel
lvl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"]: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
msg
data Version = Version
{ Version -> Word8
major :: !Word8,
Version -> Word8
minor :: !Word8,
Version -> Word8
patch :: !Word8,
Version -> Word8
subPatch :: !Word8
}
deriving (Version -> Version -> Bool
(Version -> Version -> Bool)
-> (Version -> Version -> Bool) -> Eq Version
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Version -> Version -> Bool
$c/= :: Version -> Version -> Bool
== :: Version -> Version -> Bool
$c== :: Version -> Version -> Bool
Eq, Int -> Version -> ShowS
[Version] -> ShowS
Version -> String
(Int -> Version -> ShowS)
-> (Version -> String) -> ([Version] -> ShowS) -> Show Version
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Version] -> ShowS
$cshowList :: [Version] -> ShowS
show :: Version -> String
$cshow :: Version -> String
showsPrec :: Int -> Version -> ShowS
$cshowsPrec :: Int -> Version -> ShowS
Show)
getVersion :: Instance -> IO Version
getVersion :: Instance -> IO Version
getVersion Instance
inst = Word32 -> Version
w32ToVersion (Word32 -> Version) -> IO Word32 -> IO Version
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> WGPUHsInstance -> IO Word32
RawFun.wgpuGetVersion (Instance -> WGPUHsInstance
wgpuHsInstance Instance
inst)
where
w32ToVersion :: Word32 -> Version
w32ToVersion :: Word32 -> Version
w32ToVersion Word32
w =
let major :: Word8
major = Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ (Word32
w Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
24) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xFF
minor :: Word8
minor = Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ (Word32
w Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
16) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xFF
patch :: Word8
patch = Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ (Word32
w Word32 -> Int -> Word32
forall a. Bits a => a -> Int -> a
`shiftR` Int
8) Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xFF
subPatch :: Word8
subPatch = Word32 -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Word8) -> Word32 -> Word8
forall a b. (a -> b) -> a -> b
$ Word32
w Word32 -> Word32 -> Word32
forall a. Bits a => a -> a -> a
.&. Word32
0xFF
in Version :: Word8 -> Word8 -> Word8 -> Word8 -> Version
Version {Word8
subPatch :: Word8
patch :: Word8
minor :: Word8
major :: Word8
subPatch :: Word8
patch :: Word8
minor :: Word8
major :: Word8
..}
versionToText :: Version -> Text
versionToText :: Version -> Text
versionToText Version
ver =
Text
"" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Word8 -> Text
forall a. Show a => a -> Text
showt (Version -> Word8
major Version
ver)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"."
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Word8 -> Text
forall a. Show a => a -> Text
showt (Version -> Word8
minor Version
ver)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"."
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Word8 -> Text
forall a. Show a => a -> Text
showt (Version -> Word8
patch Version
ver)
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"."
Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Word8 -> Text
forall a. Show a => a -> Text
showt (Version -> Word8
subPatch Version
ver)
showt :: Show a => a -> Text
showt :: a -> Text
showt = String -> Text
Text.pack (String -> Text) -> (a -> String) -> a -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> String
forall a. Show a => a -> String
show