module TieKnot
( tieKnotForAsync, tieKnot
) where
import Prelude ()
import Game.LambdaHack.Core.Prelude
import Control.Concurrent
import Control.Concurrent.Async
import qualified Control.Exception as Ex
import qualified Data.Primitive.PrimArray as PA
import GHC.Compact
import qualified System.Random as R
import Game.LambdaHack.Client
import qualified Game.LambdaHack.Client.UI.Content.Input as IC
import qualified Game.LambdaHack.Client.UI.Content.Screen as SC
import Game.LambdaHack.Client.UI.ContentClientUI
import Game.LambdaHack.Common.Kind
import Game.LambdaHack.Common.Misc
import Game.LambdaHack.Common.Point (speedupHackXSize)
import qualified Game.LambdaHack.Common.Tile as Tile
import qualified Game.LambdaHack.Content.CaveKind as CK
import qualified Game.LambdaHack.Content.ItemKind as IK
import qualified Game.LambdaHack.Content.ModeKind as MK
import qualified Game.LambdaHack.Content.PlaceKind as PK
import qualified Game.LambdaHack.Content.RuleKind as RK
import qualified Game.LambdaHack.Content.TileKind as TK
import Game.LambdaHack.Server
import qualified Client.UI.Content.Input as Content.Input
import qualified Client.UI.Content.Screen as Content.Screen
import qualified Content.CaveKind
import qualified Content.ItemKind
import qualified Content.ModeKind
import qualified Content.PlaceKind
import qualified Content.RuleKind
import qualified Content.TileKind
import Implementation.MonadServerImplementation (executorSer)
tieKnotForAsync :: ServerOptions -> IO ()
tieKnotForAsync options@ServerOptions{ sallClear
, sboostRandomItem
, sdungeonRng } = do
speedupHackXSizeThawed <- PA.unsafeThawPrimArray speedupHackXSize
PA.writePrimArray speedupHackXSizeThawed 0 $
RK.rXmax Content.RuleKind.standardRules
void $ PA.unsafeFreezePrimArray speedupHackXSizeThawed
initialGen <- maybe R.getStdGen return sdungeonRng
let soptionsNxt = options {sdungeonRng = Just initialGen}
boostedItems = IK.boostItemKindList initialGen Content.ItemKind.items
coitem = IK.makeData $
if sboostRandomItem
then boostedItems ++ Content.ItemKind.otherItemContent
else Content.ItemKind.content
coItemSpeedup = speedupItem coitem
cotile = TK.makeData coitem Content.TileKind.content
coTileSpeedup = Tile.speedupTile sallClear cotile
coplace = PK.makeData cotile Content.PlaceKind.content
cocave = CK.makeData coitem coplace cotile Content.CaveKind.content
copsRaw = COps
{ cocave
, coitem
, comode = MK.makeData cocave coitem Content.ModeKind.content
, coplace
, corule = RK.makeData Content.RuleKind.standardRules
, cotile
, coItemSpeedup
, coTileSpeedup
}
benchmark = sbenchmark $ sclientOptions soptionsNxt
#ifdef USE_JSFILE
let cops = copsRaw
#else
cops <- getCompact <$> compact copsRaw
#endif
sUIOptions <- mkUIOptions cops benchmark
let !ccui = CCUI
{ coinput = IC.makeData sUIOptions Content.Input.standardKeysAndMouse
, coscreen = SC.makeData Content.Screen.standardLayoutAndFeatures
}
executorSer cops ccui soptionsNxt sUIOptions
tieKnot :: ServerOptions -> IO ()
tieKnot serverOptions = do
#ifdef USE_JSFILE
let serverOptionsJS = serverOptions {sdumpInitRngs = True}
a <- async $ tieKnotForAsync serverOptionsJS
wait a
#else
let fillWorkaround =
void $ tryPutMVar workaroundOnMainThreadMVar $ return ()
a <- async $ tieKnotForAsync serverOptions
`Ex.finally` fillWorkaround
link a
workaround <- takeMVar workaroundOnMainThreadMVar
workaround
wait a
#endif