minilight-lua (empty) → 0.1.0.0
raw patch · 7 files changed
+271/−0 lines, 7 filesdep +basedep +bytestringdep +exceptionssetup-changed
Dependencies added: base, bytestring, exceptions, hslua, lens, linear, minilight, minilight-lua, mtl, sdl2, text, unix-time
Files
- CHANGELOG.md +6/−0
- LICENSE +21/−0
- Setup.hs +2/−0
- example/Main.hs +33/−0
- minilight-lua.cabal +56/−0
- src/MiniLight/FigureDSL.hs +37/−0
- src/MiniLight/Lua.hs +116/−0
+ CHANGELOG.md view
@@ -0,0 +1,6 @@+# Revision history for minilight-lua++## 0.1.0.0 -- 2020-05-10++* First version.+* Supports only limited API: translate, clip, text, picture
+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2020 myuon++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ example/Main.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE OverloadedStrings #-}+module Main where++import Control.Concurrent.MVar+import Control.Lens+import Control.Monad+import Data.Maybe+import MiniLight+import MiniLight.Lua++mainFile = "example/main.lua"++main :: IO ()+main = runLightT $ runMiniloop+ (defConfig { hotConfigReplacement = Just "example", appConfigFile = Just "" })+ initial+ (const mainloop)+ where+ initial = do+ comp <- registerComponent mainFile newLuaComponent+ reload mainFile++ return ()++ mainloop :: MiniLoop ()+ mainloop = do+ ref <- view _events+ evs <- liftIO $ tryReadMVar ref++ let notifys = case evs of+ Just evs -> mapMaybe asNotifyEvent evs+ _ -> []+ unless (null notifys) $ reload mainFile
+ minilight-lua.cabal view
@@ -0,0 +1,56 @@+cabal-version: 2.4+-- Initial package description 'minilight-lua.cabal' generated by 'cabal+-- init'. For further documentation, see+-- http://haskell.org/cabal/users-guide/++name: minilight-lua+version: 0.1.0.0+synopsis: A binding library of minilight for Lua langauge.+description:+ This library provides a way to write minilight component in Lua language.+-- bug-reports:+license: MIT+license-file: LICENSE+author: myuon+maintainer: ioi.joi.koi.loi@gmail.com+-- copyright:+category: Graphics+extra-source-files: CHANGELOG.md++source-repository head+ type: git+ location: https://github.com/myuon/minilight-lua.git++library+ exposed-modules:+ MiniLight.Lua+ MiniLight.FigureDSL+ -- other-modules:+ -- other-extensions:+ build-depends:+ base ^>=4.13.0.0,+ bytestring >= 0.10,+ exceptions >= 0.10,+ hslua >= 1.1,+ linear >= 1.20,+ minilight >= 0.5.0,+ mtl >= 2.2,+ sdl2 >= 2.4 && < 2.5,+ text >= 1.2,+ unix-time >= 0.4,+ hs-source-dirs: src+ default-language: Haskell2010+ cpp-options: -Fsumtype++executable example+ -- other-modules:+ -- other-extensions:+ build-depends:+ base ^>=4.13.0.0,+ lens,+ minilight >= 0.5.0,+ minilight-lua,+ mtl,+ hs-source-dirs: example+ main-is: Main.hs+ default-language: Haskell2010
+ src/MiniLight/FigureDSL.hs view
@@ -0,0 +1,37 @@+{-# LANGUAGE OverloadedStrings #-}+module MiniLight.FigureDSL where++import Control.Monad+import qualified Data.Config.Font as Font+import qualified Data.Text as T+import Data.Word (Word8)+import MiniLight+import qualified SDL+import qualified SDL.Vect as Vect+import Foreign.Lua++data FigureDSL+ = Empty+ | Translate (Vect.V2 Int) FigureDSL+ | Clip (Vect.V2 Int) (Vect.V2 Int) FigureDSL+ | Picture FilePath+ | Text (Vect.V4 Word8) T.Text+ deriving (Show, Read)++instance Peekable FigureDSL where+ peek = fmap read . peek++instance Pushable FigureDSL where+ push = push . show++construct :: FigureDSL -> MiniLight (Maybe Figure)+construct dsl = case dsl of+ Empty -> return $ Just emptyFigure+ Translate p fig -> fmap (fmap (translate p)) $ construct fig+ Clip p q fig ->+ fmap (fmap (clip (SDL.Rectangle (Vect.P p) q))) $ construct fig+ Picture path -> fmap Just $ picture path+ Text color t -> do+ font <- Font.loadFontFrom+ $ Font.Config (FontDescriptor "IPAGothic" (FontStyle False False)) 24 0+ fmap Just $ text font color t
+ src/MiniLight/Lua.hs view
@@ -0,0 +1,116 @@+{-# LANGUAGE OverloadedStrings #-}+module MiniLight.Lua where++import qualified Control.Monad.Caster as Caster+import Control.Monad.Catch+import Control.Monad.State hiding (state)+import qualified Data.ByteString as BS+import qualified Data.Component.Basic as Basic+import Data.IORef+import Data.Maybe+import qualified Data.Text as T+import qualified Data.Text.Encoding as TLE+import Data.UnixTime+import qualified Foreign.Lua as Lua+import Foreign.C.String+import Foreign.Ptr+import GHC.Generics (Generic)+import Linear+import MiniLight+import MiniLight.FigureDSL+import qualified SDL+import qualified SDL.Vect as Vect++data LuaComponentState = LuaComponentState {+ mousePosition :: V2 Int+} deriving (Eq, Show)++data LuaComponent = LuaComponent {+ expr :: String,+ state :: LuaComponentState,+ counter :: Int,+ updatedAt :: UnixTime+}++data LuaComponentEvent+ = SetExpr String++instance EventType LuaComponentEvent where+ getEventType (SetExpr _) = "set_expr"++instance ComponentUnit LuaComponent where+ figures comp = evalLuaComponent (expr comp) (state comp)++ onSignal ev = execStateT $ do+ lift $ Basic.emitBasicSignal ev (Basic.Config { Basic.size = V2 640 480, Basic.position = V2 0 0, Basic.visible = True })++ case asSignal ev of+ Just (SetExpr fs) -> do+ t <- liftIO getUnixTime+ modify $ \qc -> qc { expr = fs, counter = counter qc + 1, updatedAt = t }+ _ -> return ()++ case asSignal ev of+ Just (Basic.MouseOver p) ->+ modify $ \qc -> qc { state = (state qc) { mousePosition = p }, counter = counter qc + 1 }+ _ -> return ()++ useCache c1 c2 = updatedAt c1 == updatedAt c2++newLuaComponent :: LuaComponent+newLuaComponent = LuaComponent+ { expr = ""+ , state = LuaComponentState {mousePosition = 0}+ , counter = 0+ , updatedAt = UnixTime 0 0+ }++evalLuaComponent+ :: (HasLightEnv env, MonadIO m, MonadMask m)+ => String+ -> LuaComponentState+ -> LightT env m [Figure]+evalLuaComponent content state+ | content == "" = return []+ | otherwise = do+ result <- liftIO $ Lua.run $ Lua.try $ do+ Lua.openlibs+ loadLib+ st <- Lua.dostring $ TLE.encodeUtf8 $ T.pack content+ case st of+ Lua.OK -> Lua.callFunc "onDraw" ()+ _ -> Lua.throwException $ "Invalid status: " ++ show st++ case result of+ Left err -> Caster.err err >> return []+ Right rs -> liftMiniLight $ fmap catMaybes $ mapM construct rs++reload+ :: (HasLoaderEnv env, HasLightEnv env, HasLoopEnv env, MonadIO m, MonadMask m)+ => T.Text+ -> LightT env m ()+reload path = do+ fs <- liftIO $ readFile (T.unpack path)+ path @@! SetExpr fs++loadLib :: Lua.Lua ()+loadLib = Lua.requirehs "minilight" $ do+ Lua.create+ Lua.addfunction "picture" minilight_picture+ Lua.addfunction "translate" minilight_translate+ Lua.addfunction "text" minilight_text+ where+ minilight_picture :: BS.ByteString -> Lua.Lua FigureDSL+ minilight_picture cs = return $ Picture $ T.unpack $ TLE.decodeUtf8 cs++ minilight_translate :: Int -> Int -> FigureDSL -> Lua.Lua FigureDSL+ minilight_translate x y fig = return $ Translate (Vect.V2 x y) fig++ minilight_text :: BS.ByteString -> (Int, Int, Int, Int) -> Lua.Lua FigureDSL+ minilight_text cs (r, g, b, a) = return $ Text+ ( Vect.V4 (fromIntegral r)+ (fromIntegral g)+ (fromIntegral b)+ (fromIntegral a)+ )+ (TLE.decodeUtf8 cs)