{-# LANGUAGE ApplicativeDo #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE RankNTypes #-}
module Reanimate.Scene.Sprite where
import Control.Monad (void)
import Control.Monad.ST (ST)
import Data.Bifunctor (Bifunctor (first))
import Data.STRef (STRef, modifySTRef, newSTRef, readSTRef)
import Graphics.SvgTree (pattern None)
import Reanimate.Animation (Animation, Duration, SVG, Sync (SyncStretch), Time, dropA,
duration, getAnimationFrame)
import Reanimate.Effect (Effect, delayE)
import Reanimate.Scene.Core (Scene (M), ZIndex, addGen, fork, liftST, queryNow, scene,
wait)
import Reanimate.Scene.Var (Var (..), newVar, readVar, unpackVar)
import Reanimate.Transition (Transition, overlapT)
simpleVar :: (a -> SVG) -> a -> Scene s (Var s a)
simpleVar :: (a -> SVG) -> a -> Scene s (Var s a)
simpleVar a -> SVG
render a
def = do
Var s a
v <- a -> Scene s (Var s a)
forall a s. a -> Scene s (Var s a)
newVar a
def
Sprite s
_ <- Frame s SVG -> Scene s (Sprite s)
forall s. Frame s SVG -> Scene s (Sprite s)
newSprite (Frame s SVG -> Scene s (Sprite s))
-> Frame s SVG -> Scene s (Sprite s)
forall a b. (a -> b) -> a -> b
$ a -> SVG
render (a -> SVG) -> Frame s a -> Frame s SVG
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Var s a -> Frame s a
forall s a. Var s a -> Frame s a
unVar Var s a
v
return Var s a
v
findVar :: (a -> Bool) -> [Var s a] -> Scene s (Var s a)
findVar :: (a -> Bool) -> [Var s a] -> Scene s (Var s a)
findVar a -> Bool
_cond [] = [Char] -> Scene s (Var s a)
forall a. HasCallStack => [Char] -> a
error [Char]
"Variable not found."
findVar a -> Bool
cond (Var s a
v : [Var s a]
vs) = do
a
val <- Var s a -> Scene s a
forall s a. Var s a -> Scene s a
readVar Var s a
v
if a -> Bool
cond a
val then Var s a -> Scene s (Var s a)
forall (m :: * -> *) a. Monad m => a -> m a
return Var s a
v else (a -> Bool) -> [Var s a] -> Scene s (Var s a)
forall a s. (a -> Bool) -> [Var s a] -> Scene s (Var s a)
findVar a -> Bool
cond [Var s a]
vs
play :: Animation -> Scene s ()
play :: Animation -> Scene s ()
play Animation
ani = Animation -> Scene s (Sprite s)
forall s. Animation -> Scene s (Sprite s)
newSpriteA Animation
ani Scene s (Sprite s) -> (Sprite s -> Scene s ()) -> Scene s ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Sprite s -> Scene s ()
forall s. Sprite s -> Scene s ()
destroySprite
data Sprite s = Sprite Time (STRef s (Duration, ST s (Duration -> Time -> SVG -> (SVG, ZIndex))))
newtype Frame s a = Frame {Frame s a -> ST s (Time -> Time -> Time -> a)
unFrame :: ST s (Time -> Duration -> Time -> a)}
instance Functor (Frame s) where
fmap :: (a -> b) -> Frame s a -> Frame s b
fmap a -> b
fn (Frame ST s (Time -> Time -> Time -> a)
gen) = ST s (Time -> Time -> Time -> b) -> Frame s b
forall s a. ST s (Time -> Time -> Time -> a) -> Frame s a
Frame (ST s (Time -> Time -> Time -> b) -> Frame s b)
-> ST s (Time -> Time -> Time -> b) -> Frame s b
forall a b. (a -> b) -> a -> b
$ do
Time -> Time -> Time -> a
m <- ST s (Time -> Time -> Time -> a)
gen
return (\Time
real_t Time
d Time
t -> a -> b
fn (a -> b) -> a -> b
forall a b. (a -> b) -> a -> b
$ Time -> Time -> Time -> a
m Time
real_t Time
d Time
t)
instance Applicative (Frame s) where
pure :: a -> Frame s a
pure a
v = ST s (Time -> Time -> Time -> a) -> Frame s a
forall s a. ST s (Time -> Time -> Time -> a) -> Frame s a
Frame (ST s (Time -> Time -> Time -> a) -> Frame s a)
-> ST s (Time -> Time -> Time -> a) -> Frame s a
forall a b. (a -> b) -> a -> b
$ (Time -> Time -> Time -> a) -> ST s (Time -> Time -> Time -> a)
forall (m :: * -> *) a. Monad m => a -> m a
return (\Time
_ Time
_ Time
_ -> a
v)
Frame ST s (Time -> Time -> Time -> a -> b)
f <*> :: Frame s (a -> b) -> Frame s a -> Frame s b
<*> Frame ST s (Time -> Time -> Time -> a)
g = ST s (Time -> Time -> Time -> b) -> Frame s b
forall s a. ST s (Time -> Time -> Time -> a) -> Frame s a
Frame (ST s (Time -> Time -> Time -> b) -> Frame s b)
-> ST s (Time -> Time -> Time -> b) -> Frame s b
forall a b. (a -> b) -> a -> b
$ do
Time -> Time -> Time -> a -> b
m1 <- ST s (Time -> Time -> Time -> a -> b)
f
Time -> Time -> Time -> a
m2 <- ST s (Time -> Time -> Time -> a)
g
return $ \Time
real_t Time
d Time
t -> Time -> Time -> Time -> a -> b
m1 Time
real_t Time
d Time
t (Time -> Time -> Time -> a
m2 Time
real_t Time
d Time
t)
unVar :: Var s a -> Frame s a
unVar :: Var s a -> Frame s a
unVar Var s a
var = ST s (Time -> Time -> Time -> a) -> Frame s a
forall s a. ST s (Time -> Time -> Time -> a) -> Frame s a
Frame (ST s (Time -> Time -> Time -> a) -> Frame s a)
-> ST s (Time -> Time -> Time -> a) -> Frame s a
forall a b. (a -> b) -> a -> b
$ do
Time -> a
fn <- Var s a -> ST s (Time -> a)
forall s a. Var s a -> ST s (Time -> a)
unpackVar Var s a
var
return $ \Time
real_t Time
_d Time
_t -> Time -> a
fn Time
real_t
spriteT :: Frame s Time
spriteT :: Frame s Time
spriteT = ST s (Time -> Time -> Time -> Time) -> Frame s Time
forall s a. ST s (Time -> Time -> Time -> a) -> Frame s a
Frame (ST s (Time -> Time -> Time -> Time) -> Frame s Time)
-> ST s (Time -> Time -> Time -> Time) -> Frame s Time
forall a b. (a -> b) -> a -> b
$ (Time -> Time -> Time -> Time)
-> ST s (Time -> Time -> Time -> Time)
forall (m :: * -> *) a. Monad m => a -> m a
return (\Time
_real_t Time
_d Time
t -> Time
t)
spriteDuration :: Frame s Duration
spriteDuration :: Frame s Time
spriteDuration = ST s (Time -> Time -> Time -> Time) -> Frame s Time
forall s a. ST s (Time -> Time -> Time -> a) -> Frame s a
Frame (ST s (Time -> Time -> Time -> Time) -> Frame s Time)
-> ST s (Time -> Time -> Time -> Time) -> Frame s Time
forall a b. (a -> b) -> a -> b
$ (Time -> Time -> Time -> Time)
-> ST s (Time -> Time -> Time -> Time)
forall (m :: * -> *) a. Monad m => a -> m a
return (\Time
_real_t Time
d Time
_t -> Time
d)
newSprite :: Frame s SVG -> Scene s (Sprite s)
newSprite :: Frame s SVG -> Scene s (Sprite s)
newSprite Frame s SVG
render = do
Time
now <- Scene s Time
forall s. Scene s Time
queryNow
STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref <- ST s (STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> Scene
s (STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
forall s a. ST s a -> Scene s a
liftST (ST s (STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> Scene
s (STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))))
-> ST
s (STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> Scene
s (STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
forall a b. (a -> b) -> a -> b
$ (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> ST
s (STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
forall a s. a -> ST s (STRef s a)
newSTRef (-Time
1, (Time -> Time -> SVG -> (SVG, ZIndex))
-> ST s (Time -> Time -> SVG -> (SVG, ZIndex))
forall (m :: * -> *) a. Monad m => a -> m a
return ((Time -> Time -> SVG -> (SVG, ZIndex))
-> ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time -> Time -> SVG -> (SVG, ZIndex))
-> ST s (Time -> Time -> SVG -> (SVG, ZIndex))
forall a b. (a -> b) -> a -> b
$ \Time
_d Time
_t SVG
svg -> (SVG
svg, ZIndex
0))
Gen s -> Scene s ()
forall s. Gen s -> Scene s ()
addGen (Gen s -> Scene s ()) -> Gen s -> Scene s ()
forall a b. (a -> b) -> a -> b
$ do
Time -> Time -> Time -> SVG
fn <- Frame s SVG -> ST s (Time -> Time -> Time -> SVG)
forall s a. Frame s a -> ST s (Time -> Time -> Time -> a)
unFrame Frame s SVG
render
(Time
spriteDur, ST s (Time -> Time -> SVG -> (SVG, ZIndex))
spriteEffectGen) <- STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> ST s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
forall s a. STRef s a -> ST s a
readSTRef STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref
Time -> Time -> SVG -> (SVG, ZIndex)
spriteEffect <- ST s (Time -> Time -> SVG -> (SVG, ZIndex))
spriteEffectGen
return $ \Time
d Time
absT ->
let relD :: Time
relD = (if Time
spriteDur Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
< Time
0 then Time
d else Time
spriteDur) Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
now
relT :: Time
relT = Time
absT Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
now
inTimeSlice :: Bool
inTimeSlice = Time
relT Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
>= Time
0 Bool -> Bool -> Bool
&& Time
relT Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
< Time
relD
isLastFrame :: Bool
isLastFrame = Time
d Time -> Time -> Bool
forall a. Eq a => a -> a -> Bool
== Time
absT Bool -> Bool -> Bool
&& Time
relT Time -> Time -> Bool
forall a. Eq a => a -> a -> Bool
== Time
relD
in if Bool
inTimeSlice Bool -> Bool -> Bool
|| Bool
isLastFrame
then Time -> Time -> SVG -> (SVG, ZIndex)
spriteEffect Time
relD Time
relT (Time -> Time -> Time -> SVG
fn Time
absT Time
relD Time
relT)
else (SVG
None, ZIndex
0)
return $ Time
-> STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> Sprite s
forall s.
Time
-> STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> Sprite s
Sprite Time
now STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref
newSprite_ :: Frame s SVG -> Scene s ()
newSprite_ :: Frame s SVG -> Scene s ()
newSprite_ = Scene s (Sprite s) -> Scene s ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Scene s (Sprite s) -> Scene s ())
-> (Frame s SVG -> Scene s (Sprite s)) -> Frame s SVG -> Scene s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Frame s SVG -> Scene s (Sprite s)
forall s. Frame s SVG -> Scene s (Sprite s)
newSprite
newSpriteA :: Animation -> Scene s (Sprite s)
newSpriteA :: Animation -> Scene s (Sprite s)
newSpriteA = Sync -> Animation -> Scene s (Sprite s)
forall s. Sync -> Animation -> Scene s (Sprite s)
newSpriteA' Sync
SyncStretch
newSpriteA' :: Sync -> Animation -> Scene s (Sprite s)
newSpriteA' :: Sync -> Animation -> Scene s (Sprite s)
newSpriteA' Sync
sync Animation
animation =
Frame s SVG -> Scene s (Sprite s)
forall s. Frame s SVG -> Scene s (Sprite s)
newSprite (Sync -> Animation -> Time -> Time -> SVG
getAnimationFrame Sync
sync Animation
animation (Time -> Time -> SVG) -> Frame s Time -> Frame s (Time -> SVG)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Frame s Time
forall s. Frame s Time
spriteT Frame s (Time -> SVG) -> Frame s Time -> Frame s SVG
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Frame s Time
forall s. Frame s Time
spriteDuration)
Scene s (Sprite s) -> Scene s () -> Scene s (Sprite s)
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Time -> Scene s ()
forall s. Time -> Scene s ()
wait (Animation -> Time
duration Animation
animation)
newSpriteSVG :: SVG -> Scene s (Sprite s)
newSpriteSVG :: SVG -> Scene s (Sprite s)
newSpriteSVG = Frame s SVG -> Scene s (Sprite s)
forall s. Frame s SVG -> Scene s (Sprite s)
newSprite (Frame s SVG -> Scene s (Sprite s))
-> (SVG -> Frame s SVG) -> SVG -> Scene s (Sprite s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SVG -> Frame s SVG
forall (f :: * -> *) a. Applicative f => a -> f a
pure
newSpriteSVG_ :: SVG -> Scene s ()
newSpriteSVG_ :: SVG -> Scene s ()
newSpriteSVG_ = Scene s (Sprite s) -> Scene s ()
forall (f :: * -> *) a. Functor f => f a -> f ()
void (Scene s (Sprite s) -> Scene s ())
-> (SVG -> Scene s (Sprite s)) -> SVG -> Scene s ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SVG -> Scene s (Sprite s)
forall s. SVG -> Scene s (Sprite s)
newSpriteSVG
applyVar :: Var s a -> Sprite s -> (a -> SVG -> SVG) -> Scene s ()
applyVar :: Var s a -> Sprite s -> (a -> SVG -> SVG) -> Scene s ()
applyVar Var s a
var Sprite s
sprite a -> SVG -> SVG
fn = Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
forall s.
Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
spriteModify Sprite s
sprite (Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ())
-> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
forall a b. (a -> b) -> a -> b
$ do
a
varFn <- Var s a -> Frame s a
forall s a. Var s a -> Frame s a
unVar Var s a
var
return $ (SVG -> SVG) -> (SVG, ZIndex) -> (SVG, ZIndex)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ((SVG -> SVG) -> (SVG, ZIndex) -> (SVG, ZIndex))
-> (SVG -> SVG) -> (SVG, ZIndex) -> (SVG, ZIndex)
forall a b. (a -> b) -> a -> b
$ a -> SVG -> SVG
fn a
varFn
destroySprite :: Sprite s -> Scene s ()
destroySprite :: Sprite s -> Scene s ()
destroySprite (Sprite Time
_ STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref) = do
Time
now <- Scene s Time
forall s. Scene s Time
queryNow
ST s () -> Scene s ()
forall s a. ST s a -> Scene s a
liftST (ST s () -> Scene s ()) -> ST s () -> Scene s ()
forall a b. (a -> b) -> a -> b
$
STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> ((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref (((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ())
-> ((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ()
forall a b. (a -> b) -> a -> b
$ \(Time
ttl, ST s (Time -> Time -> SVG -> (SVG, ZIndex))
render) ->
(if Time
ttl Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
< Time
0 then Time
now else Time -> Time -> Time
forall a. Ord a => a -> a -> a
min Time
ttl Time
now, ST s (Time -> Time -> SVG -> (SVG, ZIndex))
render)
spriteModify :: Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
spriteModify :: Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
spriteModify (Sprite Time
born STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref) Frame s ((SVG, ZIndex) -> (SVG, ZIndex))
modFn = ST s () -> Scene s ()
forall s a. ST s a -> Scene s a
liftST (ST s () -> Scene s ()) -> ST s () -> Scene s ()
forall a b. (a -> b) -> a -> b
$
STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> ((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref (((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ())
-> ((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ()
forall a b. (a -> b) -> a -> b
$ \(Time
ttl, ST s (Time -> Time -> SVG -> (SVG, ZIndex))
renderGen) ->
( Time
ttl,
do
Time -> Time -> SVG -> (SVG, ZIndex)
render <- ST s (Time -> Time -> SVG -> (SVG, ZIndex))
renderGen
Time -> Time -> Time -> (SVG, ZIndex) -> (SVG, ZIndex)
modRender <- Frame s ((SVG, ZIndex) -> (SVG, ZIndex))
-> ST s (Time -> Time -> Time -> (SVG, ZIndex) -> (SVG, ZIndex))
forall s a. Frame s a -> ST s (Time -> Time -> Time -> a)
unFrame Frame s ((SVG, ZIndex) -> (SVG, ZIndex))
modFn
return $ \Time
relD Time
relT ->
let absT :: Time
absT = Time
relT Time -> Time -> Time
forall a. Num a => a -> a -> a
+ Time
born in Time -> Time -> Time -> (SVG, ZIndex) -> (SVG, ZIndex)
modRender Time
absT Time
relD Time
relT ((SVG, ZIndex) -> (SVG, ZIndex))
-> (SVG -> (SVG, ZIndex)) -> SVG -> (SVG, ZIndex)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Time -> Time -> SVG -> (SVG, ZIndex)
render Time
relD Time
relT
)
spriteMap :: Sprite s -> (SVG -> SVG) -> Scene s ()
spriteMap :: Sprite s -> (SVG -> SVG) -> Scene s ()
spriteMap sprite :: Sprite s
sprite@(Sprite Time
born STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
_) SVG -> SVG
fn = do
Time
now <- Scene s Time
forall s. Scene s Time
queryNow
let tDelta :: Time
tDelta = Time
now Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
born
Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
forall s.
Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
spriteModify Sprite s
sprite (Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ())
-> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
forall a b. (a -> b) -> a -> b
$ do
Time
t <- Frame s Time
forall s. Frame s Time
spriteT
return $ \(SVG
svg, ZIndex
zindex) -> (if (Time
t Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
tDelta) Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
< Time
0 then SVG
svg else SVG -> SVG
fn SVG
svg, ZIndex
zindex)
spriteTween :: Sprite s -> Duration -> (Double -> SVG -> SVG) -> Scene s ()
spriteTween :: Sprite s -> Time -> (Time -> SVG -> SVG) -> Scene s ()
spriteTween sprite :: Sprite s
sprite@(Sprite Time
born STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
_) Time
dur Time -> SVG -> SVG
fn = do
Time
now <- Scene s Time
forall s. Scene s Time
queryNow
let tDelta :: Time
tDelta = Time
now Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
born
Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
forall s.
Sprite s -> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
spriteModify Sprite s
sprite (Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ())
-> Frame s ((SVG, ZIndex) -> (SVG, ZIndex)) -> Scene s ()
forall a b. (a -> b) -> a -> b
$ do
Time
t <- Frame s Time
forall s. Frame s Time
spriteT
return $ (SVG -> SVG) -> (SVG, ZIndex) -> (SVG, ZIndex)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first ((SVG -> SVG) -> (SVG, ZIndex) -> (SVG, ZIndex))
-> (SVG -> SVG) -> (SVG, ZIndex) -> (SVG, ZIndex)
forall a b. (a -> b) -> a -> b
$ \SVG
svg -> Time -> SVG -> SVG
fn (Time -> Time -> Time -> Time
forall a. Ord a => a -> a -> a -> a
clamp Time
0 Time
1 (Time -> Time) -> Time -> Time
forall a b. (a -> b) -> a -> b
$ (Time
t Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
tDelta) Time -> Time -> Time
forall a. Fractional a => a -> a -> a
/ Time
dur) SVG
svg
Time -> Scene s ()
forall s. Time -> Scene s ()
wait Time
dur
where
clamp :: a -> a -> a -> a
clamp a
a a
b a
v
| a
v a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
a = a
a
| a
v a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> a
b = a
b
| Bool
otherwise = a
v
spriteVar :: Sprite s -> a -> (a -> SVG -> SVG) -> Scene s (Var s a)
spriteVar :: Sprite s -> a -> (a -> SVG -> SVG) -> Scene s (Var s a)
spriteVar Sprite s
sprite a
def a -> SVG -> SVG
fn = do
Var s a
v <- a -> Scene s (Var s a)
forall a s. a -> Scene s (Var s a)
newVar a
def
Var s a -> Sprite s -> (a -> SVG -> SVG) -> Scene s ()
forall s a. Var s a -> Sprite s -> (a -> SVG -> SVG) -> Scene s ()
applyVar Var s a
v Sprite s
sprite a -> SVG -> SVG
fn
return Var s a
v
spriteE :: Sprite s -> Effect -> Scene s ()
spriteE :: Sprite s -> Effect -> Scene s ()
spriteE (Sprite Time
born STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref) Effect
effect = do
Time
now <- Scene s Time
forall s. Scene s Time
queryNow
ST s () -> Scene s ()
forall s a. ST s a -> Scene s a
liftST (ST s () -> Scene s ()) -> ST s () -> Scene s ()
forall a b. (a -> b) -> a -> b
$
STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> ((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref (((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ())
-> ((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ()
forall a b. (a -> b) -> a -> b
$ \(Time
ttl, ST s (Time -> Time -> SVG -> (SVG, ZIndex))
renderGen) ->
( Time
ttl,
do
Time -> Time -> SVG -> (SVG, ZIndex)
render <- ST s (Time -> Time -> SVG -> (SVG, ZIndex))
renderGen
return $ \Time
d Time
t SVG
svg ->
let (SVG
svg', ZIndex
z) = Time -> Time -> SVG -> (SVG, ZIndex)
render Time
d Time
t SVG
svg
in (Time -> Effect -> Effect
delayE (Time -> Time -> Time
forall a. Ord a => a -> a -> a
max Time
0 (Time -> Time) -> Time -> Time
forall a b. (a -> b) -> a -> b
$ Time
now Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
born) Effect
effect Time
d Time
t SVG
svg', ZIndex
z)
)
spriteZ :: Sprite s -> ZIndex -> Scene s ()
spriteZ :: Sprite s -> ZIndex -> Scene s ()
spriteZ (Sprite Time
born STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref) ZIndex
zindex = do
Time
now <- Scene s Time
forall s. Scene s Time
queryNow
ST s () -> Scene s ()
forall s a. ST s a -> Scene s a
liftST (ST s () -> Scene s ()) -> ST s () -> Scene s ()
forall a b. (a -> b) -> a -> b
$
STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> ((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ()
forall s a. STRef s a -> (a -> a) -> ST s ()
modifySTRef STRef s (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
ref (((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ())
-> ((Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex)))
-> (Time, ST s (Time -> Time -> SVG -> (SVG, ZIndex))))
-> ST s ()
forall a b. (a -> b) -> a -> b
$ \(Time
ttl, ST s (Time -> Time -> SVG -> (SVG, ZIndex))
renderGen) ->
( Time
ttl,
do
Time -> Time -> SVG -> (SVG, ZIndex)
render <- ST s (Time -> Time -> SVG -> (SVG, ZIndex))
renderGen
return $ \Time
d Time
t SVG
svg ->
let (SVG
svg', ZIndex
z) = Time -> Time -> SVG -> (SVG, ZIndex)
render Time
d Time
t SVG
svg in (SVG
svg', if Time
t Time -> Time -> Bool
forall a. Ord a => a -> a -> Bool
< Time
now Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
born then ZIndex
z else ZIndex
zindex)
)
spriteScope :: Scene s a -> Scene s a
spriteScope :: Scene s a -> Scene s a
spriteScope (M Time -> ST s (a, Time, Time, [Gen s])
action) = (Time -> ST s (a, Time, Time, [Gen s])) -> Scene s a
forall s a. (Time -> ST s (a, Time, Time, [Gen s])) -> Scene s a
M ((Time -> ST s (a, Time, Time, [Gen s])) -> Scene s a)
-> (Time -> ST s (a, Time, Time, [Gen s])) -> Scene s a
forall a b. (a -> b) -> a -> b
$ \Time
t -> do
(a
a, Time
s, Time
p, [Gen s]
gens) <- Time -> ST s (a, Time, Time, [Gen s])
action Time
t
(a, Time, Time, [Gen s]) -> ST s (a, Time, Time, [Gen s])
forall (m :: * -> *) a. Monad m => a -> m a
return (a
a, Time
s, Time
p, (Gen s -> Gen s) -> [Gen s] -> [Gen s]
forall a b. (a -> b) -> [a] -> [b]
map (Time -> Gen s -> Gen s
forall (f :: * -> *) t b p.
(Functor f, Ord t, Num b) =>
t -> f (t -> t -> (SVG, b)) -> f (p -> t -> (SVG, b))
genFn (Time
t Time -> Time -> Time
forall a. Num a => a -> a -> a
+ Time -> Time -> Time
forall a. Ord a => a -> a -> a
max Time
s Time
p)) [Gen s]
gens)
where
genFn :: t -> f (t -> t -> (SVG, b)) -> f (p -> t -> (SVG, b))
genFn t
maxT f (t -> t -> (SVG, b))
gen = do
t -> t -> (SVG, b)
frameGen <- f (t -> t -> (SVG, b))
gen
return $ \p
_ t
t ->
if t
t t -> t -> Bool
forall a. Ord a => a -> a -> Bool
< t
maxT
then t -> t -> (SVG, b)
frameGen t
maxT t
t
else (SVG
None, b
0)
asAnimation :: (forall s'. Scene s' a) -> Scene s Animation
asAnimation :: (forall s'. Scene s' a) -> Scene s Animation
asAnimation forall s'. Scene s' a
s = do
Time
now <- Scene s Time
forall s. Scene s Time
queryNow
return $ Time -> Animation -> Animation
dropA Time
now ((forall s'. Scene s' a) -> Animation
forall a. (forall s. Scene s a) -> Animation
scene (Time -> Scene s ()
forall s. Time -> Scene s ()
wait Time
now Scene s () -> Scene s a -> Scene s a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Scene s a
forall s'. Scene s' a
s))
transitionO :: Transition -> Double -> (forall s'. Scene s' a) -> (forall s'. Scene s' b) -> Scene s ()
transitionO :: Transition
-> Time
-> (forall s'. Scene s' a)
-> (forall s'. Scene s' b)
-> Scene s ()
transitionO Transition
t Time
o forall s'. Scene s' a
a forall s'. Scene s' b
b = do
Animation
aA <- (forall s'. Scene s' a) -> Scene s Animation
forall a s. (forall s'. Scene s' a) -> Scene s Animation
asAnimation forall s'. Scene s' a
a
Animation
bA <- Scene s Animation -> Scene s Animation
forall s a. Scene s a -> Scene s a
fork (Scene s Animation -> Scene s Animation)
-> Scene s Animation -> Scene s Animation
forall a b. (a -> b) -> a -> b
$ do
Time -> Scene s ()
forall s. Time -> Scene s ()
wait (Animation -> Time
duration Animation
aA Time -> Time -> Time
forall a. Num a => a -> a -> a
- Time
o)
(forall s'. Scene s' b) -> Scene s Animation
forall a s. (forall s'. Scene s' a) -> Scene s Animation
asAnimation forall s'. Scene s' b
b
Animation -> Scene s ()
forall s. Animation -> Scene s ()
play (Animation -> Scene s ()) -> Animation -> Scene s ()
forall a b. (a -> b) -> a -> b
$ Time -> Transition -> Transition
overlapT Time
o Transition
t Animation
aA Animation
bA