1module Time where 2 3import Control.Monad.State.Strict 4 5import Types 6import Status 7import View 8 9next :: Step -> M NextStep 10next = nextStep . Just 11 12nextStep :: Maybe Step -> M NextStep 13nextStep cont = showMessages cont nextStep' 14 15nextStep' :: Maybe Step -> M NextStep 16nextStep' a = do 17 showHint 18 showStats 19 view <- lift . mkView =<< get 20 return $ NextStep view a 21 22prompt :: String -> Step -> M NextStep 23prompt p a = do 24 showHint 25 showStats 26 immediateMessage p 27 nextStep' (Just a) 28 29-- Fork off a long duration job as a separate thread. 30-- 31-- The background job is the first parameter; second is the main 32-- thread. The difference between the two is that when the job 33-- finishes, the program doesn't quit. 34-- 35-- The job always runs before the main thread. 36fork :: M NextStep -> M NextStep -> M NextStep 37fork job rest = do 38 jn <- job 39 rn <- rest 40 runthread jn rn 41 where 42 runthread (NextStep _ (Just contjob)) (NextStep v (Just contr)) = 43 return $ NextStep v $ Just $ \i -> do 44 jn <- contjob i 45 rn <- contr i 46 runthread jn rn 47 runthread (NextStep _ Nothing) (NextStep v (Just contr)) = 48 return $ NextStep v (Just contr) 49 runthread _ (NextStep v Nothing) = 50 return $ NextStep v Nothing 51 52-- If called in the main thread, program exits. 53endThread :: M NextStep 54endThread = nextStep Nothing 55 56-- Starts a thread that waits the specified number of ticks, 57-- and then runs the action. 58delayAction :: Int -> M NextStep -> M () -> M NextStep 59delayAction n cont a = fork (delayAction' n a) cont 60 61delayAction' :: Int -> M () -> M NextStep 62delayAction' 0 a = a >> endThread 63delayAction' n a = next $ \_ -> delayAction' (pred n) a 64