This repository has been archived by the owner on Mar 1, 2019. It is now read-only.
/
Renderer.purs
65 lines (54 loc) · 2.09 KB
/
Renderer.purs
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
module Cherry.Renderer
( Renderer
, createRenderer
, runRenderer
) where
import Prelude
import Cherry.Store (Store, select)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Control.Monad.Eff.Ref (REF, Ref, modifyRef, newRef, readRef, writeRef)
import DOM (DOM)
import DOM.HTML (window)
import DOM.HTML.Types (htmlDocumentToParentNode)
import DOM.HTML.Window (document, requestAnimationFrame)
import DOM.Node.ParentNode (QuerySelector(..), querySelector)
import DOM.Node.Types (Node, elementToNode)
import Data.List (List(..), (!!), (:))
import Data.Maybe (Maybe(..))
import VOM (VNode, patch)
newtype Renderer e s = Renderer
{ container :: Maybe Node
, view :: s -> VNode e
, historyRef :: Ref (List (VNode e))
, renderFlagRef :: Ref Boolean
}
createRenderer :: forall e s.
String ->
(s -> VNode (dom :: DOM, ref :: REF | e)) ->
Eff (dom :: DOM, ref :: REF | e) (Renderer (dom :: DOM, ref :: REF | e) s)
createRenderer selector view = do
doc <- htmlDocumentToParentNode <$> (window >>= document)
container <- map elementToNode <$> querySelector (QuerySelector selector) doc
historyRef <- newRef Nil
renderFlagRef <- newRef false
pure $ Renderer { container, view, historyRef, renderFlagRef }
runRenderer :: forall e s.
Store (console :: CONSOLE, dom :: DOM, ref :: REF | e) s ->
Renderer (console :: CONSOLE, dom :: DOM, ref :: REF | e) s ->
Eff (console :: CONSOLE, dom :: DOM, ref :: REF | e) Unit
runRenderer store (Renderer r) =
case r.container of
Nothing -> log "Container is not found"
Just t -> do
renderFlag <- readRef r.renderFlagRef
if renderFlag
then pure unit
else do
writeRef r.renderFlagRef true
void $ window >>= requestAnimationFrame do
writeRef r.renderFlagRef false
currentState <- select store (\s -> s)
modifyRef r.historyRef (\h -> (r.view currentState) : h)
history <- readRef r.historyRef
patch (history !! 1) (history !! 0) t