module Engine.Stage.Bootstrap.Setup
  ( stackStage
  , bootstrapStage
  ) where

import RIO

import UnliftIO.Resource qualified as Resource

import Engine.Stage.Component qualified as Stage
import Engine.Types (StackStage(..))
import Engine.Types qualified as Engine
import Engine.StageSwitch (trySwitchStage)

stackStage
  :: (a -> StackStage)
  -> Engine.StageSetupRIO a
  -> StackStage
stackStage :: forall a. (a -> StackStage) -> StageSetupRIO a -> StackStage
stackStage a -> StackStage
handoff StageSetupRIO a
action = forall rp p rr st. RenderPass rp => Stage rp p rr st -> StackStage
StackStage forall a b. (a -> b) -> a -> b
$ forall a.
(a -> StackStage)
-> StageSetupRIO a
-> Stage NoRenderPass NoPipelines NoFrameResources NoRunState
bootstrapStage a -> StackStage
handoff StageSetupRIO a
action

bootstrapStage
  :: (a -> StackStage)
  -> Engine.StageSetupRIO a
  -> Engine.Stage Stage.NoRenderPass Stage.NoPipelines Stage.NoFrameResources Stage.NoRunState
bootstrapStage :: forall a.
(a -> StackStage)
-> StageSetupRIO a
-> Stage NoRenderPass NoPipelines NoFrameResources NoRunState
bootstrapStage a -> StackStage
handoff StageSetupRIO a
action = forall (t :: * -> *) rp p st rr.
Foldable t =>
Text
-> Rendering rp p st
-> Resources rp p st rr
-> t (Scene rp p st rr)
-> Stage rp p rr st
Stage.assemble Text
"Bootstrap" forall st. NoRendering st
Stage.noRendering Resources NoRenderPass NoPipelines NoRunState NoFrameResources
resources forall a. Maybe a
Nothing
  where
    resources :: Resources NoRenderPass NoPipelines NoRunState NoFrameResources
resources = forall rp p. NoResources rp p
Stage.noResources
      { $sel:rInitialRS:Resources :: StageRIO (Maybe SwapchainResources) (ReleaseKey, NoRunState)
Stage.rInitialRS =
          forall a.
(a -> StackStage)
-> StageSetupRIO a
-> StageRIO (Maybe SwapchainResources) (ReleaseKey, NoRunState)
transitState a -> StackStage
handoff StageSetupRIO a
action
      }

transitState
  :: (a -> StackStage)
  -> Engine.StageSetupRIO a
  -> Engine.StageSetupRIO (Resource.ReleaseKey, Stage.NoRunState)
transitState :: forall a.
(a -> StackStage)
-> StageSetupRIO a
-> StageRIO (Maybe SwapchainResources) (ReleaseKey, NoRunState)
transitState a -> StackStage
handoff StageSetupRIO a
action = do
  a
res <- StageSetupRIO a
action

  Bool
switched <- forall rs. NextStage -> StageRIO rs Bool
trySwitchStage forall b c a. (b -> c) -> (a -> b) -> a -> c
. StackStage -> NextStage
Engine.Replace forall a b. (a -> b) -> a -> b
$
    a -> StackStage
handoff a
res

  forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless Bool
switched forall a b. (a -> b) -> a -> b
$
    forall (m :: * -> *) env.
(MonadIO m, MonadReader env m, HasLogFunc env, HasCallStack) =>
Utf8Builder -> m ()
logError Utf8Builder
"Bootstrap switch failed"

  ReleaseKey
key <- forall (m :: * -> *). MonadResource m => IO () -> m ReleaseKey
Resource.register forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
  pure (ReleaseKey
key, NoRunState
Stage.NoRunState)