{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE Strict #-}
{-# LANGUAGE TypeFamilies #-}
module Apecs.Util (
runGC, global,
EntityCounter(..), nextEntity, newEntity,
) where
import Control.Applicative (liftA2)
import Control.Monad.Reader
import Data.Monoid
import Data.Semigroup
import System.Mem (performMajorGC)
import Apecs.Core
import Apecs.Stores
import Apecs.System
global :: Entity
global = Entity (-1)
newtype EntityCounter = EntityCounter {getCounter :: Sum Int} deriving (Semigroup, Monoid, Eq, Show)
instance Component EntityCounter where
type Storage EntityCounter = ReadOnly (Global EntityCounter)
{-# INLINE nextEntity #-}
nextEntity :: (MonadIO m, Get w m EntityCounter) => SystemT w m Entity
nextEntity = do EntityCounter n <- get global
setReadOnly global (EntityCounter $ n+1)
return (Entity . getSum $ n)
{-# INLINE newEntity #-}
newEntity :: (MonadIO m, Set w m c, Get w m EntityCounter)
=> c -> SystemT w m Entity
newEntity c = do ety <- nextEntity
set ety c
return ety
runGC :: System w ()
runGC = lift performMajorGC