packages feed

mischief-ecs-0.1.0.0: src/Mischief/ECS/Interval.hs

module Mischief.ECS.Interval (start, stop, Interval) where

import Control.Concurrent (threadDelay)
import Control.Concurrent.Async (async)
import Control.Concurrent.STM
import Control.Monad
import Control.Monad.IO.Class
import Data.IORef
import Mischief.ECS.World

newtype Interval = Interval (IORef Bool)

start :: (MonadSystem w m) => Int -> System () -> m Interval
start t s = do
  world <- unsafeGetWorld
  i <- Interval <$> liftIO (newIORef False)
  _ <- liftIO $ async $ run world i t s
  return i

run :: World -> Interval -> Int -> System () -> IO ()
run world (Interval break) t s = do
  b <- liftIO $ readIORef break
  unless b $ do
    liftIO $ threadDelay t

    liftIO $ atomically $ modifyTVar' world.deferredAsync (++ [s])
    run world (Interval break) t s

stop :: (MonadSystem w m) => Interval -> m ()
stop (Interval break) = liftIO $ writeIORef break True