patat-0.12.0.0: lib/Patat/Transition.hs
--------------------------------------------------------------------------------
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-}
module Patat.Transition
( Duration (..)
, threadDelayDuration
, TransitionGen
, TransitionId
, TransitionInstance (..)
, parseTransitionSettings
, newTransition
, stepTransition
) where
--------------------------------------------------------------------------------
import qualified Data.Aeson.Extended as A
import qualified Data.Aeson.TH.Extended as A
import Data.Bifunctor (first)
import qualified Data.HashMap.Strict as HMS
import Data.List.NonEmpty (NonEmpty (..))
import qualified Data.List.NonEmpty as NonEmpty
import Data.Text (Text)
import qualified Data.Text as T
import Data.Traversable (for)
import Patat.Presentation.Settings (TransitionSettings (..))
import qualified Patat.Transition.Dissolve as Dissolve
import Patat.Transition.Internal
import qualified Patat.Transition.Matrix as Matrix
import qualified Patat.Transition.SlideLeft as SlideLeft
import System.Random (uniformR)
--------------------------------------------------------------------------------
data RandomTransitionSettings = RandomTransitionSettings
{ rtsItems :: Maybe (NonEmpty TransitionSettings)
}
--------------------------------------------------------------------------------
$(A.deriveFromJSON A.dropPrefixOptions ''RandomTransitionSettings)
--------------------------------------------------------------------------------
random :: NonEmpty TransitionGen -> TransitionGen
random items size matrix0 matrix1 rg0 =
let (idx, rg1) = uniformR (0, length items - 1) rg0 in
(items NonEmpty.!! idx) size matrix0 matrix1 rg1
--------------------------------------------------------------------------------
transitions :: NonEmpty (Text, Transition)
transitions =
("dissolve", Transition Dissolve.transition) :|
("matrix", Transition Matrix.transition) :
("slideLeft", Transition SlideLeft.transition) : []
--------------------------------------------------------------------------------
transitionTable :: HMS.HashMap Text Transition
transitionTable = foldMap (uncurry HMS.singleton) transitions
--------------------------------------------------------------------------------
parseTransitionSettings
:: TransitionSettings -> Either String TransitionGen
parseTransitionSettings ts
-- Random is treated specially here.
| ty == "random" = fmap random $ do
settings <- A.resultToEither . A.fromJSON . A.Object $ tsParams ts
case rtsItems settings of
-- Items specified: parse those
Just items -> traverse parseTransitionSettings items
-- No items specified: parse default transition settings.
Nothing -> for transitions $ \(typ, _) -> parseTransitionSettings
TransitionSettings {tsType = typ, tsParams = mempty}
-- Found the transition type.
| Just (Transition f) <- HMS.lookup ty transitionTable =
fmap (f $) . first (\err ->
"could not parse " ++ T.unpack ty ++ " transition: " ++ err) .
A.resultToEither . A.fromJSON . A.Object $ tsParams ts
-- Not found, error.
| otherwise = Left $ "unknown transition type: " ++ show ty
where
ty = tsType ts