-
Notifications
You must be signed in to change notification settings - Fork 30
/
Main.hs
71 lines (61 loc) · 3.28 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
module Main where
import Graphics.Gloss
import qualified Graphics.Gloss.Interface.IO.Game as G
import Buttons
import Control.Varying
main :: IO ()
main = G.playIO (InWindow "Varying Example" (320, 240) (800, 200)) white 30
(renderButtons 0 (Just 0) 0 (Just 0) 0 (Just 0), network)
(return . fst) (\e (_, network') -> runVar network' e)
(const $ return)
network :: Monad m => Var m G.Event Picture
network =
renderButtons <$> negWhenUntoggled static0 (toggled filter0)
<*> (Just <$> negWhenUntoggled dyn0 (toggled filter0))
<*> negWhenUntoggled static5 (toggled filter5)
<*> (Just <$> negWhenUntoggled dyn5 (toggled filter5))
<*> negWhenUntoggled static10(toggled filter10)
<*> (Just <$> negWhenUntoggled dyn10 (toggled filter10))
-- | Simply produces "-1" if the second signal produces False, or the value
-- of the first signal.
negWhenUntoggled :: Monad m
=> Var m G.Event Int -> Var m G.Event Bool -> Var m G.Event Int
negWhenUntoggled count mode = (\n on -> if on then n else -1) <$> count <*> mode
--------------------------------------------------------------------------------
-- Static
--------------------------------------------------------------------------------
static0 :: Monad m => Var m G.Event Int
static0 = events ~> collectWith append ~> var (foldl (flip ($)) 0)
where append on xs = if on then (+1):xs else []
events = (<$) <$> toggled filter0 <*> clicked filter0
static5 :: Monad m => Var m G.Event Int
static5 = events ~> collectWith append ~> var (foldl (flip ($)) 0)
where append on xs = if on then (+1):xs else xs
events = (<$) <$> toggled filter5 <*> clicked filter5
static10 :: Monad m => Var m G.Event Int
static10 = clicked filter10 ~> accumulate (\n e -> if isEvent e then n+1 else n)
0
--------------------------------------------------------------------------------
-- Dynamic
--------------------------------------------------------------------------------
dyn0 :: Monad m => Var m G.Event Int
dyn0 = switchByMode (toggled filter0) $ \on -> if on then count else 0
where count = clicked filter0 ~> collect ~> var length
dyn5 :: Monad m => Var m G.Event Int
dyn5 = (count `onlyWhenE` toggledOn) ~> startingWith 0
where count = clicked filter5 ~> collect ~> var length
toggledOn = toggled filter5 ~> onTrue
dyn10 :: Monad m => Var m G.Event Int
dyn10 = count `orE` pass
where count = clicked filter10 ~> collect ~> var length
pass = toggled filter10 ~> onWhen not ~> var (0 <$)
--------------------------------------------------------------------------------
-- Helpers
--------------------------------------------------------------------------------
clicked :: Monad m => (G.Event -> Maybe ButtonClick) -> Var m G.Event (Event ())
clicked f = var ((== Just Click) . f) ~> onTrue
toggled :: Monad m => (G.Event -> Maybe ButtonClick) -> Var m G.Event Bool
toggled f = toggle f ~> accumulate (\on e -> if isEvent e then not on else on)
True
toggle :: Monad m => (G.Event -> Maybe ButtonClick) -> Var m G.Event (Event ())
toggle f = var ((== Just Toggle) . f) ~> onTrue