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