1 {-# LANGUAGE Arrows, FlexibleContexts #-}
3 module RMCA.Layer.Board ( boardSF
7 import Control.Concurrent
8 import Control.Concurrent.MVar
9 import Data.ReactiveValue
13 import RMCA.Auxiliary.Curry
14 import RMCA.Layer.Layer
16 import RMCA.Global.Clock
21 -- The state of the board is described by the list of the playheads
22 -- and the different actions onto the board.
23 boardAction :: [PlayHead]
24 -> SF ((Board, Layer), Event BeatNo) (Event ([PlayHead], [Note]))
25 boardAction ph = proc ((board, Layer { relPitch = rp
29 e <- arr $ fmap (uncurry5 $ advanceHeads)
30 -< ebno `tag` (board, fromEvent ebno, rp, s, ph)
31 returnA -< traceShow e e
33 boardSF :: SF (Board, Layer, Tempo) (Event [Note])
34 boardSF = proc (board, l, t) -> do
35 ebno <- layerMetronome -< (t, l)
36 iph <- startHeads -< board
37 boardSF' iph -< (board, l, ebno)
38 where boardSF' :: [PlayHead] -> SF (Board, Layer, Event BeatNo) (Event [Note])
39 boardSF' ph = switch (swap ^<< splitE ^<< boardAction ph)
43 -- We need the list of initial playheads
44 boardSF :: [PlayHead] -> SF (Board, Layer, Tempo) (Event [Note])
45 boardSF iph = proc (board, l@Layer { relPitch = rp
48 ebno <- layerMetronome -< (t,l)
49 --iph <- arr startHeads -< board
50 boardSF' iph -< ((board, l), ebno)
52 boardSF' :: [PlayHead] -> SF ((Board, Layer), Event BeatNo) (Event [Note])
53 boardSF' ph = switch (boardAction ph >>> arr splitE >>> arr swap)
54 (\nph -> second notYet >>> boardSF' nph)
59 -> ReactiveFieldReadWrite IO Tempo
60 -> ReactiveFieldReadWrite IO Layer
61 -> ReactiveFieldReadWrite IO [Note]
63 boardSetup board tempoRV layerRV outBoardRV = do
64 layer <- reactiveValueRead layerRV
65 tempo <- reactiveValueRead tempoRV
66 (inBoard, outBoard) <- yampaReactiveDual (layer, tempo) (boardSF board)
67 let inRV = pairRW layerRV tempoRV
71 reactiveValueOnCanRead outBoard
72 (reactiveValueRead outBoard >>= reactiveValueWrite outBoardRV . event [] id)
73 putStrLn "Board started."
78 (^:>) :: (ReactiveValueRead a b m, ReactiveValueReadWrite c d m) =>
80 not ^:> rv = reactiveValueOnCanRead not resync
81 where resync = reactiveValueRead rv >>= reactiveValueWrite rv