module Aztecs.World.Entities where

import Aztecs.Entity
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Data.Word

data Entities = Entities
  { Entities -> Word32
entitiesNextGeneration :: Word32,
    Entities -> IntMap Word32
entitiesGenerations :: IntMap Word32,
    Entities -> Word32
entitiesNextIndex :: Word32,
    Entities -> [Word32]
entitiesFreeIndicies :: [Word32]
  }

emptyEntities :: Entities
emptyEntities :: Entities
emptyEntities = Word32 -> IntMap Word32 -> Word32 -> [Word32] -> Entities
Entities Word32
0 IntMap Word32
forall a. IntMap a
IntMap.empty Word32
0 []
{-# INLINE emptyEntities #-}

mkEntityWithCounter :: Entities -> (Entity, Entities)
mkEntityWithCounter :: Entities -> (Entity, Entities)
mkEntityWithCounter (Entities Word32
gen IntMap Word32
gens Word32
index [Word32]
free) =
  let (Word32
i, Word32
nextIndex, [Word32]
free') = case [Word32]
free of
        (Word32
i' : [Word32]
rest) -> (Word32
i', Word32
index, [Word32]
rest)
        [] -> (Word32
index, Word32
index Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1, [])
      nextGeneration :: Word32
nextGeneration = Word32
gen Word32 -> Word32 -> Word32
forall a. Num a => a -> a -> a
+ Word32
1
      gens' :: IntMap Word32
gens' = Key -> Word32 -> IntMap Word32 -> IntMap Word32
forall a. Key -> a -> IntMap a -> IntMap a
IntMap.insert (Word32 -> Key
forall a b. (Integral a, Num b) => a -> b
fromIntegral Word32
i) Word32
gen IntMap Word32
gens
   in (Word32 -> Word32 -> Entity
mkEntity Word32
i Word32
gen, Word32 -> IntMap Word32 -> Word32 -> [Word32] -> Entities
Entities Word32
nextGeneration IntMap Word32
gens' Word32
nextIndex [Word32]
free')
{-# INLINE mkEntityWithCounter #-}

entities :: Entities -> [Entity]
entities :: Entities -> [Entity]
entities (Entities Word32
_ IntMap Word32
gens Word32
_ [Word32]
_) = ((Key, Word32) -> Entity) -> [(Key, Word32)] -> [Entity]
forall a b. (a -> b) -> [a] -> [b]
map (Key, Word32) -> Entity
forall {a}. Integral a => (a, Word32) -> Entity
go (IntMap Word32 -> [(Key, Word32)]
forall a. IntMap a -> [(Key, a)]
IntMap.toList IntMap Word32
gens)
  where
    go :: (a, Word32) -> Entity
go (a
i, Word32
gen) = Word32 -> Word32 -> Entity
mkEntity (a -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i) Word32
gen
{-# INLINE entities #-}