module Termbox.Tea
(
Program (..),
run,
InitError (..),
Scene,
image,
fill,
cursor,
Image,
char,
fg,
bg,
bold,
underline,
blink,
at,
atRow,
atCol,
Color,
defaultColor,
red,
green,
yellow,
blue,
magenta,
cyan,
white,
bright,
color,
gray,
Event (..),
Key (..),
Mouse (..),
MouseButton (..),
Pos (..),
posUp,
posDown,
posLeft,
posRight,
Size (..),
)
where
import Control.Concurrent.MVar (newEmptyMVar, putMVar, takeMVar)
import Control.Monad (forever)
import qualified Ki
import Termbox
( Color,
Event (..),
Image,
InitError (..),
Key (..),
Mouse (..),
MouseButton (..),
Pos (..),
Scene,
Size (..),
at,
atCol,
atRow,
bg,
blink,
blue,
bold,
bright,
char,
color,
cursor,
cyan,
defaultColor,
fg,
fill,
getSize,
gray,
green,
image,
magenta,
poll,
posDown,
posLeft,
posRight,
posUp,
red,
underline,
white,
yellow,
)
import qualified Termbox (render, run)
data Program s = forall e.
Program
{
forall s. Program s -> Size -> s
initialize :: Size -> s,
()
pollEvent :: Maybe (IO e),
()
handleEvent :: s -> Event e -> IO s,
forall s. Program s -> s -> Scene
render :: s -> Scene,
forall s. Program s -> s -> Bool
finished :: s -> Bool
}
run :: Program s -> IO (Either InitError s)
run :: forall s. Program s -> IO (Either InitError s)
run Program s
program =
IO s -> IO (Either InitError s)
forall a. IO a -> IO (Either InitError a)
Termbox.run (Program s -> IO s
forall s. Program s -> IO s
run_ Program s
program)
run_ :: Program s -> IO s
run_ :: forall s. Program s -> IO s
run_ Program {Size -> s
$sel:initialize:Program :: forall s. Program s -> Size -> s
initialize :: Size -> s
initialize, Maybe (IO e)
$sel:pollEvent:Program :: ()
pollEvent :: Maybe (IO e)
pollEvent, s -> Event e -> IO s
$sel:handleEvent:Program :: ()
handleEvent :: s -> Event e -> IO s
handleEvent, s -> Scene
$sel:render:Program :: forall s. Program s -> s -> Scene
render :: s -> Scene
render, s -> Bool
$sel:finished:Program :: forall s. Program s -> s -> Bool
finished :: s -> Bool
finished} = do
s
state0 <- Size -> s
initialize (Size -> s) -> IO Size -> IO s
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO Size
getSize
let loop0 :: IO (Event e) -> s -> IO s
loop0 IO (Event e)
doPoll =
let loop :: s -> IO s
loop s
s0 =
if s -> Bool
finished s
s0
then s -> IO s
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure s
s0
else do
Scene -> IO ()
Termbox.render (s -> Scene
render s
s0)
Event e
event <- IO (Event e)
doPoll
s
s1 <- s -> Event e -> IO s
handleEvent s
s0 Event e
event
s -> IO s
loop s
s1
in s -> IO s
loop
case Maybe (IO e)
pollEvent of
Maybe (IO e)
Nothing -> IO (Event e) -> s -> IO s
loop0 IO (Event e)
forall e. IO (Event e)
poll s
state0
Just IO e
pollEvent1 -> do
MVar (Event e)
eventVar <- IO (MVar (Event e))
forall a. IO (MVar a)
newEmptyMVar
(Scope -> IO s) -> IO s
forall a. (Scope -> IO a) -> IO a
Ki.scoped \Scope
scope -> do
Scope -> IO Void -> IO ()
Ki.fork_ Scope
scope do
IO () -> IO Void
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever do
e
event <- IO e
pollEvent1
MVar (Event e) -> Event e -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Event e)
eventVar (e -> Event e
forall e. e -> Event e
EventUser e
event)
Scope -> IO Void -> IO ()
Ki.fork_ Scope
scope do
IO () -> IO Void
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever do
Event e
event <- IO (Event e)
forall e. IO (Event e)
Termbox.poll
MVar (Event e) -> Event e -> IO ()
forall a. MVar a -> a -> IO ()
putMVar MVar (Event e)
eventVar Event e
event
IO (Event e) -> s -> IO s
loop0 (MVar (Event e) -> IO (Event e)
forall a. MVar a -> IO a
takeMVar MVar (Event e)
eventVar) s
state0