mischief-ecs-0.2.0.0: src/Mischief/ECS/Repeater.hs
module Mischief.ECS.Repeater (Repeater (..)) 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 GHC.Float (float2Int)
import Mischief.ECS.Components
import Mischief.ECS.Components.HooksDef
import Mischief.ECS.Hooks
import Mischief.ECS.World
import Mischief.ECS.World.Insert
import Mischief.ECS.World.Query
import Mischief.ECS.World.Query.Markers
data Repeater = Repeater Float (System ())
newtype RepeaterRef = RepeaterRef (IORef Bool) deriving anyclass (Component)
instance Component Repeater where
onAdd =
[ hook $ \(HookContext e) -> do
i <- liftIO (newIORef False)
Just (Repeater t s) <- single $ mkGet e (C @Repeater)
insert (RepeaterRef i) e
world <- unsafeGetWorld
void $ liftIO $ async $ run world i (float2Int $ 1000000 * t) s
]
onRemove =
[ hook $ \(HookContext e) -> do
break <- single $ mkGet e (C @RepeaterRef)
case break of
Nothing -> pure ()
Just (RepeaterRef break) -> liftIO $ writeIORef break False
]
run :: World -> IORef Bool -> Int -> System () -> IO ()
run world break t s = do
b <- liftIO $ readIORef break
unless b $ do
liftIO $ threadDelay t
liftIO $ atomically $ modifyTVar' world.deferredAsync (++ [s])
run world break t s