module Stage.Loader.Scene
  ( Process
  , spawn
  ) where

import RIO

import Data.Type.Equality (type (~))
import UnliftIO.Resource (MonadResource)

import Engine.Camera qualified as Camera
import Engine.Worker qualified as Worker
import Render.DescSets.Set0 (Scene(..), emptyScene)

type Process = Worker.Merge Scene

spawn
  :: ( MonadResource m
     , MonadUnliftIO m
     , Worker.HasOutput projection
     , Worker.GetOutput projection ~ Camera.Projection 'Camera.Orthographic
     )
  => projection
  -> m Process
spawn :: forall (m :: * -> *) projection.
(MonadResource m, MonadUnliftIO m, HasOutput projection,
 GetOutput projection ~ Projection 'Orthographic) =>
projection -> m Process
spawn = (GetOutput projection -> Scene) -> projection -> m Process
forall (m :: * -> *) i o.
(MonadUnliftIO m, MonadResource m, HasOutput i) =>
(GetOutput i -> o) -> i -> m (Merge o)
Worker.spawnMerge1 GetOutput projection -> Scene
Projection 'Orthographic -> Scene
mkScene

mkScene :: Camera.Projection 'Camera.Orthographic -> Scene
mkScene :: Projection 'Orthographic -> Scene
mkScene Camera.Projection{Transform
projectionTransform :: Transform
projectionInverse :: Transform
$sel:projectionInverse:Projection :: forall (pk :: ProjectionKind). Projection pk -> Transform
$sel:projectionTransform:Projection :: forall (pk :: ProjectionKind). Projection pk -> Transform
..} =
  Scene
emptyScene
    { $sel:sceneProjection:Scene :: Transform
sceneProjection    = Transform
projectionTransform
    , $sel:sceneInvProjection:Scene :: Transform
sceneInvProjection = Transform
projectionInverse
    }