-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathMain.hs
119 lines (95 loc) · 3.26 KB
/
Main.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
119
{-# LANGUAGE Arrows #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE FlexibleContexts #-}
module
Main
where
import Prelude hiding (id, (.))
import Control.Applicative
import Control.Category
import Control.Arrow
import Data.Maybe
import Graphics.Gloss
import qualified Graphics.Gloss.Interface.IO.Game as G
import Control.Artery
import Buttons
import GlossInterface
filterA :: Monad m => (a -> Bool) -> Artery m (Maybe a) (Maybe a)
filterA cond = arr $ \mx -> do {x <- mx; if cond x then Just x else Nothing}
scanMaybe :: Monad m => (i -> a -> a) -> a -> Artery m (Maybe i) a
scanMaybe f a0 = scan (\mi a -> maybe a (f `flip` a) mi) a0
drSwitch :: Monad m => Artery m a b -> Artery m (a, Maybe (Artery m a b)) b
drSwitch ar0 = Artery $ step ar0
where
step ar (x, mNext) r =
do
(y, ar') <- runArtery ar x
let next = drSwitch (fromMaybe ar' mNext)
r y next
dkSwitch ::
Monad m =>
Artery m a b ->
Artery m (a, b) (Maybe t) ->
(Artery m a b -> t -> Artery m a b) ->
Artery m a b
dkSwitch ar0 test0 fNext = Artery $ step ar0 test0
where
step ar test x r =
do
(y, ar') <- runArtery ar x
(mt, test') <- runArtery test (x, y)
let next = maybe (dkSwitch ar' test' fNext) (fNext ar') mt
r y next
-- Main body
mainArtery ::
Artery IO (Float, Maybe G.Event) Picture
mainArtery = proc (_, e) ->
do
click0 <- filterA ((Just Click ==) . filter0) -< e
click5 <- filterA ((Just Click ==) . filter5) -< e
click10 <- filterA ((Just Click ==) . filter10) -< e
toggle0 <- filterA ((Just Toggle ==) . filter0) -< e
toggle5 <- filterA ((Just Toggle ==) . filter5) -< e
toggle10 <- filterA ((Just Toggle ==) . filter10) -< e
mode0 <- scanMaybe (\_ b -> not b) True -< toggle0
mode5 <- scanMaybe (\_ b -> not b) True -< toggle5
mode10 <- scanMaybe (\_ b -> not b) True -< toggle10
-- Part 1: static version
count0 <- scan ($) 0 -<
foldr (.) id $ catMaybes [(+1) <$ click0, (const 0) <$ toggle0]
count5 <- scanMaybe ($) 0 -< (if mode5 then (+1) else id) <$ click5
count10 <- scanMaybe ($) 0 -< (+1) <$ click10
let show0 = if mode0 then count0 else -1
let show5 = if mode5 then count5 else -1
let show10 = if mode10 then count10 else -1
-- Part 2: dynamic version
-- Every toggle event causes switch of counters,
-- with every counter is newly created.
let newCounter0 = if not mode0 then counter else pure (-1)
dynamic0 <- drSwitch counter -< (click0, newCounter0 <$ toggle0)
-- Every toggle event causes switch of a counter,
-- with one counter reused.
dynamic5 <-
(let
test = arr $ \((_, t), _) -> t
active pa _ = dkSwitch pa test inactive
inactive pa _ = dkSwitch (pure (-1)) test (\_ -> active pa)
in
active (arr fst >>> counter) ())
-< (click5, () <$ toggle5)
returnA -<
renderButtons
show0 (Just dynamic0)
show5 (Just dynamic5)
show10 Nothing
where
counter :: Artery IO (Maybe a) Int
counter = proc e -> scanMaybe ($) 0 -< (+1) <$ e
main :: IO ()
main =
do
playArtery
(InWindow "Artery Example" (320, 240) (800, 200))
white
30
mainArtery