-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathMain.hs
93 lines (67 loc) · 2.84 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
module Main where
import Control.Applicative
import Control.Monad (join)
import Data.Monoid
import Control.FRPNow
import Graphics.Gloss.Interface.IO.Game hiding (Event)
import Control.FRPNow.Gloss
import Buttons
-- Utilities
if_then_else :: Bool -> a -> a -> a
if_then_else True t _ = t
if_then_else False _ f = f
replaceWith :: a -> EvStream b -> EvStream a
replaceWith = fmap . const
filterEq :: Eq a => a -> EvStream a -> EvStream ()
filterEq x = replaceWith () . filterEs (== x)
eachEs :: EvStream () -> a -> EvStream a
eachEs = flip replaceWith
-- FRP network
mainFRPNow :: Behavior Time
-> EvStream GEvent
-> Behavior (Behavior Picture)
mainFRPNow _ glossEvent = do
-- Part 1: static version
-- Input
let click0 = filterEq (Just Click) $ filter0 <$> glossEvent
let click5 = filterEq (Just Click) $ filter5 <$> glossEvent
let click10 = filterEq (Just Click) $ filter10 <$> glossEvent
let toggle0 = filterEq (Just Toggle) $ filter0 <$> glossEvent
let toggle5 = filterEq (Just Toggle) $ filter5 <$> glossEvent
let toggle10 = filterEq (Just Toggle) $ filter10 <$> glossEvent
-- Behavior
mode0 <- foldEs (\x _ -> not x) True toggle0
mode5 <- foldEs (\x _ -> not x) True toggle5
mode10 <- foldEs (\x _ -> not x) True toggle10
count0 <- foldEs (\x f -> f x) 0 $ eachEs toggle0 (const 0)
<> eachEs click0 (+1)
count5 <- foldEs (\x _ -> x + 1) 0 $ click5 `during` mode5
count10 <- foldEs (\x _ -> x + 1) 0 $ click10
-- Part 2: dynamic version
-- Scenario 0: generate new graphs and switch to the latest one.
let makeDynamicCounter0 = do
firstCounter <- newCounter
currentCounter <-
fromChanges firstCounter (newCounter `snapshots` resetRequest)
return $ join currentCounter
where
resetRequest :: EvStream ()
resetRequest = toggle0 `during` mode0
newCounter :: Behavior (Behavior Int)
newCounter = foldEs (\x _ -> x + 1) 0 click0
dynamicCount0 <- makeDynamicCounter0
-- Output
let minus1 = pure (-1)::Behavior Int
let output0 = if_then_else <$> mode0 <*> count0 <*> minus1
let output5 = if_then_else <$> mode5 <*> count5 <*> minus1
let output10 = if_then_else <$> mode10 <*> count10 <*> minus1
let dynamicOutput0 = if_then_else <$> mode0 <*> dynamicCount0 <*> minus1
return $ renderButtons <$> output0 <*> (Just <$> dynamicOutput0)
<*> output5 <*> pure Nothing
<*> output10 <*> pure Nothing
-- Gloss event loop
main :: IO ()
main = runNowGlossPure (InWindow "FRPNow Example" (320, 240) (800, 200))
white
30
mainFRPNow