{-# OPTIONS_HADDOCK hide #-}
{-# LANGUAGE NoImplicitPrelude #-}
module Imj.Graphics.Animation.Design.Render
( renderAnim
) where
import Imj.Prelude
import Control.Monad.IO.Class(MonadIO)
import Control.Monad.Reader.Class(MonadReader)
import Data.Either(partitionEithers)
import Imj.Geo.Discrete
import Imj.Graphics.Animation.Design.Types
import Imj.Graphics.Animation.Design.Color
import Imj.Graphics.Render
import Imj.Iteration
{-# INLINABLE renderAnim #-}
renderAnim :: (Draw e, MonadReader e m, MonadIO m)
=> Animation
-> Coords Pos
-> m ()
renderAnim (Animation points _ interaction (UpdateSpec _ (Iteration _ frameForNextUpdate)) mayChar) =
render' frameForNextUpdate mayChar points interaction
{-# INLINABLE render' #-}
render' :: (Draw e, MonadReader e m, MonadIO m)
=> Frame
-> Maybe Char
-> AnimatedPoints
-> (Coords Pos -> InteractionResult)
-> Coords Pos
-> m ()
render' _ _ (AnimatedPoints Nothing _ _) _ _ = return ()
render' _ _ (AnimatedPoints (Just []) _ _) _ _ = return ()
render'
parentFrame mayCharAnim (AnimatedPoints (Just branches) _ childFrame) interaction r = do
let (children, aliveCoordinates) = partitionEithers branches
selectRenderedCoordinates =
filter (\(AnimatedPoint canInteract coords _) ->
case canInteract of
DontInteract -> interaction coords == Stable
Interact -> True)
relFrame = parentFrame - childFrame
color = colorFromFrame relFrame
mapM_ (\(AnimatedPoint _ c mayChar) -> do
let char = fromMaybe (error "no char was specified") $ mayChar <|> mayCharAnim
drawChar char (sumCoords c r) color)
$ selectRenderedCoordinates aliveCoordinates
mapM_ (\child -> render' relFrame mayCharAnim child interaction r) children