-
Notifications
You must be signed in to change notification settings - Fork 2
/
Host6.hs
118 lines (98 loc) · 2.78 KB
/
Host6.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
{-
Copyright : (c) Dave Laing, 2016
License : BSD3
Maintainer : [email protected]
Stability : experimental
Portability : non-portable
-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE GADTs #-}
module Host6 (
go6
, Input(..)
, Output(..)
, SampleApp6
) where
import Data.Maybe (isJust)
import Control.Monad (unless)
import Control.Monad.Identity (Identity(..))
import Control.Monad.IO.Class (MonadIO, liftIO)
import Control.Monad.Ref
import Control.Monad.Primitive (PrimMonad)
import Data.IORef (readIORef)
import System.IO
import Data.Dependent.Sum
import Reflex
import Reflex.Host.Class
data Input t = Input {
ieOpen :: Event t ()
, ieRead :: Event t String
}
data Output t = Output {
oeWrite :: Event t String
, oeQuit :: Event t ()
}
type SampleApp6 t m = (Reflex t, MonadHold t m)
=> Input t
-> m (Output t)
type SampleApp6IO t m = ( Ref m ~ Ref IO
, ReflexHost t
, MonadIO (HostFrame t)
, PrimMonad (HostFrame t)
)
=> Output t
-> PerformEventT t m (Event t ())
host :: (forall t m. SampleApp6 t m)
-> (forall t m. SampleApp6IO t m)
-> IO ()
host myGuest myGuestIO =
runSpiderHost $ do
(eOpen, eOpenTriggerRef) <- newEventWithTriggerRef
(eRead, eReadTriggerRef) <- newEventWithTriggerRef
out <- runHostFrame $ myGuest $ Input eOpen eRead
(eQuit, FireCommand fire) <- hostPerformEventT $ myGuestIO out
hQuit <- subscribeEvent eQuit
let
readPhase =
readEvent hQuit >>= sequence
loop = do
input <- liftIO getLine
mEReadTrigger <- liftIO $ readIORef eReadTriggerRef
mQuit <- case mEReadTrigger of
Nothing ->
return []
Just eTrigger ->
fire [eTrigger :=> Identity input] readPhase
let quit = any isJust mQuit
unless quit
loop
mEOpenTrigger <- liftIO $ readIORef eOpenTriggerRef
mQuit <- case mEOpenTrigger of
Nothing ->
return []
Just eTrigger ->
fire [eTrigger :=> Identity ()] readPhase
let quit = any isJust mQuit
unless quit
loop
guest :: SampleApp6 t m
guest (Input eOpen eRead) = do
let
eMessage = ffilter (/= "/quit") eRead
eQuit = () <$ ffilter (== "/quit") eRead
eWrite = leftmost [
"Hi" <$ eOpen
, eMessage
, "Bye" <$ eQuit
]
return $ Output eWrite eQuit
guestIO :: SampleApp6IO t m
guestIO (Output eWrite eQuit) = do
performEvent_ $ (\x -> liftIO . putStrLn $ "> " ++ x) <$> eWrite
return eQuit
go6 :: IO ()
go6 = do
hSetBuffering stdin LineBuffering
host guest guestIO