{-# OPTIONS_HADDOCK hide #-} {-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE LambdaCase #-} module Imj.Graphics.Animation.Design.Update ( shouldUpdate , updateAnimation , getDeadline ) where import Imj.Prelude import Data.Either(partitionEithers) import Imj.Graphics.Animation.Design.Types import Imj.Graphics.Animation.Design.Timing import Imj.Iteration import Imj.Timing {- | Returns 'True' if the 'KeyTime' is beyond the 'Animation' deadline or if the time difference is within 'animationUpdateMargin'. -} shouldUpdate :: Animation -> KeyTime -- ^ The current 'KeyTime' -> Bool shouldUpdate a (KeyTime k) = let (KeyTime k') = getDeadline a in diffSystemTime k' k < animationUpdateMargin updateAnimation :: Animation -- ^ The current animation -> Maybe Animation -- ^ The updated animation, or Nothing if the 'Animation' -- is over. updateAnimation (Animation points update interaction (UpdateSpec k it@(Iteration _ frame)) c) = let newPoints = update interaction frame points newUpdateSpec = UpdateSpec (addDuration animationPeriod k) (nextIteration it) newAnim = Animation newPoints update interaction newUpdateSpec c in case isActive newAnim of True -> Just newAnim False -> Nothing isActive :: Animation -> Bool isActive (Animation points _ _ _ _) = hasActivePoints points hasActivePoints :: AnimatedPoints -> Bool hasActivePoints (AnimatedPoints Nothing _ _) = False hasActivePoints (AnimatedPoints (Just []) _ _) = False hasActivePoints (AnimatedPoints (Just branches) _ _) = let (children, activeCoordinates) = partitionEithers branches childrenActive = map hasActivePoints children in (not . null) activeCoordinates || or childrenActive -- | Returns the time at which an 'Animation' should be updated. getDeadline :: Animation -> KeyTime getDeadline (Animation _ _ _ (UpdateSpec k _) _) = k