-------------------------------------------------------------------------------- {-# 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