module Mischief.ECS.Time where import Control.Monad.IO.Class import GHC.Records (HasField (getField)) import Mischief.ECS.App import Mischief.ECS.App.Plugins import Mischief.ECS.App.Schedules import Mischief.ECS.Components import Mischief.ECS.Resources import Mischief.ECS.Systems qualified as Systems import Mischief.ECS.Tables import Mischief.ECS.Utils import Mischief.ECS.World import Mischief.ECS.World.Insert import Mischief.ECS.World.Modify import Mischief.ECS.World.Query import Mischief.ECS.World.Query.Queryable import System.Clock data Time = Time { Time -> TimeSpec delta :: TimeSpec, Time -> TimeSpec elapsed :: TimeSpec } deriving (Int -> Time -> ShowS [Time] -> ShowS Time -> String (Int -> Time -> ShowS) -> (Time -> String) -> ([Time] -> ShowS) -> Show Time forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a $cshowsPrec :: Int -> Time -> ShowS showsPrec :: Int -> Time -> ShowS $cshow :: Time -> String show :: Time -> String $cshowList :: [Time] -> ShowS showList :: [Time] -> ShowS Show, Typeable Time Set DefaultComponentType Hooks Time IsExclusive (RelExclusivity Time) (Typeable Time, IsExclusive (RelExclusivity Time)) => Set DefaultComponentType -> Hooks Time -> Component Time forall c. (Typeable c, IsExclusive (RelExclusivity c)) => Set DefaultComponentType -> Hooks c -> Component c $crequired :: Set DefaultComponentType required :: Set DefaultComponentType $chooks :: Hooks Time hooks :: Hooks Time Component) time :: System Time time :: System Time time = Maybe Time -> Time forall a. HasCallStack => Maybe a -> a unwrap (Maybe Time -> Time) -> System (Maybe Time) -> System Time forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> forall c. QueryType c => System (Maybe c) res @Time deltaTime :: System Float deltaTime :: System Float deltaTime = Time -> Float deltaSecs (Time -> Float) -> System Time -> System Float forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> System Time time deltaSecs :: Time -> Float deltaSecs :: Time -> Float deltaSecs Time {TimeSpec delta :: Time -> TimeSpec delta :: TimeSpec delta} = Int64 -> Float forall a b. (Integral a, Num b) => a -> b fromIntegral TimeSpec delta.sec Float -> Float -> Float forall a. Num a => a -> a -> a + Int64 -> Float forall a b. (Integral a, Num b) => a -> b fromIntegral TimeSpec delta.nsec Float -> Float -> Float forall a. Fractional a => a -> a -> a / Float 1000000000 data TimePlugin = TimePlugin deriving (TimePlugin -> TimePlugin -> Bool (TimePlugin -> TimePlugin -> Bool) -> (TimePlugin -> TimePlugin -> Bool) -> Eq TimePlugin forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a $c== :: TimePlugin -> TimePlugin -> Bool == :: TimePlugin -> TimePlugin -> Bool $c/= :: TimePlugin -> TimePlugin -> Bool /= :: TimePlugin -> TimePlugin -> Bool Eq) instance Plugin TimePlugin where init :: TimePlugin -> System () init TimePlugin _ = do currentTime <- IO TimeSpec -> System TimeSpec forall a. IO a -> System a forall (m :: * -> *) a. MonadIO m => IO a -> m a liftIO (IO TimeSpec -> System TimeSpec) -> IO TimeSpec -> System TimeSpec forall a b. (a -> b) -> a -> b $ Clock -> IO TimeSpec getTime Clock Monotonic insertRes $ Time {delta = TimeSpec {sec = 0, nsec = 0}, elapsed = currentTime} Systems.add First updateTime updateTime :: System () updateTime :: System () updateTime = do Just time <- forall c. QueryType c => System (Maybe c) res @Time currentTime <- liftIO $ getTime Monotonic insertRes Time {delta = currentTime - time.elapsed, elapsed = currentTime}