h-raylib 5.5.2.1 → 5.5.3.0
raw patch · 12 files changed
+197/−97 lines, 12 filesdep −exceptionsdep ~containersdep ~template-haskell
Dependencies removed: exceptions
Dependency ranges changed: containers, template-haskell
Files
- CHANGELOG.md +7/−0
- CONTRIBUTING.md +0/−21
- README.md +3/−0
- default.nix +1/−1
- h-raylib.cabal +27/−9
- lib/rl_bindings.c +2/−4
- src/Raylib/Internal/Foreign.hs +9/−0
- src/Raylib/Internal/TH.hs +4/−30
- src/Raylib/Types/Core.hs +104/−19
- src/Raylib/Util.hs +13/−12
- src/Raylib/Util/Lenses.hs +1/−1
- src/Raylib/Util/Lenses/TH.hs +26/−0
CHANGELOG.md view
@@ -8,6 +8,13 @@ h-raylib's version numbers do not follow the usual format. The first two numbers in the version track the underlying C raylib version. For example, `5.1.x.x` versions use raylib 5.1 under the hood. The third number represents breaking changes (renamed/deleted functions or modules). The last number represents non-breaking changes (new functions or modules, bug fixes, etc). The safest version bound format to use is `h-raylib >=x.y.z.w && <x.y.(z+1)` (instead of the usual `^>=` bound). +## Version 5.5.3.0+_14 August 2025_++- **BREAKING CHANGE**: Bracket functions now only work with the `IO` monad+- \[[#60](https://github.com/Anut-py/h-raylib/issues/60)\] Added the `disable-lens` flag+- Loosened version bounds+ ## Version 5.5.2.1 _28 October 2024_
CONTRIBUTING.md view
@@ -25,24 +25,3 @@ ### In progress - Add web build support \[[#4](https://github.com/Anut-py/h-raylib/issues/4)\]--### Implemented--Items which have been completed but not published to hackage.--(none)--### Published--Items which have been published to hackage.--- Implement automatic memory management for callbacks (`5.1.1.0`)-- Move Raylib.Internal.Native functions into the modules where they are called (`5.1.1.0`)- - Use Template Haskell to clean up boilerplate-- Split Raylib.Types into multiple modules (`5.1.1.0`)-- Bind `raygui` \[[#34](https://github.com/Anut-py/h-raylib/issues/34)\] (`5.1.1.0`)-- Bind `raymath` (`4.6.0.1`)-- Bind `rcamera` (`4.6.0.1`)-- Bind `rlgl` (`4.5.3.2`)-- Allow manual unloading of assets for larger projects (`4.5.3.1`)-- Make it easier to pass shader parameters (`4.5.3.0`)
README.md view
@@ -81,6 +81,9 @@ The flags `platform-windows`, `platform-mac`, `platform-linux`, and `platform-bsd` are also supported if you want to build for a different platform. +If you prefer not to use the `lens` package, you may enable the `disable-lens` flag. This+removes the dependency on `lens` and disables `Raylib.Util.Lenses`.+ ## Running in GHCi You can use this library in GHCi just like any other library, but you will need to add `--constraint="h-raylib +ghci"` to the command. For example, in the root folder of this repository, you could use the command below to use the library through GHCi.
default.nix view
@@ -3,7 +3,7 @@ }: mkDerivation { pname = "h-raylib";- version = "5.5.2.1";+ version = "5.5.3.0"; src = ./.; isLibrary = true; isExecutable = buildExamples;
h-raylib.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: h-raylib-version: 5.5.2.1+version: 5.5.3.0 synopsis: Raylib bindings for Haskell category: graphics description:@@ -45,7 +45,7 @@ source-repository head type: git- location: git://github.com/Anut-py/h-raylib.git+ location: https://github.com/Anut-py/h-raylib.git flag detect-platform description:@@ -101,6 +101,11 @@ default: False manual: True +flag disable-lens+ description: Exclude the lens dependency and Raylib.Util.Lenses+ default: False+ manual: True+ common example-options default-language: Haskell2010 @@ -229,24 +234,34 @@ Raylib.Util.Colors Raylib.Util.GUI Raylib.Util.GUI.Styles- Raylib.Util.Lenses Raylib.Util.Math Raylib.Util.RLGL + if !flag(disable-lens)+ exposed-modules:+ Raylib.Util.Lenses+ other-modules: Raylib.Internal.TH Raylib.Internal.Web.Native Raylib.Internal.Web.Processable + if !flag(disable-lens)+ other-modules:+ Raylib.Util.Lenses.TH+ build-depends: , base >=4.0 && <4.22 , bytestring >=0.11.0 && <0.13- , containers >=0.6.0 && <0.7- , exceptions >=0.10.4 && <0.11- , lens >=4.0 && <5.4- , linear >=1.22 && <1.24- , template-haskell >=2.16.0.0 && <2.23.0.0+ , containers >=0.6.0 && <0.9+ , template-haskell >=2.16.0.0 && <2.24 , text >=2.0 && <2.2+ + + if !flag(disable-lens)+ build-depends:+ , linear >=1.22 && <1.24+ , lens >=4.0 && <5.4 hs-source-dirs: src default-language: Haskell2010@@ -325,7 +340,7 @@ else cc-options:- -DPLATFORM_DESKTOP_GLFW -Wno-int-to-void-pointer-cast+ -DPLATFORM_DESKTOP_GLFW -Wno-int-to-void-pointer-cast -Wno-discarded-qualifiers c-sources: lib/rgui_bindings.c@@ -363,3 +378,6 @@ if flag(ghci) cpp-options: -DGHCI+ + if flag(disable-lens)+ cpp-options: -DDISABLE_LENS
lib/rl_bindings.c view
@@ -2382,10 +2382,8 @@ void CustomCallback(int logLevel, const char *text, va_list args) {- size_t n = vsnprintf(NULL, 0, text, args) + 1;- char *buffer = malloc(n);- vsnprintf(buffer, n, text, args);- customCallback(logLevel, buffer);+ char *formatted = TextFormat(text, args);+ customCallback(logLevel, formatted); } RLBIND void SetTraceLogCallback_(TraceLogCallback_ a)
src/Raylib/Internal/Foreign.hs view
@@ -44,8 +44,13 @@ import Foreign (FunPtr, Ptr, Storable (peek, peekByteOff, poke, sizeOf), allocaBytes, castPtr, malloc, newArray, nullPtr, peekArray, plusPtr, pokeArray0, with, withArray, withArrayLen) import Foreign.C (CFloat, CInt, CString, CUChar, CUInt, peekCString, withCString) import Foreign.C.Types (CBool, CChar, CShort, CUShort)++#ifndef DISABLE_LENS+ import Linear (V2, V3, V4) +#endif+ -- Internal utility functions #ifdef WEB_FFI@@ -111,11 +116,15 @@ let val = arr !! i in rlFreeDependents val (plusPtr ptr (i * sizeOf val)) ) +#ifndef DISABLE_LENS+ instance Freeable (V2 a) instance Freeable (V3 a) instance Freeable (V4 a)++#endif rlFreeMaybeArray :: (Freeable a, Storable a) => Maybe [a] -> Ptr a -> IO () rlFreeMaybeArray Nothing _ = return ()
src/Raylib/Internal/TH.hs view
@@ -3,58 +3,32 @@ {-# LANGUAGE TupleSections #-} -- | Template Haskell functions used internally-module Raylib.Internal.TH (genLenses, genNative) where--import Control.Lens (makeLensesFor)-import Control.Monad (zipWithM)+module Raylib.Internal.TH (genNative) where #ifdef WEB_FFI import Language.Haskell.TH ( Body (NormalB), Clause (Clause),- Con (RecC),- Dec (DataD, FunD, SigD),+ Dec (FunD, SigD), DecsQ, Exp (AppE, LitE, VarE),- Info (TyConI), Lit (StringL),- Name, TypeQ, mkName,- nameBase,- reify, ) import Raylib.Internal.Web.Native (callRaylibFunction) #else import Language.Haskell.TH- ( Con (RecC),- Dec (DataD, ForeignD),+ ( Dec (ForeignD), DecsQ,- Info (TyConI),- Name, TypeQ,- mkName,- nameBase,- reify, Foreign (ImportF), Callconv (CCall), Safety (Safe),+ mkName, Foreign (ImportF), Callconv (CCall), Safety (Safe), ) #endif---- | Creates lenses with an underscore before field names; e.g. @vector2'x@--- becomes the lens @_vector2'x@-genLenses :: [Name] -> DecsQ-genLenses names = do- infos <- mapM reify names- concat <$> zipWithM genLensesForType names infos- where- genLensesForType name (TyConI (DataD _ _ _ _ [RecC _ ctors] _)) =- makeLensesFor mapping name- where- mapping = map (\(a, _, _) -> let fName = nameBase a in (fName, '_' : fName)) ctors- genLensesForType _ _ = error "(genLenses) Received a name that does not refer to a valid type!" -- | Generates native code for the given functions. On non-web platforms, this -- means @foreign import@ statements. On web platforms, this means
src/Raylib/Types/Core.hs view
@@ -2,6 +2,7 @@ {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE CPP #-} -- | Bindings for types used in all raylib modules module Raylib.Types.Core@@ -140,11 +141,16 @@ newCString, peekCString, )-import Linear (V2(V2), V3(V3), V4(V4)) import Raylib.Internal (Closeable(..), _unloadAutomationEventList, addAutomationEventList) import Raylib.Internal.Foreign (Freeable (rlFreeDependents), c'free, peekStaticArray, pokeStaticArray) +#ifndef DISABLE_LENS +import Linear (V2(V2), V3(V3), V4(V4))++#endif++ --------------------------------------- -- core enums ------------------------- ---------------------------------------@@ -659,25 +665,97 @@ -- core structures -------------------- --------------------------------------- +pattern Vector2 :: Float -> Float -> Vector2+pattern Vector3 :: Float -> Float -> Float -> Vector3+pattern Vector4 :: Float -> Float -> Float -> Float -> Vector4 +#ifdef DISABLE_LENS++data Vector2' = Vector2' Float Float deriving (Eq, Show, Freeable)+instance Storable Vector2' where+ sizeOf _ = 8+ alignment _ = 4+ peek _p = do+ x <- realToFrac <$> peek (p'vector2'x _p)+ y <- realToFrac <$> peek (p'vector2'y _p)+ return $ Vector2' x y+ poke _p (Vector2' x y) = do+ poke (p'vector2'x _p) (realToFrac x)+ poke (p'vector2'y _p) (realToFrac y)+ return ()+type Vector2 = Vector2'++pattern Vector2+ { vector2'x ,+ vector2'y+ } = Vector2' vector2'x vector2'y+{-# COMPLETE Vector2 :: Vector2' #-}++data Vector3' = Vector3' Float Float Float deriving (Eq, Show, Freeable)++instance Storable Vector3' where+ sizeOf _ = 12+ alignment _ = 4+ peek _p = do+ x <- realToFrac <$> peek (p'vector3'x _p)+ y <- realToFrac <$> peek (p'vector3'y _p)+ z <- realToFrac <$> peek (p'vector3'z _p)+ return $ Vector3' x y z+ poke _p (Vector3' x y z) = do+ poke (p'vector3'x _p) (realToFrac x)+ poke (p'vector3'y _p) (realToFrac y)+ poke (p'vector3'z _p) (realToFrac z)+ return ()++type Vector3 = Vector3'++pattern Vector3+ { vector3'x ,+ vector3'y ,+ vector3'z+ } = Vector3' vector3'x vector3'y vector3'z+{-# COMPLETE Vector3 :: Vector3' #-}++data Vector4' = Vector4' Float Float Float Float deriving (Eq, Show, Freeable)++instance Storable Vector4' where+ sizeOf _ = 16+ alignment _ = 4+ peek _p = do+ x <- realToFrac <$> peek (p'vector4'x _p)+ y <- realToFrac <$> peek (p'vector4'y _p)+ z <- realToFrac <$> peek (p'vector4'z _p)+ w <- realToFrac <$> peek (p'vector4'w _p)+ return $ Vector4' x y z w+ poke _p (Vector4' x y z w) = do+ poke (p'vector4'x _p) (realToFrac x)+ poke (p'vector4'y _p) (realToFrac y)+ poke (p'vector4'z _p) (realToFrac z)+ poke (p'vector4'w _p) (realToFrac w)+ return ()++type Vector4 = Vector4'++pattern Vector4+ { vector4'x,+ vector4'y,+ vector4'z,+ vector4'w+ } = Vector4' vector4'x vector4'y vector4'z vector4'w+{-# COMPLETE Vector4 :: Vector4' #-}++#else+ type Vector2 = V2 Float -pattern Vector2 :: Float -> Float -> Vector2 pattern Vector2 { vector2'x , vector2'y } = V2 vector2'x vector2'y {-# COMPLETE Vector2 :: V2 #-} -p'vector2'x :: Ptr Vector2 -> Ptr CFloat-p'vector2'x = (`plusPtr` 0)--p'vector2'y :: Ptr Vector2 -> Ptr CFloat-p'vector2'y = (`plusPtr` 4)- type Vector3 = V3 Float -pattern Vector3 :: Float -> Float -> Float -> Vector3 pattern Vector3 { vector3'x , vector3'y ,@@ -685,18 +763,8 @@ } = V3 vector3'x vector3'y vector3'z {-# COMPLETE Vector3 :: V3 #-} -p'vector3'x :: Ptr Vector3 -> Ptr CFloat-p'vector3'x = (`plusPtr` 0)--p'vector3'y :: Ptr Vector3 -> Ptr CFloat-p'vector3'y = (`plusPtr` 4)--p'vector3'z :: Ptr Vector3 -> Ptr CFloat-p'vector3'z = (`plusPtr` 8)- type Vector4 = V4 Float -pattern Vector4 :: a -> a -> a -> a -> V4 a pattern Vector4 { vector4'x, vector4'y,@@ -704,6 +772,23 @@ vector4'w } = V4 vector4'x vector4'y vector4'z vector4'w {-# COMPLETE Vector4 :: V4 #-}++#endif++p'vector2'x :: Ptr Vector2 -> Ptr CFloat+p'vector2'x = (`plusPtr` 0)++p'vector2'y :: Ptr Vector2 -> Ptr CFloat+p'vector2'y = (`plusPtr` 4)++p'vector3'x :: Ptr Vector3 -> Ptr CFloat+p'vector3'x = (`plusPtr` 0)++p'vector3'y :: Ptr Vector3 -> Ptr CFloat+p'vector3'y = (`plusPtr` 4)++p'vector3'z :: Ptr Vector3 -> Ptr CFloat+p'vector3'z = (`plusPtr` 8) vectorToColor :: Vector4 -> Color vectorToColor (Vector4 x y z w) = Color (round $ x * 255) (round $ y * 255) (round $ z * 255) (round $ w * 255)
src/Raylib/Util.hs view
@@ -35,7 +35,6 @@ where import Control.Monad (void)-import Control.Monad.Catch (MonadMask, bracket, bracket_) import Control.Monad.IO.Class (MonadIO (liftIO)) import Raylib.Core (beginBlendMode, beginDrawing, beginMode2D, beginMode3D, beginScissorMode, beginShaderMode, beginTextureMode, beginVrStereoMode, closeWindow, endBlendMode, endDrawing, endMode2D, endMode3D, endScissorMode, endShaderMode, endTextureMode, endVrStereoMode, initWindow, setTargetFPS, windowShouldClose) import Raylib.Internal (WindowResources, Closeable (..), managed)@@ -52,6 +51,7 @@ VrStereoConfig, ) import Raylib.Util.Math (Vector (vectorNormalize, (|-|)))+import Control.Exception (bracket, bracket_) #ifdef WEB_FFI @@ -66,10 +66,11 @@ #endif ++ -- | NOTE: Only for native targets. If your program is intended to -- run on the web, use `raylibApplication` instead. withWindow ::- (MonadIO m, MonadMask m) => -- | Window width Int -> -- | Window height@@ -78,32 +79,32 @@ String -> -- | Target FPS Int ->- (WindowResources -> m b) ->- m b+ (WindowResources -> IO b) ->+ IO b withWindow w h title fps = bracket (liftIO $ initWindow w h title <* setTargetFPS fps) (liftIO . closeWindow . Just) -drawing :: (MonadIO m, MonadMask m) => m b -> m b+drawing :: IO b -> IO b drawing = bracket_ (liftIO beginDrawing) (liftIO endDrawing) -mode2D :: (MonadIO m, MonadMask m) => Camera2D -> m b -> m b+mode2D :: Camera2D -> IO b -> IO b mode2D camera = bracket_ (liftIO (beginMode2D camera)) (liftIO endMode2D) -mode3D :: (MonadIO m, MonadMask m) => Camera3D -> m b -> m b+mode3D :: Camera3D -> IO b -> IO b mode3D camera = bracket_ (liftIO (beginMode3D camera)) (liftIO endMode3D) -textureMode :: (MonadIO m, MonadMask m) => RenderTexture -> m b -> m b+textureMode :: RenderTexture -> IO b -> IO b textureMode rt = bracket_ (liftIO (beginTextureMode rt)) (liftIO endTextureMode) -shaderMode :: (MonadIO m, MonadMask m) => Shader -> m b -> m b+shaderMode :: Shader -> IO b -> IO b shaderMode shader = bracket_ (liftIO (beginShaderMode shader)) (liftIO endShaderMode) -blendMode :: (MonadIO m, MonadMask m) => BlendMode -> m b -> m b+blendMode :: BlendMode -> IO b -> IO b blendMode bm = bracket_ (liftIO (beginBlendMode bm)) (liftIO endBlendMode) -scissorMode :: (MonadIO m, MonadMask m) => Int -> Int -> Int -> Int -> m b -> m b+scissorMode :: Int -> Int -> Int -> Int -> IO b -> IO b scissorMode x y width height = bracket_ (liftIO (beginScissorMode x y width height)) (liftIO endScissorMode) -vrStereoMode :: (MonadIO m, MonadMask m) => VrStereoConfig -> m b -> m b+vrStereoMode :: VrStereoConfig -> IO b -> IO b vrStereoMode config = bracket_ (liftIO (beginVrStereoMode config)) (liftIO endVrStereoMode) -- | Gets the direction of a camera as a ray.
src/Raylib/Util/Lenses.hs view
@@ -5,7 +5,7 @@ module Raylib.Util.Lenses where import Control.Lens (Lens', lens)-import Raylib.Internal.TH (genLenses)+import Raylib.Util.Lenses.TH (genLenses) import qualified Raylib.Types as RL $( genLenses
+ src/Raylib/Util/Lenses/TH.hs view
@@ -0,0 +1,26 @@+module Raylib.Util.Lenses.TH (genLenses) where++import Language.Haskell.TH+ ( Con (RecC),+ Dec (DataD),+ DecsQ,+ Name,+ Info (TyConI),+ nameBase,+ reify+ )+import Control.Lens (makeLensesFor)+import Control.Monad (zipWithM)++-- | Creates lenses with an underscore before field names; e.g. @vector2'x@+-- becomes the lens @_vector2'x@+genLenses :: [Name] -> DecsQ+genLenses names = do+ infos <- mapM reify names+ concat <$> zipWithM genLensesForType names infos+ where+ genLensesForType name (TyConI (DataD _ _ _ _ [RecC _ ctors] _)) =+ makeLensesFor mapping name+ where+ mapping = map (\(a, _, _) -> let fName = nameBase a in (fName, '_' : fName)) ctors+ genLensesForType _ _ = error "(genLenses) Received a name that does not refer to a valid type!"