-
Notifications
You must be signed in to change notification settings - Fork 30
/
Main.hs
89 lines (69 loc) · 2.4 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
{-# LANGUAGE Arrows #-}
{-# LANGUAGE LambdaCase #-}
module
Main
where
import Prelude hiding (id, (.))
import Control.Applicative
import Control.Category
import Control.Arrow
import Graphics.Gloss
import qualified Graphics.Gloss.Interface.IO.Game as G
import Control.Wire
import Buttons
import GlossInterface
-- Utility
accumHold ::
(Monoid e, Monad m) =>
a -> Wire s e m (Event (a->a)) a
accumHold x = (hold <|> pure x) . accumE (flip ($)) x
-- Main body
mainWire ::
Wire (Timed Float ()) () IO (Event G.Event) Picture
mainWire = proc e ->
do
click0 <- filterE ((Just Click ==) . filter0) -< e
click5 <- filterE ((Just Click ==) . filter5) -< e
click10 <- filterE ((Just Click ==) . filter10) -< e
toggle0 <- filterE ((Just Toggle ==) . filter0) -< e
toggle5 <- filterE ((Just Toggle ==) . filter5) -< e
toggle10 <- filterE ((Just Toggle ==) . filter10) -< e
mode0 <- accumHold True -< not <$ toggle0
mode5 <- accumHold True -< not <$ toggle5
mode10 <- accumHold True -< not <$ toggle10
-- Part 1: static version
count0 <- accumHold 0 -< mergeL ((+1) <$ click0) (const 0 <$ toggle0)
count5 <- accumHold 0 -< (if mode5 then (+1) else id) <$ click5
count10 <- accumHold 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 mode0 then counter else arr $ const (-1)
dynamic0 <- rSwitch counter -< (click0, newCounter0 <$ toggle0)
-- `modes` can switch multiple state with inactive one suspended.
-- There's another solution using `kSwitch`. See Yampa-example.
dynamic5 <-
modes True (\case {True -> counter; False -> pure (-1)})
-< (click5, mode5 <$ toggle5)
-- <|> operator is suitable for scenario 10.
dynamic10 <-
pure (-1) . unless fst <|> counter . arr snd
-< (mode10, click10)
returnA -<
renderButtons
show0 (Just dynamic0)
show5 (Just dynamic5)
show10 (Just dynamic10)
where
counter = proc e -> accumHold 0 -< (+1) <$ e
main :: IO ()
main =
do
playNetwire
(InWindow "Netwire Example" (320, 240) (800, 200))
white
30
mainWire